Skip to content

MCP Widget Usage Guide

ZHAO Xudong edited this page Jan 2, 2026 · 1 revision

MCP Widget Usage Guide

English | 中文

English

Overview

The MCP (Model Context Protocol) widget is a built-in Electerm widget that exposes Electerm's APIs via the Model Context Protocol. This allows AI assistants and external tools to interact with Electerm programmatically, enabling automation of terminal operations, bookmark management, and other features.

Features

  • HTTP Server: Runs a local HTTP server (default: http://127.0.0.1:30837/mcp)
  • Server-Sent Events (SSE): Uses SSE for real-time communication
  • Session Management: Supports multiple concurrent sessions with unique session IDs
  • CORS Support: Allows cross-origin requests for web-based integrations
  • IPC Communication: Uses Electron's IPC to communicate with the main Electerm application
  • Configurable APIs: Enable/disable different API groups based on needs

Configuration

The MCP widget can be configured with the following options:

  • Host: IP address to bind the server to (default: 127.0.0.1)
  • Port: Port number to listen on (default: 30837)
  • Enable Bookmarks: Enable bookmark management APIs (default: true)
  • Enable Bookmark Groups: Enable bookmark group APIs (default: true)
  • Enable Quick Commands: Enable quick command APIs (default: true)
  • Enable History: Enable history APIs (default: true)
  • Enable Transfer: Enable file transfer APIs (default: false)
  • Enable Settings: Enable settings APIs (default: false)

Architecture

The MCP widget consists of several key components:

  1. Express Server: Handles HTTP requests and CORS
  2. MCP Server: Implements the Model Context Protocol
  3. Streamable HTTP Transport: Manages SSE communication
  4. IPC Bridge: Communicates with Electerm's renderer process
  5. Tool Registry: Registers available tools based on configuration

How to Use

  1. Start the Widget:

    • Open Electerm
    • Go to Widgets panel
    • Select "MCP Server" widget
    • Configure options as needed
    • Click "Run"
  2. Connect to the Server:

    • The server will be available at http://127.0.0.1:30837/mcp (or configured host/port)
    • Use HTTP POST requests with JSON-RPC 2.0 protocol
    • Include mcp-session-id header for session management
    • Responses are sent via Server-Sent Events (SSE)
  3. Initialize Session:

    POST /mcp
    Content-Type: application/json
    Accept: application/json, text/event-stream
    
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {},
        "clientInfo": {
          "name": "your-client",
          "version": "1.0.0"
        }
      }
    }

    Response (SSE):

    event: message
    data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"electerm-mcp-server","version":"1.0.0"},"capabilities":{}}}
    

Available Tools

Terminal Management (Always Enabled)

  • list_tabs: List all open terminal tabs

    {
      "name": "list_tabs",
      "description": "List all open terminal tabs",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • get_active_tab: Get the currently active tab

    {
      "name": "get_active_tab",
      "description": "Get the currently active tab",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • switch_tab: Switch to a specific tab

    {
      "name": "switch_tab",
      "description": "Switch to a specific tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to switch to"}
        },
        "required": ["tabId"]
      }
    }
  • close_tab: Close a specific tab

    {
      "name": "close_tab",
      "description": "Close a specific tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to close"}
        },
        "required": ["tabId"]
      }
    }
  • reload_tab: Reload/reconnect a tab

    {
      "name": "reload_tab",
      "description": "Reload/reconnect a tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to reload (default: active tab)"}
        }
      }
    }
  • duplicate_tab: Duplicate a tab

    {
      "name": "duplicate_tab",
      "description": "Duplicate a tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to duplicate"}
        },
        "required": ["tabId"]
      }
    }
  • open_local_terminal: Open a new local terminal tab

    {
      "name": "open_local_terminal",
      "description": "Open a new local terminal tab",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • send_terminal_command: Send a command to the active terminal

    {
      "name": "send_terminal_command",
      "description": "Send a command to the active terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "command": {"type": "string", "description": "Command to send"},
          "tabId": {"type": "string", "description": "Optional: specific tab ID"},
          "inputOnly": {"type": "boolean", "description": "Input only mode (no enter key)"}
        },
        "required": ["command"]
      }
    }
  • get_terminal_selection: Get current text selection in terminal

    {
      "name": "get_terminal_selection",
      "description": "Get the current text selection in terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Optional: specific tab ID"}
        }
      }
    }
  • get_terminal_output: Get recent terminal output

    {
      "name": "get_terminal_output",
      "description": "Get recent terminal output/buffer content",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Optional: specific tab ID"},
          "lines": {"type": "number", "description": "Number of lines to return (default: 50)"}
        }
      }
    }

