主要变更: - Skill Learning 闭环系统 (9/9 AC) - Opus 4.7 模型层接入 + adaptive thinking - Prompt 工程优化 (64 审计测试) - Agent Teams 简化门控 (默认启用) - Windows Terminal 后端修复 (EncodedCommand/WT_SESSION) - TF-IDF 技能搜索精准化 (字段加权/CJK 优化) - Autonomy 系统 (/autonomy 命令) - ACP 协议完整实现 - mock.module 泄漏修复 (CI 全绿) - 152+ lint/type 修复
11 KiB
/mcp 斜杠命令路由机制
本文档描述用户在 REPL 交互模式下输入 /mcp 时,命令如何被解析、查找、分发,以及如何通过 React 状态机渲染交互式子项界面。
架构概览
用户输入 /mcp [args]
│
▼
┌─────────────────────────────────┐
│ 第一层:斜杠命令解析 │
│ slashCommandParsing.ts │
│ parseSlashCommand() │
│ → commandName + args 拆分 │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ 第二层:命令查找与加载 │
│ commands.ts → findCommand() │
│ commands/mcp/index.ts │
│ → 懒加载 mcp.tsx 模块 │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ 第三层:命令处理器分发 │
│ commands/mcp/mcp.tsx → call() │
│ → 根据 args 决定渲染哪个组件 │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ 第四层:交互式 UI 状态机 │
│ MCPSettings → viewState 切换 │
│ MCPListPanel → 列表导航 │
│ MCPStdioServerMenu / │
│ MCPRemoteServerMenu → 操作菜单 │
└─────────────────────────────────┘
第一层:斜杠命令解析
文件: src/utils/slashCommandParsing.ts
parseSlashCommand() 负责将用户的原始输入拆分为命令名和参数:
parseSlashCommand('/mcp')
// → { commandName: 'mcp', args: '', isMcp: false }
parseSlashCommand('/mcp enable sorftime')
// → { commandName: 'mcp', args: 'enable sorftime', isMcp: false }
parseSlashCommand('/mcp:tool (MCP) arg1')
// → { commandName: 'mcp:tool (MCP)', args: 'arg1', isMcp: true }
解析规则:
- 取
/后的第一个词作为commandName - 剩余部分整体作为
args字符串 - 如果第二个词是
(MCP),则拼入commandName并标记isMcp: true - 解析器不处理子命令层级,子命令路由由各命令处理器自行实现
第二层:命令查找与加载
命令注册
文件: src/commands/mcp/index.ts
const mcp = {
type: 'local-jsx', // 本地 JSX 组件命令,不经过 AI
name: 'mcp',
description: 'Manage MCP servers',
immediate: true, // 直接执行,不需要 AI 处理
argumentHint: '[enable|disable [server-name]]',
load: () => import('./mcp.js'), // 懒加载处理器
} satisfies Command
命令查找
文件: src/commands.ts
findCommand() 在全局 COMMANDS 列表中按 name 或 aliases 精确匹配:
export function findCommand(commandName: string, commands: Command[]): Command | undefined {
return commands.find(
_ => _.name === commandName ||
getCommandName(_) === commandName ||
_.aliases?.includes(commandName),
);
}
全局命令列表由 COMMANDS() 函数(memoized)构建,mcp 是其中之一。
命令执行入口
文件: src/utils/processUserInput/processSlashCommand.tsx
processSlashCommand 调用 findCommand 找到命令后:
- 对
local-jsx类型命令,调用load()懒加载模块 - 调用模块导出的
call(onDone, context, args)函数 - 返回的 React 节点由 Ink 渲染到终端
第三层:命令处理器分发
文件: src/commands/mcp/mcp.tsx
call() 函数根据 args 参数手动路由到不同的子功能:
export async function call(onDone, _context, args?: string): Promise<React.ReactNode> {
if (args) {
const parts = args.trim().split(/\s+/);
// /mcp no-redirect → 绕过 ant 用户重定向,直接显示 MCP 设置
if (parts[0] === 'no-redirect') {
return <MCPSettings onComplete={onDone} />;
}
// /mcp reconnect <server-name> → 重连指定服务器
if (parts[0] === 'reconnect' && parts[1]) {
return <MCPReconnect serverName={parts.slice(1).join(' ')} onComplete={onDone} />;
}
// /mcp enable [server-name|all] → 启用服务器
// /mcp disable [server-name|all] → 禁用服务器
if (parts[0] === 'enable' || parts[0] === 'disable') {
return <MCPToggle
action={parts[0]}
target={parts.length > 1 ? parts.slice(1).join(' ') : 'all'}
onComplete={onDone}
/>;
}
}
// /mcp (无参数) → ant 用户重定向到 /plugins,其他用户显示 MCPSettings
if (process.env.USER_TYPE === 'ant') {
return <PluginSettings onComplete={onDone} args="manage" showMcpRedirectMessage />;
}
return <MCPSettings onComplete={onDone} />;
}
子命令映射表
| 输入 | 路由目标 | 说明 |
|---|---|---|
/mcp |
<MCPSettings> |
交互式服务器管理 UI |
/mcp no-redirect |
<MCPSettings> |
绕过 ant 重定向 |
/mcp reconnect <name> |
<MCPReconnect> |
重连指定服务器 |
/mcp enable [name] |
<MCPToggle action="enable"> |
启用服务器(默认 all) |
/mcp disable [name] |
<MCPToggle action="disable"> |
禁用服务器(默认 all) |
MCPToggle 组件
MCPToggle 是一个无 UI 的效果组件(返回 null),通过 useEffect 执行一次性操作:
- 从
appState.mcp.clients中筛选目标服务器(排除ide) - 调用
toggleMcpServer(name)切换启用状态 - 通过
onComplete回调返回结果消息
第四层:交互式 UI 状态机
MCPSettings — 视图控制器
文件: src/components/mcp/MCPSettings.tsx
MCPSettings 是整个交互式界面的控制器,用 React state 驱动一个 5 状态的视图状态机:
type MCPViewState =
| { type: 'list'; defaultTab?: string }
| { type: 'server-menu'; server: ServerInfo }
| { type: 'server-tools'; server: ServerInfo }
| { type: 'server-tool-detail'; server: ServerInfo; toolIndex: number }
| { type: 'agent-server-menu'; agentServer: AgentMcpServerInfo }
状态转换图:
list ──(选中普通服务器)──→ server-menu ──(查看工具)──→ server-tools ──(选中工具)──→ server-tool-detail
│ │ │ │
│ └──(Esc/返回)──→ list └──(返回)──→ server-menu └──(返回)──→ server-tools
│
└──(选中 Agent 服务器)──→ agent-server-menu
│
└──(Esc/返回)──→ list
MCPSettings 数据准备
组件启动时:
- 从
appState.mcp.clients获取所有 MCP 客户端,过滤掉ide类型 - 按传输类型(stdio/sse/http/claudeai-proxy)分类
- 对远程服务器检查 OAuth 认证状态
- 从
appState.agentDefinitions提取 Agent 专属 MCP 服务器 - 若无任何服务器,直接调用
onComplete显示提示信息
MCPListPanel — 服务器列表
文件: src/components/mcp/MCPListPanel.tsx
这是用户看到的"子项选择"界面,负责:
分组与排序:
Project MCPs (.mcp.json) ← scope: project
Local MCPs (settings.local.json) ← scope: local
User MCPs (settings.json) ← scope: user
Enterprise MCPs ← scope: enterprise
claude.ai ← type: claudeai-proxy
Agent MCPs ← 来自 agent 定义
Built-in MCPs (always available) ← scope: dynamic
状态图标:
| 状态 | 图标 | 文字 |
|---|---|---|
connected |
✓ (绿色) | connected |
disabled |
○ (灰色) | disabled |
pending |
○ (灰色) | connecting… / reconnecting (n/m)… |
needs-auth |
△ (黄色) | needs authentication |
failed |
✗ (红色) | failed |
键盘交互:
↑↓— 在扁平列表中上下移动光标(selectedIndex)Enter— 选中当前项,触发onSelectServer(server)→setViewState({ type: 'server-menu', server })Esc— 退出,调用onComplete('MCP dialog dismissed')
子菜单组件
选中某个服务器后,根据传输类型渲染不同的操作菜单:
| 传输类型 | 组件 | 可用操作 |
|---|---|---|
stdio |
MCPStdioServerMenu |
启用/禁用、重连、查看工具、删除 |
sse / http |
MCPRemoteServerMenu |
认证、启用/禁用、重连、查看工具、删除 |
| Agent | MCPAgentServerMenu |
查看 Agent 配置信息 |
与 CLI 模式的对比
REPL 斜杠命令和 CLI 参数模式对 mcp 子命令的处理方式完全不同:
| 维度 | REPL /mcp |
CLI claude mcp |
|---|---|---|
| 定义位置 | commands/mcp/index.ts + mcp.tsx |
main.tsx:4677-4757 (Commander.js) |
| 子命令路由 | call() 内手动 args.split() |
Commander.js .command() 链式注册 |
| 子命令集合 | enable, disable, reconnect, no-redirect | serve, add, remove, list, get, add-json, add-from-claude-desktop, reset-project-choices |
| 交互方式 | Ink React 组件(键盘导航) | 一次性执行并退出 |
| 处理器 | React 组件 (MCPSettings, MCPToggle) |
async handler 函数 (cli/handlers/mcp.tsx) |
两套子命令几乎没有重叠——REPL 侧重运行时交互(启用/禁用/浏览),CLI 侧重配置管理(添加/删除/列出)。
关键文件索引
| 文件 | 职责 |
|---|---|
src/utils/slashCommandParsing.ts |
斜杠命令输入解析 |
src/utils/processUserInput/processSlashCommand.tsx |
斜杠命令执行入口 |
src/commands.ts |
全局命令注册与查找 (findCommand) |
src/commands/mcp/index.ts |
/mcp 命令定义(type, name, load) |
src/commands/mcp/mcp.tsx |
/mcp 处理器,args 分发 + MCPToggle 组件 |
src/components/mcp/MCPSettings.tsx |
交互式 UI 状态机控制器 |
src/components/mcp/MCPListPanel.tsx |
服务器列表与键盘导航 |
src/components/mcp/MCPStdioServerMenu.tsx |
stdio 服务器操作菜单 |
src/components/mcp/MCPRemoteServerMenu.tsx |
远程服务器操作菜单 |
src/components/mcp/MCPAgentServerMenu.tsx |
Agent MCP 服务器菜单 |
src/components/mcp/MCPToolListView.tsx |
工具列表视图 |
src/components/mcp/MCPToolDetailView.tsx |
工具详情视图 |
src/main.tsx:4677-4757 |
CLI 模式 claude mcp 子命令注册 |
src/cli/handlers/mcp.tsx |
CLI 模式 handler 实现 |