@wonderwhy-er/desktop-commander
Version:
MCP server for terminal operations and file editing
79 lines (78 loc) • 3.36 kB
JavaScript
import { terminalManager } from '../terminal-manager.js';
import { commandManager } from '../command-manager.js';
import { ExecuteCommandArgsSchema, ReadOutputArgsSchema, ForceTerminateArgsSchema } from './schemas.js';
import { capture } from "../utils.js";
export async function executeCommand(args) {
const parsed = ExecuteCommandArgsSchema.safeParse(args);
if (!parsed.success) {
capture('server_execute_command_failed');
throw new Error(`Invalid arguments for execute_command: ${parsed.error}`);
}
try {
// Extract all commands for analytics while ensuring execution continues even if parsing fails
const commands = commandManager.extractCommands(parsed.data.command);
capture('server_execute_command', {
command: commandManager.getBaseCommand(parsed.data.command), // Keep original for backward compatibility
commands: commands // Add the array of all identified commands
});
}
catch (error) {
// If anything goes wrong with command extraction, just continue with execution
capture('server_execute_command', {
command: commandManager.getBaseCommand(parsed.data.command)
});
// Log the error but continue execution
console.error('Error during command extraction:', error);
}
if (!commandManager.validateCommand(parsed.data.command)) {
throw new Error(`Command not allowed: ${parsed.data.command}`);
}
const result = await terminalManager.executeCommand(parsed.data.command, parsed.data.timeout_ms);
return {
content: [{
type: "text",
text: `Command started with PID ${result.pid}\nInitial output:\n${result.output}${result.isBlocked ? '\nCommand is still running. Use read_output to get more output.' : ''}`
}],
};
}
export async function readOutput(args) {
const parsed = ReadOutputArgsSchema.safeParse(args);
if (!parsed.success) {
throw new Error(`Invalid arguments for read_output: ${parsed.error}`);
}
const output = terminalManager.getNewOutput(parsed.data.pid);
return {
content: [{
type: "text",
text: output === null
? `No session found for PID ${parsed.data.pid}`
: output || 'No new output available'
}],
};
}
export async function forceTerminate(args) {
const parsed = ForceTerminateArgsSchema.safeParse(args);
if (!parsed.success) {
throw new Error(`Invalid arguments for force_terminate: ${parsed.error}`);
}
const success = terminalManager.forceTerminate(parsed.data.pid);
return {
content: [{
type: "text",
text: success
? `Successfully initiated termination of session ${parsed.data.pid}`
: `No active session found for PID ${parsed.data.pid}`
}],
};
}
export async function listSessions() {
const sessions = terminalManager.listActiveSessions();
return {
content: [{
type: "text",
text: sessions.length === 0
? 'No active sessions'
: sessions.map(s => `PID: ${s.pid}, Blocked: ${s.isBlocked}, Runtime: ${Math.round(s.runtime / 1000)}s`).join('\n')
}],
};
}