Bookmark Management (if enabled)

  • list_bookmarks: List all bookmarks

    {
      "name": "list_bookmarks",
      "description": "List all SSH/terminal bookmarks",
      "inputSchema": {
        "type": "object",
        "properties": {
          "groupId": {"type": "string", "description": "Optional: Filter by bookmark group ID"}
        }
      }
    }
  • get_bookmark: Get a specific bookmark

    {
      "name": "get_bookmark",
      "description": "Get a specific bookmark by ID",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID"}
        },
        "required": ["id"]
      }
    }
  • add_bookmark: Add a new bookmark

    {
      "name": "add_bookmark",
      "description": "Add a new SSH/terminal bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "Bookmark title"},
          "host": {"type": "string", "description": "SSH host address"},
          "port": {"type": "number", "description": "SSH port (default 22)"},
          "username": {"type": "string", "description": "SSH username"},
          "password": {"type": "string", "description": "SSH password (optional)"},
          "type": {"type": "string", "enum": ["ssh", "local", "serial", "telnet"], "description": "Connection type"}
        },
        "required": ["title"]
      }
    }
  • edit_bookmark: Edit an existing bookmark

    {
      "name": "edit_bookmark",
      "description": "Edit an existing bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to edit"},
          "updates": {"type": "object", "description": "Fields to update"}
        },
        "required": ["id", "updates"]
      }
    }
  • delete_bookmark: Delete a bookmark

    {
      "name": "delete_bookmark",
      "description": "Delete a bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to delete"}
        },
        "required": ["id"]
      }
    }
  • open_bookmark: Open a bookmark in a new tab

    {
      "name": "open_bookmark",
      "description": "Open a bookmark in a new tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to open"}
        },
        "required": ["id"]
      }
    }

Bookmark Groups (if enabled)

  • list_bookmark_groups: List bookmark groups

    {
      "name": "list_bookmark_groups",
      "description": "List all bookmark groups/folders",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • add_bookmark_group: Add a bookmark group

    {
      "name": "add_bookmark_group",
      "description": "Add a new bookmark group",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "Group title"},
          "parentId": {"type": "string", "description": "Optional parent group ID"}
        },
        "required": ["title"]
      }
    }

Quick Commands (if enabled)

  • list_quick_commands: List quick commands

    {
      "name": "list_quick_commands",
      "description": "List all quick commands",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • add_quick_command: Add a quick command

    {
      "name": "add_quick_command",
      "description": "Add a new quick command",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {"type": "string", "description": "Quick command name"},
          "command": {"type": "string", "description": "Command to execute"},
          "inputOnly": {"type": "boolean", "description": "Input only mode (no enter)"},
          "labels": {"type": "array", "items": {"type": "string"}, "description": "Tags/labels for the command"}
        },
        "required": ["name", "command"]
      }
    }
  • run_quick_command: Run a quick command

    {
      "name": "run_quick_command",
      "description": "Run a quick command in the active terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Quick command ID to run"}
        },
        "required": ["id"]
      }
    }
  • delete_quick_command: Delete a quick command

    {
      "name": "delete_quick_command",
      "description": "Delete a quick command",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Quick command ID to delete"}
        },
        "required": ["id"]
      }
    }

History (if enabled)

  • list_history: List connection history

    {
      "name": "list_history",
      "description": "List connection history",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {"type": "number", "description": "Max number of entries (default 50)"}
        }
      }
    }
  • clear_history: Clear connection history

    {
      "name": "clear_history",
      "description": "Clear connection history",
      "inputSchema": {"type": "object", "properties": {}}
    }

File Transfer (if enabled)

  • list_transfers: List active transfers

    {
      "name": "list_transfers",
      "description": "List active file transfers",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_transfer_history: List transfer history

    {
      "name": "list_transfer_history",
      "description": "List file transfer history",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {"type": "number", "description": "Max number of entries"}
        }
      }
    }

