返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / docs / mcp / page.tsx
1 import { buildPageMetadata } from "@/lib/page-meta";
2
3 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
4 const { locale } = await params;
5 const isZh = locale === "zh";
6 return buildPageMetadata({
7 path: "/docs/mcp",
8 locale,
9 title: isZh ? "MCP · Codewhale 文档" : "MCP · Codewhale Docs",
10 description: isZh
11 ? "通过 Model Context Protocol 消费外部工具服务器,或把 Codewhale 作为 MCP 服务器暴露。"
12 : "Consume external tool servers over the Model Context Protocol, or expose Codewhale itself as an MCP server.",
13 });
14 }
15
16 export default async function McpPage({ params }: { params: Promise<{ locale: string }> }) {
17 const { locale } = await params;
18 const isZh = locale === "zh";
19 const bodyClass = isZh
20 ? "text-ink-soft leading-[1.9] tracking-wide"
21 : "text-ink-soft leading-relaxed";
22
23 return (
24 <section className="space-y-10">
25 <section id="overview" className="scroll-mt-32">
26 <h2 className="font-display text-3xl mb-1">MCP</h2>
27 <p className={`${bodyClass} mt-3`}>
28 {isZh
29 ? "Codewhale 可以通过 MCP(Model Context Protocol)加载额外的工具。MCP 服务器可以是由 TUI 启动的本地 stdio 进程,也可以是远程 URL 服务器(Streamable HTTP,带旧版 SSE 回退)。连接成功的服务器会把工具注册进模型目录;失败或被禁用的服务器不会作为可用工具呈现给模型。"
30 : "Codewhale can load additional tools via MCP (Model Context Protocol). MCP servers can be local stdio processes that the TUI starts, or remote URL-based servers that speak Streamable HTTP with legacy SSE fallback. A successfully connected server registers its tools into the model catalog; a failed or disabled server is never presented as an available tool."}
31 </p>
32 <p className={`${bodyClass} mt-3`}>
33 {isZh ? (
34 <>
35 配置文件默认在 <code className="inline">~/.codewhale/mcp.json</code>
36 (新文件缺失时仍读取旧版 <code className="inline">~/.deepseek/mcp.json</code>),可用{" "}
37 <code className="inline">mcp_config_path</code> 或{" "}
38 <code className="inline">DEEPSEEK_MCP_CONFIG</code> 覆盖。也兼容其他客户端使用的{" "}
39 <code className="inline">mcpServers</code> 键名。
40 </>
41 ) : (
42 <>
43 The config file defaults to <code className="inline">~/.codewhale/mcp.json</code> (the
44 legacy <code className="inline">~/.deepseek/mcp.json</code> is still read when the
45 Codewhale file is absent), overridable with{" "}
46 <code className="inline">mcp_config_path</code> or{" "}
47 <code className="inline">DEEPSEEK_MCP_CONFIG</code>. The{" "}
48 <code className="inline">mcpServers</code> key used by other clients is accepted too.
49 </>
50 )}
51 </p>
52 </section>
53
54 <section id="setup" className="scroll-mt-32">
55 <h2 className="font-display text-2xl mb-1">{isZh ? "配置与管理" : "Setup and management"}</h2>
56 <p className={`${bodyClass} mt-3`}>
57 {isZh ? (
58 <>
59 用 <code className="inline">codewhale-tui mcp init</code> 生成初始配置;TUI 内的{" "}
60 <code className="inline">/mcp</code>{" "}
61 打开紧凑管理器,显示每个服务器的启用状态、传输方式、命令或 URL、超时和连接错误。常用命令:
62 </>
63 ) : (
64 <>
65 Bootstrap a starter config with <code className="inline">codewhale-tui mcp init</code>;
66 inside the TUI, <code className="inline">/mcp</code> opens a compact manager showing each
67 server's enabled state, transport, command or URL, timeouts, and connection errors. Common
68 commands:
69 </>
70 )}
71 </p>
72 <pre className="code-block mt-4">{`codewhale-tui mcp add <name> --command "<cmd>" --arg "<arg>"
73 codewhale-tui mcp add <name> --url "https://example.com/mcp" --bearer-token-env-var MCP_TOKEN
74 codewhale-tui mcp login <name> # OAuth for remote servers
75 codewhale-tui mcp list
76 codewhale-tui mcp validate`}</pre>
77 <p className={`${bodyClass} mt-3`}>
78 {isZh
79 ? "在 TUI 里做的配置编辑会立即写盘,但模型可见的 MCP 工具池不会热加载——管理器会把它标记为需要重启。/mcp validate 和 /mcp reload 会重新连接以刷新界面快照。"
80 : "Config edits made from the TUI are written immediately, but the model-visible MCP tool pool is not hot-reloaded — the manager marks it restart-required. /mcp validate and /mcp reload reconnect to refresh the on-screen snapshot."}
81 </p>
82 </section>
83
84 <section id="auth" className="scroll-mt-32">
85 <h2 className="font-display text-2xl mb-1">{isZh ? "远程认证" : "Remote authentication"}</h2>
86 <p className={`${bodyClass} mt-3`}>
87 {isZh
88 ? "URL 服务器可以使用静态 headers、从环境变量派生的 env_headers、bearer_token_env_var 或 OAuth。优先级是保守的:先应用 headers 和 env_headers;bearer_token_env_var 只在尚未设置 Authorization 时添加;OAuth 登录获取的令牌同样不会覆盖已有的显式 header。应避免提交字面量 Authorization header——优先用 env_headers、bearer_token_env_var 或 OAuth 登录,让秘密留在 MCP 文件之外。"
89 : "URL-based servers can use static headers, env-derived env_headers, bearer_token_env_var, or OAuth. Precedence is conservative: headers and env_headers apply first; bearer_token_env_var adds an Authorization header only when one is not already set; OAuth login tokens likewise never override an explicit header. Avoid committing literal Authorization headers — prefer env_headers, bearer_token_env_var, or OAuth login so secrets stay outside the MCP file."}
90 </p>
91 </section>
92
93 <section id="tools" className="scroll-mt-32">
94 <h2 className="font-display text-2xl mb-1">{isZh ? "工具命名与安全" : "Tool naming and safety"}</h2>
95 <p className={`${bodyClass} mt-3`}>
96 {isZh ? (
97 <>
98 发现的 MCP 工具以 <code className="inline">mcp_&lt;server&gt;_&lt;tool&gt;</code>{" "}
99 的形式暴露给模型——例如名为 <code className="inline">git</code> 的服务器的{" "}
100 <code className="inline">status</code> 工具会变成{" "}
101 <code className="inline">mcp_git_status</code>。MCP
102 工具和内置工具走同一套审批框架:只读的 MCP 辅助工具在策略允许时可免提示运行,有副作用的 MCP
103 工具需要审批,Full Access 也不会绕过硬策略拦截。
104 </>
105 ) : (
106 <>
107 Discovered MCP tools are exposed to the model as{" "}
108 <code className="inline">mcp_&lt;server&gt;_&lt;tool&gt;</code> — a server named{" "}
109 <code className="inline">git</code> with a <code className="inline">status</code> tool
110 becomes <code className="inline">mcp_git_status</code>. MCP tools flow through the same
111 approval framework as built-in tools: read-only MCP helpers can run without prompts when
112 policy permits, side-effectful MCP tools require approval, and Full Access does not bypass
113 hard policy holds.
114 </>
115 )}
116 </p>
117 <p className={`${bodyClass} mt-3`}>
118 {isZh
119 ? "只配置你信任的 MCP 服务器,并把 MCP 服务器配置视为等同于在本机运行代码。经过审查的本地插件包也可以贡献 MCP 服务器:它们复用同一个 MCP 管理器、审批和网络策略路径,以 <plugin>-<server> 的命名空间身份出现,边界比手写的 mcp.json 更严格。"
120 : "Only configure MCP servers you trust, and treat MCP server configuration as equivalent to running code on your machine. Reviewed local plugin bundles can also contribute MCP servers: they reuse the same MCP manager, approval, and network-policy paths, appear under namespaced <plugin>-<server> identities, and are held to a stricter boundary than hand-written mcp.json."}
121 </p>
122 </section>
123
124 <section id="server" className="scroll-mt-32">
125 <h2 className="font-display text-2xl mb-1">
126 {isZh ? "把 Codewhale 作为 MCP 服务器" : "Codewhale as an MCP server"}
127 </h2>
128 <p className={`${bodyClass} mt-3`}>
129 {isZh ? (
130 <>
131 <code className="inline">codewhale-tui serve --mcp</code> 会把 Codewhale
132 作为 stdio MCP 服务器运行,让其他会话(或任何 MCP 客户端)调用它的工具;
133 <code className="inline">codewhale mcp-server</code> 是 dispatcher
134 暴露的等价入口。<code className="inline">codewhale-tui mcp add-self</code>{" "}
135 会自动解析当前二进制路径并把服务器写进你的 MCP 配置。注意区分:
136 <code className="inline">serve --http</code> 是运行时 HTTP/SSE API,是另一种模式。
137 </>
138 ) : (
139 <>
140 <code className="inline">codewhale-tui serve --mcp</code> runs Codewhale as an stdio MCP
141 server so other sessions (or any MCP client) can call its tools;{" "}
142 <code className="inline">codewhale mcp-server</code> is the equivalent dispatcher
143 entrypoint. <code className="inline">codewhale-tui mcp add-self</code> resolves the current
144 binary path and writes the server into your MCP config. Keep the modes distinct:{" "}
145 <code className="inline">serve --http</code> is the runtime HTTP/SSE API, a separate
146 surface.
147 </>
148 )}
149 </p>
150 </section>
151
152 <section id="source" className="hairline-t pt-8">
153 <p className="text-sm text-ink-mute">
154 {isZh
155 ? "来源文档:docs/MCP.md · 更新时请同步修改 docs-map.ts。"
156 : "Source document: docs/MCP.md · Update docs-map.ts when changing."}
157 </p>
158 </section>
159 </section>
160 );
161 }
162
162 lines Plain Text