跳到主要内容

Worker 线程

mcp.worker.ts 是一个独立的 Worker 线程,提供通过 claude CLI 管理 MCP 服务器的桥接层。它作为 McpService(SDK 直连方式)的补充,支持读取 Claude 配置文件中的 MCP 服务器记录以及通过 CLI 进行增删测试操作。

文件路径packages/desktop/app/main/workers/mcp.worker.ts

架构图

graph LR
subgraph Main["主进程"]
Router["McpRouter / 调用方"]
end

subgraph Worker["Worker 线程"]
Port["MessagePort"]
McpWorkerClass["McpWorker"]
end

subgraph External["外部"]
ClaudeCLI["claude CLI"]
ConfigFile["~/.claude/config.json"]
end

Router -->|postMessage| Port
Port -->|message event| McpWorkerClass
McpWorkerClass -->|spawn| ClaudeCLI
McpWorkerClass -->|readFile| ConfigFile
McpWorkerClass -->|postMessage| Port
Port -->|result/error| Router

通信协议

请求格式

type WorkerAction =
| { id: number; action: 'list' }
| { id: number; action: 'add'; payload: McpServerInput }
| { id: number; action: 'addJson'; payload: McpServerJsonInput }
| { id: number; action: 'remove'; payload: McpServerRemoveInput }
| { id: number; action: 'test'; payload: McpServerRemoveInput }
| { id: number; action: 'discover'; payload: McpServerRemoveInput };

响应格式

type WorkerResponse =
| { id: number; result: unknown }
| { id: number; error: string };

每个请求通过 id 字段进行请求-响应配对。

支持的操作

Action方法CLI 命令说明
listlist()无(直接读文件)读取 config.json 中的服务器列表
addadd()claude mcp add添加服务器
addJsonaddJson()claude mcp add-jsonJSON 批量添加
removeremove()claude mcp remove删除服务器
testtest()claude mcp test测试连接
discoverdiscover()claude mcp inspect发现工具/资源/提示词

list — 配置文件读取

list() 不调用 CLI,而是直接读取 ~/.claude/config.json 文件:

private async readClaudeConfig(): Promise<ClaudeConfig | null> {
const configPath = path.join(os.homedir(), '.claude', 'config.json');
const content = await fsp.readFile(configPath, 'utf8');
return JSON.parse(content);
}

配置文件结构

interface ClaudeConfig {
mcpServers?: Record<string, McpServerConfig & Record<string, unknown>>;
projects?: Record<string, {
mcpServers?: Record<string, McpServerConfig & Record<string, unknown>>;
}>;
}

服务器记录映射

从 config.json 读取的记录需要转换为内部格式:

private toServerRecord(input): McpServerRecord {
// 传输类型推断:transport > type > 默认 'stdio'
const transport = config.transport ?? config.type ?? 'stdio';

return {
id: `${scope}:${projectPath ?? 'global'}:${name}`,
name,
scope,
type: transport,
projectPath,
status: 'configured',
config
};
}

ID 格式{scope}:{projectPath|global}:{name}

作用域

  • user — 全局配置的服务器(mcpServers 顶层)
  • local — 项目级配置的服务器(projects[path].mcpServers

add — 添加服务器

通过 claude mcp add CLI 命令添加服务器:

Stdio 服务器

claude mcp add --scope user my-server \
-e API_KEY=xxx \
npx -y @example/mcp-server

参数构建:

  1. ['mcp', 'add', '--scope', scope, name]
  2. 遍历 env,添加 -e KEY=VALUE 参数
  3. 追加 commandargs

SSE/HTTP 服务器

claude mcp add --scope user my-server \
--transport sse \
--header "Authorization: Bearer token" \
https://api.example.com/mcp

参数构建:

  1. ['mcp', 'add', '--scope', scope, name]
  2. --transport sse|http
  3. URL
  4. 遍历 headers,添加 --header "Key: Value" 参数

discover — 发现能力

使用 claude mcp inspect 命令获取 JSON 格式的能力清单:

claude mcp inspect --scope user my-server --format json

JSON 提取

从 CLI 输出中提取 JSON 对象:

private extractJson(output: string) {
const match = /\{[\s\S]*\}/.exec(output);
if (!match) return null;
return JSON.parse(match[0]);
}

结果规范化

工具/资源/提示词列表统一为 McpToolInfo[] 格式:

private normalizeToolList(value: any): McpToolInfo[] {
// 支持字符串数组和对象数组
// string → { name: string }
// { name, description } → McpToolInfo
}

服务器标识符解析

Worker 中的服务器标识使用 scope:name 格式(与 McpService 的 UUID 格式不同):

private parseServerIdentifier(id?: string, scope?: string) {
const [prefix, ...rest] = id.split(':');
const name = rest.length ? rest.join(':') : prefix;
const normalizedScope = rest.length
? prefix as 'user' | 'local'
: scope ?? 'user';
return { scope: normalizedScope, name };
}

示例

  • user:my-server{ scope: 'user', name: 'my-server' }
  • local:/path/to/project:db-server{ scope: 'local', name: '/path/to/project:db-server' }
  • my-server(无前缀) → { scope: 'user', name: 'my-server' }

CLI 执行

所有 CLI 操作通过 runClaude() 方法执行:

private async runClaude(
args: string[],
options: { cwd?: string } = {}
): Promise<{ success: boolean; stdout: string; stderr: string }>
  • 使用 child_process.spawn 启动 claude 进程
  • 收集 stdout 和 stderr
  • 通过进程退出码判断成功/失败
  • 支持工作目录(cwd)指定,用于 local scope 操作

Worker 与 McpService 的关系

特性McpService(SDK 直连)mcp.worker(CLI 桥接)
连接方式直接使用 MCP SDK通过 claude CLI
进程模型主进程内独立 Worker 线程
配置来源Electron Store (mcp-config)~/.claude/config.json
工具调用支持不支持
用途运行时连接和工具调用配置管理和 CLI 兼容
实时性实时连接按需操作

注意:当前版本中,McpService(SDK 直连)是主要的运行时实现。Worker 作为补充,提供与 Claude CLI 的配置互操作能力。两者管理的配置是独立的(分别存储在 Electron Store 和 ~/.claude/config.json)。

错误处理

Worker 线程中的错误通过消息协议传递:

port.on('message', async (message: WorkerAction) => {
try {
// 处理请求...
port.postMessage({ id: message.id, result: ... });
} catch (error) {
port.postMessage({
id: message.id,
error: error instanceof Error ? error.message : String(error)
});
}
});

所有异常都被捕获并转换为错误响应,不会导致 Worker 线程崩溃。

相关文件