Skip to main content
Glama

start_interactive_command

Initiate an interactive command session on Kali Linux MCP Server to handle user inputs like SQL prompts, enabling continued execution without closing the session.

Instructions

(需要交互式比如mysql -u root -p)在Kali Linux环境中启动一个交互式命令,并返回会话ID。交互式命令可以接收用户输入,可以在不close_interactive_command的情况下同时执行execute_command。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYes要在Kali Linux环境中执行的交互式命令。

Implementation Reference

  • The primary handler for the 'start_interactive_command' tool. Validates the command input, handles special cases like msfconsole, creates an InteractiveSession using CommandExecutor, stores it in activeSessions map, and returns session details including initial output and input readiness.
    case "start_interactive_command": { let command = String(request.params.arguments?.command); if (!command) { throw new McpError(ErrorCode.InvalidParams, "命令是必需的"); } // 存储当前命令到全局变量 (global as any).currentInteractiveCommand = command; // 如果是 msfconsole,添加 -q 参数 if (command.trim() === 'msfconsole') { command = 'msfconsole -q'; log.info("检测到 msfconsole,自动添加 -q 参数启动。"); } try { log.info(`准备启动交互式命令: ${command}`); // 显式设置pty选项,特别是对msfconsole这类特殊终端程序 const ptyOptions = { waitForPrompt: true, // 等待提示符后再返回 maxWaitTime: command.includes('msfconsole') ? 3000000 : 30000, // msfconsole等待更长时间(2分钟),其他命令30秒 forcePty: command.includes('msfconsole'), // 为msfconsole强制分配PTY term: "xterm-256color", // 设置终端类型 cols: 100, // 设置列数 rows: 40 // 设置行数 }; // 对于msfconsole特别提示用户可能需要等待较长时间 if (command.includes('msfconsole')) { log.info(`正在启动msfconsole,这可能需要1-2分钟时间,请耐心等待...`); } // 创建交互式会话 const session = await commandExecutor.createInteractiveSession(command, ptyOptions); activeSessions.set(session.sessionId, session); // 显示实时输出信息 log.info(`交互式会话已创建并等待提示符,ID: ${session.sessionId}`); // 添加对msfconsole会话的特别提示 let responseMessage: any = { status: "success", session_id: session.sessionId, initial_output: session.stdout, waiting_for_input: session.isWaitingForInput }; log.info(`输入状态: ${session.isWaitingForInput ? '等待输入' : '不等待输入'}`); return { content: [{ type: "text", text: JSON.stringify(responseMessage) }] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); log.error(`创建交互式会话失败: ${errorMessage}`); throw new McpError( ErrorCode.InternalError, `无法创建交互式会话: ${errorMessage}` ); } }
  • Input schema definition for the 'start_interactive_command' tool, specifying a required 'command' string parameter.
    { name: "start_interactive_command", description: "(需要交互式比如mysql -u root -p)在Kali Linux环境中启动一个交互式命令,并返回会话ID。交互式命令可以接收用户输入,可以在不close_interactive_command的情况下同时执行execute_command。", inputSchema: { type: "object", properties: { command: { type: "string", description: "要在Kali Linux环境中执行的交互式命令。" } }, required: ["command"] }
  • src/index.ts:73-156 (registration)
    Registers the 'start_interactive_command' tool by including its definition in the tools list returned by the ListToolsRequestSchema handler.
    server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "execute_command", description: "(无需交互式比如ping 127.0.0.1)在Kali Linux渗透测试环境中执行命令。支持所有Kali Linux内置的安全测试工具和常规Linux命令。", inputSchema: { type: "object", properties: { command: { type: "string", description: "要在Kali Linux环境中执行的命令。可以是任何安全测试、漏洞扫描、密码破解等渗透测试命令。" } }, required: ["command"] } }, { name: "start_interactive_command", description: "(需要交互式比如mysql -u root -p)在Kali Linux环境中启动一个交互式命令,并返回会话ID。交互式命令可以接收用户输入,可以在不close_interactive_command的情况下同时执行execute_command。", inputSchema: { type: "object", properties: { command: { type: "string", description: "要在Kali Linux环境中执行的交互式命令。" } }, required: ["command"] } }, { name: "send_input_to_command", description: "(自行判断是AI输入还是用户手动输入)向正在运行的交互式命令发送用户输入。", inputSchema: { type: "object", properties: { session_id: { type: "string", description: "交互式会话ID。" }, input: { type: "string", description: "发送给命令的输入文本。" }, end_line: { type: "boolean", description: "是否在输入后添加换行符。默认为true。" } }, required: ["session_id", "input"] } }, { name: "get_command_output", description: "获取交互式命令的最新输出。", inputSchema: { type: "object", properties: { session_id: { type: "string", description: "交互式会话ID。" } }, required: ["session_id"] } }, { name: "close_interactive_command", description: "关闭交互式命令会话。", inputSchema: { type: "object", properties: { session_id: { type: "string", description: "交互式会话ID。" } }, required: ["session_id"] } } ] }; });
  • Core helper function in CommandExecutor class that implements the interactive command startup logic: establishes SSH shell with PTY, configures terminal environment, executes the command, sets up event handlers for real-time output processing and input prompt detection, and supports waiting for readiness.
    async createInteractiveSession( command: string, options: { cwd?: string; env?: Record<string, string>; waitForPrompt?: boolean; // 是否等待提示符后再返回 maxWaitTime?: number; // 最大等待时间(毫秒) forcePty?: boolean; // 是否强制分配PTY term?: string; // 终端类型 cols?: number; // 终端列数 rows?: number; // 终端行数 } = {} ): Promise<InteractiveSession> { if (!this.isConnected || !this.sshClient) { throw new Error('SSH未连接,请先调用connect方法'); } const { cwd = '/', env = {}, waitForPrompt = true, maxWaitTime = 3000000, // 默认最大等待30秒 forcePty = false, // 默认不强制PTY term = 'xterm-256color', // 默认终端类型 cols = 80, // 默认终端列数 rows = 24 // 默认终端行数 } = options; try { log.info(`创建交互式会话: ${command}`); // 创建环境变量设置 let envSettings = Object.entries(env) .map(([key, value]) => `export ${key}="${String(value).replace(/"/g, '\\"')}"`) .join('; '); // 为交互式终端添加必要的环境变量 const defaultEnvSettings = [ `export TERM=${term}`, `export COLUMNS=${cols}`, `export LINES=${rows}`, 'export PS1="\\u@\\h:\\w\\$ "' ].join('; '); envSettings = envSettings ? `${envSettings}; ${defaultEnvSettings}` : defaultEnvSettings; // 特殊命令处理 let processedCommand = command; // 对于msfconsole等命令,添加特殊处理 if (command.includes('msfconsole')) { log.info('检测到msfconsole命令,添加特殊处理'); // 确保使用安静模式启动 if (!processedCommand.includes('-q')) { processedCommand = `${processedCommand} -q`; } log.info(`处理后的msfconsole命令: ${processedCommand}`); } // 最终命令 const finalCommand = `cd "${cwd}" && ${envSettings} && ${processedCommand}`; // 创建会话并配置 const sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`; // 传递PTY相关参数到createSessionObject const session = await this.createSessionObject(sessionId, finalCommand, { forcePty, term, cols, rows }); log.info(`交互式会话创建成功,ID: ${sessionId}`); // 通知实时查看器会话开始 await this.realtimePusher.notifySessionStart(sessionId, command); // 如果需要等待提示符出现 if (waitForPrompt) { return await this.waitForSessionPrompt(session, command, maxWaitTime); } return session; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); log.error(`创建交互式会话失败: ${errorMessage}`); throw error; } }
  • Helper function used by interactive sessions to detect if the command prompt is ready for input, with special handling for msfconsole and various common prompts.
    function isWaitingForInput(output: string): boolean { // 检查是否有全局重载函数,如果有则使用它 if ((global as any).overrideWaitingCheck) { return (global as any).overrideWaitingCheck(output); } // 检查输出是否为会话对象,如果是并且有msfPromptDetected标记,直接返回true if (output && typeof output === 'object' && (output as any).msfPromptDetected) { return true; } if (!output || output.trim() === '') { return false; } // 首先移除所有ANSI转义序列,确保检查的是纯文本内容 const cleanOutput = stripAnsiCodes(output); // 检查常见的命令行提示符 const lines = cleanOutput.split('\n'); // 获取最后20行非空文本,某些程序可能会有很长的输出 const lastLines = lines.filter(line => line.trim().length > 0).slice(-20); const lastLine = lastLines.length > 0 ? lastLines[lastLines.length - 1] : ''; const cleanLine = lastLine.trim(); // 检查命令是否为msfconsole const isMsfconsole = (global as any).currentInteractiveCommand?.includes('msfc') || false; // 在日志中记录最后几行,帮助调试 // log.debug(`检测输入提示符,最后一行: "${cleanLine}"`); // msfconsole特殊处理 if (isMsfconsole) { // 使用静态变量跟踪用户输入状态 if (!(global as any).msfInputState) { (global as any).msfInputState = { hasReturnedTrue: false, // 是否曾经返回过true hasUserInput: false, // 用户是否输入过命令 outputLength: 0 // 输出长度记录 }; } // 检查是否是第一次(从未返回过true) const isFirstTime = !((global as any).msfInputState.hasReturnedTrue); const isMsf6Prompt = isFirstTime ? /^msf6\s>$/.test(cleanLine.trim()) // 第一次:严格匹配"msf6 >" : /^msf6\s.+>$/.test(cleanLine.trim()); // 之后:要求"msf6"和">"之间有其他内容 // 检测用户是否输入了新命令 // 只有当输出长度增加时才认为是新输入 if (cleanOutput.length > (global as any).msfInputState.outputLength) { // 如果输出增加了,说明有新的用户输入 if ((global as any).msfInputState.hasReturnedTrue) { (global as any).msfInputState.hasUserInput = true; } (global as any).msfInputState.outputLength = cleanOutput.length; } if (isMsf6Prompt) { // 第一次检测到提示符 if (!((global as any).msfInputState.hasReturnedTrue)) { (global as any).msfInputState.hasReturnedTrue = true; (global as any).msfInputState.outputLength = cleanOutput.length; return true; } // 已经返回过true,并且用户已经输入过命令 else if ((global as any).msfInputState.hasUserInput) { (global as any).msfInputState.hasUserInput = false; // 重置用户输入状态 (global as any).msfInputState.outputLength = cleanOutput.length; // 更新输出长度 return true; } } return false; } else { // 非msfconsole命令才使用常见的提示符模式 const promptPatterns = [ /[\$#>]\s*$/, // 常见的shell提示符: $, #, > /password[: ]*$/i, // 密码提示 /continue\? \[(y\/n)\]/i, // 继续提示 /\[\?\]\s*$/, // 问号提示 /输入.*[::]/, // 中文输入提示 /please enter.*:/i, // 英文输入提示 /press.*to continue/i, // 按键继续提示 /Enter\s*.*:/i, // Enter提示 /\(.*\)\s*$/, // 括号内选择提示,如 (Y/n) /\s+y\/n\s*$/i, // y/n选择 /mysql>\s*$/, // mysql提示符 /sqlite>\s*$/, // sqlite提示符 /ftp>\s*$/, // ftp提示符 /postgres=#\s*$/, // postgres提示符 /Press RETURN to continue/, // 按回车继续 /waiting for input/i // 通用等待输入文本 ]; // 检查最后一行是否匹配任何提示符模式 for (const pattern of promptPatterns) { if (pattern.test(cleanLine)) { log.debug(`匹配到提示符模式 ${pattern},判定为等待输入`); return true; } } } // 如果都不匹配,则默认不是在等待输入 return false; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sfz009900/kalilinuxmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server