Settings (if enabled)

  • get_settings: Get application settings

    {
      "name": "get_settings",
      "description": "Get current application settings",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_terminal_themes: List terminal themes

    {
      "name": "list_terminal_themes",
      "description": "List available terminal themes",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_ui_themes: List UI themes

    {
      "name": "list_ui_themes",
      "description": "List available UI themes",
      "inputSchema": {"type": "object", "properties": {}}
    }

Complete Example

Here's a complete example showing how to initialize a session and perform operations:

const axios = require('axios');

async function example() {
  const serverUrl = 'http://127.0.0.1:30837/mcp';

  try {
    // 1. Initialize session
    const initResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 1,
      method: 'initialize',
      params: {
        protocolVersion: '2024-11-05',
        capabilities: {},
        clientInfo: { name: 'example-client', version: '1.0.0' }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream'
      }
    });

    const sessionId = initResponse.headers['mcp-session-id'];
    console.log('Session ID:', sessionId);

    // 2. List available tools
    const toolsResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 2,
      method: 'tools/list',
      params: {}
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // Parse SSE response
    const toolsData = JSON.parse(toolsResponse.data.split('\n')
      .find(line => line.startsWith('data: '))
      .substring(6));

    console.log('Available tools:', toolsData.result.tools.map(t => t.name));

    // 3. Open a local terminal
    const terminalResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 3,
      method: 'tools/call',
      params: {
        name: 'open_local_terminal',
        arguments: {}
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // 4. Send a command
    const commandResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 4,
      method: 'tools/call',
      params: {
        name: 'send_terminal_command',
        arguments: { command: 'echo "Hello from MCP!"' }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // 5. Get terminal output
    const outputResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 5,
      method: 'tools/call',
      params: {
        name: 'get_terminal_output',
        arguments: { lines: 10 }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

example();

Error Handling

The MCP server provides detailed error responses:

{
  "jsonrpc": "2.0",
  "id": 123,
  "error": {
    "code": -32603,
    "message": "Internal server error",
    "data": "Additional error details"
  }
}

Common error codes:

  • -32603: Internal server error (e.g., no active window)
  • -32602: Invalid params
  • -32601: Method not found

CORS Configuration

The server is configured with permissive CORS headers:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
  • Access-Control-Allow-Headers: Content-Type, mcp-session-id

Security Notes

  • The server runs locally by default
  • CORS is enabled for cross-origin access
  • No authentication is implemented - use at your own risk
  • Consider firewall rules if exposing to network
  • Session IDs are generated server-side for each new session
  • Requests timeout after 30 seconds by default

Testing

The widget includes comprehensive tests that verify:

  • Server accessibility and CORS configuration
  • MCP protocol initialization
  • Tool listing and calling
  • Session management
  • Error handling in various scenarios

Run tests with: npm run test2 (includes MCP widget tests)

Chinese

概述

MCP (Model Context Protocol) 组件是 Electerm 的内置组件,通过模型上下文协议暴露 Electerm 的 API。这允许 AI 助手和外部工具以编程方式与 Electerm 交互,实现终端操作、书签管理等功能的自动化。

功能特性

  • HTTP 服务器:运行本地 HTTP 服务器(默认:http://127.0.0.1:30837/mcp
  • 服务器发送事件 (SSE):使用 SSE 进行实时通信
  • 会话管理:支持多个并发会话,具有唯一的会话 ID
  • CORS 支持:允许跨域请求,支持网页集成
  • IPC 通信:使用 Electron 的 IPC 与主 Electerm 应用程序通信
  • 可配置 API:根据需要启用/禁用不同的 API 组

配置选项

MCP 组件可以配置以下选项:

  • 主机:服务器绑定 IP 地址(默认:127.0.0.1
  • 端口:监听端口号(默认:30837
  • 启用书签:启用书签管理 API(默认:true
  • 启用书签组:启用书签组 API(默认:true
  • 启用快捷命令:启用快捷命令 API(默认:true
  • 启用历史记录:启用历史记录 API(默认:true
  • 启用传输:启用文件传输 API(默认:false
  • 启用设置:启用设置 API(默认:false

架构

MCP 组件由几个关键组件组成:

  1. Express 服务器:处理 HTTP 请求和 CORS
  2. MCP 服务器:实现模型上下文协议
  3. 可流式 HTTP 传输:管理 SSE 通信
  4. IPC 桥接:与 Electerm 的渲染进程通信
  5. 工具注册表:根据配置注册可用工具

使用方法

  1. 启动组件

    • 打开 Electerm
    • 进入组件面板
    • 选择 "MCP Server" 组件
    • 根据需要配置选项
    • 点击 "运行"
  2. 连接服务器

    • 服务器将在 http://127.0.0.1:30837/mcp 可用(或配置的主机/端口)
    • 使用 HTTP POST 请求,JSON-RPC 2.0 协议
    • 包含 mcp-session-id 头部进行会话管理
    • 响应通过服务器发送事件 (SSE) 发送
  3. 初始化会话

    POST /mcp
    Content-Type: application/json
    Accept: application/json, text/event-stream
    
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {},
        "clientInfo": {
          "name": "your-client",
          "version": "1.0.0"
        }
      }
    }

    响应 (SSE)

    event: message
    data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"electerm-mcp-server","version":"1.0.0"},"capabilities":{}}}
    

可用工具

终端管理(始终启用)

  • list_tabs:列出所有打开的终端标签页

    {
      "name": "list_tabs",
      "description": "List all open terminal tabs",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • get_active_tab:获取当前活动标签页

    {
      "name": "get_active_tab",
      "description": "Get the currently active tab",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • switch_tab:切换到指定标签页

    {
      "name": "switch_tab",
      "description": "Switch to a specific tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to switch to"}
        },
        "required": ["tabId"]
      }
    }
  • close_tab:关闭指定标签页

    {
      "name": "close_tab",
      "description": "Close a specific tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to close"}
        },
        "required": ["tabId"]
      }
    }
  • reload_tab:重新加载/重连标签页

    {
      "name": "reload_tab",
      "description": "Reload/reconnect a tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to reload (default: active tab)"}
        }
      }
    }
  • duplicate_tab:复制标签页

    {
      "name": "duplicate_tab",
      "description": "Duplicate a tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Tab ID to duplicate"}
        },
        "required": ["tabId"]
      }
    }
  • open_local_terminal:打开新的本地终端标签页

    {
      "name": "open_local_terminal",
      "description": "Open a new local terminal tab",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • send_terminal_command:向活动终端发送命令

    {
      "name": "send_terminal_command",
      "description": "Send a command to the active terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "command": {"type": "string", "description": "Command to send"},
          "tabId": {"type": "string", "description": "Optional: specific tab ID"},
          "inputOnly": {"type": "boolean", "description": "Input only mode (no enter key)"}
        },
        "required": ["command"]
      }
    }
  • get_terminal_selection:获取终端中的当前文本选择

    {
      "name": "get_terminal_selection",
      "description": "Get the current text selection in terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Optional: specific tab ID"}
        }
      }
    }
  • get_terminal_output:获取最近的终端输出

    {
      "name": "get_terminal_output",
      "description": "Get recent terminal output/buffer content",
      "inputSchema": {
        "type": "object",
        "properties": {
          "tabId": {"type": "string", "description": "Optional: specific tab ID"},
          "lines": {"type": "number", "description": "Number of lines to return (default: 50)"}
        }
      }
    }

