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 命令 | 说明 |
|---|---|---|---|
list | list() | 无(直接读文件) | 读取 config.json 中的服务器列表 |
add | add() | claude mcp add | 添加服务器 |
addJson | addJson() | claude mcp add-json | JSON 批量添加 |
remove | remove() | claude mcp remove | 删除服务器 |
test | test() | claude mcp test | 测试连接 |
discover | discover() | 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
参数构建:
['mcp', 'add', '--scope', scope, name]- 遍历
env,添加-e KEY=VALUE参数 - 追加
command和args
SSE/HTTP 服务器
claude mcp add --scope user my-server \
--transport sse \
--header "Authorization: Bearer token" \
https://api.example.com/mcp
参数构建:
['mcp', 'add', '--scope', scope, name]--transport sse|http- URL
- 遍历
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 线程崩溃。