| 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_<server>_<tool></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_<server>_<tool></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 |