书签管理(如果启用)

  • list_bookmarks:列出所有书签

    {
      "name": "list_bookmarks",
      "description": "List all SSH/terminal bookmarks",
      "inputSchema": {
        "type": "object",
        "properties": {
          "groupId": {"type": "string", "description": "Optional: Filter by bookmark group ID"}
        }
      }
    }
  • get_bookmark:获取指定书签

    {
      "name": "get_bookmark",
      "description": "Get a specific bookmark by ID",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID"}
        },
        "required": ["id"]
      }
    }
  • add_bookmark:添加新书签

    {
      "name": "add_bookmark",
      "description": "Add a new SSH/terminal bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "Bookmark title"},
          "host": {"type": "string", "description": "SSH host address"},
          "port": {"type": "number", "description": "SSH port (default 22)"},
          "username": {"type": "string", "description": "SSH username"},
          "password": {"type": "string", "description": "SSH password (optional)"},
          "type": {"type": "string", "enum": ["ssh", "local", "serial", "telnet"], "description": "Connection type"}
        },
        "required": ["title"]
      }
    }
  • edit_bookmark:编辑现有书签

    {
      "name": "edit_bookmark",
      "description": "Edit an existing bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to edit"},
          "updates": {"type": "object", "description": "Fields to update"}
        },
        "required": ["id", "updates"]
      }
    }
  • delete_bookmark:删除书签

    {
      "name": "delete_bookmark",
      "description": "Delete a bookmark",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to delete"}
        },
        "required": ["id"]
      }
    }
  • open_bookmark:在新标签页中打开书签

    {
      "name": "open_bookmark",
      "description": "Open a bookmark in a new tab",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Bookmark ID to open"}
        },
        "required": ["id"]
      }
    }

书签组(如果启用)

  • list_bookmark_groups:列出书签组

    {
      "name": "list_bookmark_groups",
      "description": "List all bookmark groups/folders",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • add_bookmark_group:添加书签组

    {
      "name": "add_bookmark_group",
      "description": "Add a new bookmark group",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "Group title"},
          "parentId": {"type": "string", "description": "Optional parent group ID"}
        },
        "required": ["title"]
      }
    }

快捷命令(如果启用)

  • list_quick_commands:列出快捷命令

    {
      "name": "list_quick_commands",
      "description": "List all quick commands",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • add_quick_command:添加快捷命令

    {
      "name": "add_quick_command",
      "description": "Add a new quick command",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {"type": "string", "description": "Quick command name"},
          "command": {"type": "string", "description": "Command to execute"},
          "inputOnly": {"type": "boolean", "description": "Input only mode (no enter)"},
          "labels": {"type": "array", "items": {"type": "string"}, "description": "Tags/labels for the command"}
        },
        "required": ["name", "command"]
      }
    }
  • run_quick_command:运行快捷命令

    {
      "name": "run_quick_command",
      "description": "Run a quick command in the active terminal",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Quick command ID to run"}
        },
        "required": ["id"]
      }
    }
  • delete_quick_command:删除快捷命令

    {
      "name": "delete_quick_command",
      "description": "Delete a quick command",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "description": "Quick command ID to delete"}
        },
        "required": ["id"]
      }
    }

历史记录(如果启用)

  • list_history:列出连接历史记录

    {
      "name": "list_history",
      "description": "List connection history",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {"type": "number", "description": "Max number of entries (default 50)"}
        }
      }
    }
  • clear_history:清除连接历史记录

    {
      "name": "clear_history",
      "description": "Clear connection history",
      "inputSchema": {"type": "object", "properties": {}}
    }

文件传输(如果启用)

  • list_transfers:列出活动传输

    {
      "name": "list_transfers",
      "description": "List active file transfers",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_transfer_history:列出传输历史记录

    {
      "name": "list_transfer_history",
      "description": "List file transfer history",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {"type": "number", "description": "Max number of entries"}
        }
      }
    }

设置(如果启用)

  • get_settings:获取应用程序设置

    {
      "name": "get_settings",
      "description": "Get current application settings",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_terminal_themes:列出终端主题

    {
      "name": "list_terminal_themes",
      "description": "List available terminal themes",
      "inputSchema": {"type": "object", "properties": {}}
    }
  • list_ui_themes:列出 UI 主题

    {
      "name": "list_ui_themes",
      "description": "List available UI themes",
      "inputSchema": {"type": "object", "properties": {}}
    }

完整示例

以下是一个完整的示例,展示如何初始化会话并执行操作:

const axios = require('axios');

async function example() {
  const serverUrl = 'http://127.0.0.1:30837/mcp';

  try {
    // 1. 初始化会话
    const initResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 1,
      method: 'initialize',
      params: {
        protocolVersion: '2024-11-05',
        capabilities: {},
        clientInfo: { name: 'example-client', version: '1.0.0' }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream'
      }
    });

    const sessionId = initResponse.headers['mcp-session-id'];
    console.log('Session ID:', sessionId);

    // 2. 列出可用工具
    const toolsResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 2,
      method: 'tools/list',
      params: {}
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // 解析 SSE 响应
    const toolsData = JSON.parse(toolsResponse.data.split('\n')
      .find(line => line.startsWith('data: '))
      .substring(6));

    console.log('Available tools:', toolsData.result.tools.map(t => t.name));

    // 3. 打开本地终端
    const terminalResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 3,
      method: 'tools/call',
      params: {
        name: 'open_local_terminal',
        arguments: {}
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // 4. 发送命令
    const commandResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 4,
      method: 'tools/call',
      params: {
        name: 'send_terminal_command',
        arguments: { command: 'echo "Hello from MCP!"' }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

    // 5. 获取终端输出
    const outputResponse = await axios.post(serverUrl, {
      jsonrpc: '2.0',
      id: 5,
      method: 'tools/call',
      params: {
        name: 'get_terminal_output',
        arguments: { lines: 10 }
      }
    }, {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/event-stream',
        'mcp-session-id': sessionId
      }
    });

  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

example();

错误处理

MCP 服务器提供详细的错误响应:

{
  "jsonrpc": "2.0",
  "id": 123,
  "error": {
    "code": -32603,
    "message": "Internal server error",
    "data": "Additional error details"
  }
}

常见错误代码:

  • -32603:内部服务器错误(例如,没有活动窗口)
  • -32602:无效参数
  • -32601:方法未找到

CORS 配置

服务器配置了宽松的 CORS 头部:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
  • Access-Control-Allow-Headers: Content-Type, mcp-session-id

安全注意事项

  • 服务器默认在本地运行
  • 已启用 CORS 以允许跨域访问
  • 未实现身份验证 - 使用时请自行承担风险
  • 如果暴露到网络,请考虑防火墙规则
  • 会话 ID 由服务器端为每个新会话生成
  • 请求默认在 30 秒后超时

测试

该组件包含全面的测试,用于验证:

  • 服务器可访问性和 CORS 配置
  • MCP 协议初始化
  • 工具列出和调用
  • 会话管理
  • 各种场景下的错误处理

运行测试:npm run test2(包括 MCP 组件测试)

Clone this wiki locally