MCP Server
Sigil 的 MCP Server 是 AI 客户端接入的入口。本篇讲它的协议、监听机制、客户端授权。
协议选择
Sigil 实现的是 Model Context Protocol(MCP)的 Streamable HTTP transport,JSON-RPC 2.0 消息封装,Bearer Token 鉴权(每个客户端独立 Token)。
支持的协议版本
| 版本 | 说明 |
|---|---|
| 2026-07-28 | 当前版本。无状态化改版 |
| 2025-11-25 | |
| 2025-06-18 | 结构化输出 |
| 2025-03-26 | |
| 2024-11-05 | 首个正式版 |
老客户端按旧的握手方式接入,新客户端按新的无状态方式接入,同一个端点同时服务两代 —— 升级 Sigil 不会让你手上任何一个客户端失效。
2026-07-28 这版改了什么
那一版是 MCP 发布以来最大的一次修订:把协议从「有长连接、有会话」改成 「每个请求都是独立的普通 HTTP 请求」—— 删掉了握手、会话 ID、断线续传。
对 Sigil 来说迁移成本很低,因为它本来就是这么实现的:从第一版起就没有会话状态, 也没用那些被弃用的特性。当初为了让连接更稳而做的设计,恰好走在了规范后来的方向上。
顺带说明一个刻意不做的取舍:那一版引入了「服务端要东西时让客户端带着答案重试」的 机制(MRTR),用来替代原先由服务端发起的请求。Sigil 不实现它 —— 它会把「审批」变成一轮协议交互、交到 AI 客户端手里, 而 Sigil 审批的全部意义就是它发生在桌面端、AI 碰不到。
其它协议特性
- 结构化输出:
tools/call在人读content之外,对支持的能力额外返回机读的structuredContent;tools/list为这些能力同时声明outputSchema - 工具注解:
tools/list为每个能力标注readOnlyHint/destructiveHint, 客户端据此对只读工具免确认、对破坏型工具强确认 - 服务器自述:
server/discover一次返回身份、支持的协议版本与能力, 客户端不必逐个探测 - 缓存提示:列表类结果带「可以缓存多久」的提示,见下方缓存与刷新
MCP 是 Anthropic 推出的开放协议,被 Claude Code、Cursor、Cline、Zed、Continue 等 主流 AI 客户端原生支持。
缓存与刷新
工具列表是个不小的载荷(当前上百个能力),客户端每次重连都重新拉一遍是浪费。 所以 Sigil 会告诉客户端「这份结果可以当新鲜的用多久」。
| 内容 | 可缓存 | 为什么 |
|---|---|---|
| 工具列表 | 5 秒 | 它随金库凭据实时变 —— 存一条新凭据,对应工具要立刻出现 |
| 斜杠命令列表 | 1 小时 | 内置不变,只随 Sigil 升级变 |
| 服务器自述 | 1 小时 | 同上 |
工具列表刻意取得很短,就是为了保住「加了凭据马上能用」这个体验。 代价只是客户端偶尔多拉一次列表 —— 那点开销远小于让你干等。
缓存不会跨客户端共享
所有可缓存结果都标记为「私有」。这不是保守,是必须的:Sigil 的工具列表是 按 Token 过滤的(每个客户端能看到的能力和凭据都可能不同)。 如果允许共享缓存,一个受限客户端就可能拿到另一个全权客户端的工具列表 —— 那会让 Token 范围这个功能形同虚设。
Sigil 不主动推送「列表变了」
MCP 允许服务端在工具列表变化时推一条通知,让客户端立刻刷新。Sigil 目前不发这类推送, 客户端靠上面的缓存时长自行判断何时重取 —— 这也是工具列表的缓存时间被压到 5 秒的原因。
默认配置
| 项 | 值 |
|---|---|
| 监听地址 | 127.0.0.1:8421(仅本机回环) |
| 路径 | /mcp |
| 端口策略 | 8421 被占用时自动顺延 |
| TLS | 不启用(仅本机回环,TLS 是 overkill) |
| Token 算法 | 自托管签发,Constant-time 比对 |
| Origin 校验 | 所有路由强制校验 Origin 头(防 DNS rebinding) |
| 端点文件 | endpoint.json 仅当前用户可读(Windows ACL / Unix 0600) |
如果需要绑定其他网口(如 0.0.0.0,给同一局域网的移动端用),需手动启用"远程网关"——这是显式行为,不会被默默开启。
Origin 校验(防 DNS rebinding)
MCP 规范要求本机 HTTP server 必须校验 Origin 头,否则恶意网页可借 DNS rebinding 让浏览器向 127.0.0.1:8421 发请求。Sigil 的策略:
- 无
Origin头 → 放行:非浏览器 MCP 客户端(Claude Code / Cursor / curl)天然不发 Origin,不受影响 Origin为本机回环(localhost/127.0.0.1/[::1])→ 放行- 其它外部域名 →
403 Forbidden(正是 rebinding 攻击的来源)
这道校验覆盖所有路由,包括无鉴权的 /health、/metrics,杜绝聚合指标被恶意网页旁路读取。
客户端授权
Token 颗粒度
Sigil 给每个客户端独立颁发 Bearer Token:
Sigil ──┬── Bearer "sk_sigil_aaaa..." ──→ Claude Code
├── Bearer "sk_sigil_bbbb..." ──→ Cursor
└── Bearer "sk_sigil_cccc..." ──→ Cline(仅只读)每个 Token 有独立的:
- 名称(出现在审计日志的 caller 列)
- 能力范围:哪些能力可调用 —— 不在范围内的,它连看都看不到
- 可见凭据:能用金库里的哪几条凭据 —— 范围外的凭据,调用时直接被拒
- 创建时间 / 最后使用时间
- 过期时间(可选)
- 是否启用
这两个范围是两道独立的闸,都得过。举个例子:给某个客户端放行了 git_repo_list,但可见凭据只给了 gitee —— 它可以列 Gitee 的仓库, 拿 github1 去列 GitHub 的仓库则会被拒绝,并告诉它缺的是哪条凭据。
撤销
撤销 Token = 立即让对应的客户端连接失效。在 MCP 页 → 客户端管理 → 行末"⋯" → 撤销。
撤销是即时生效的,不需要重启 Sigil。
Token 一次性显示
新建客户端时显示的明文 Token 只在生成那一刻可见——关闭对话框后,UI 不再展示,OS 密钥环里只有 hash 用于比对。
如果你忘了 Token:撤销旧的,重新生成一个。
协议方法(关心实现的人看)
Sigil 实现以下 MCP 方法:
| 方法 | 用途 |
|---|---|
initialize | 客户端握手 + 版本协商(声明 protocolVersion 2025-06-18) |
tools/list | 列出当前 Token 可用的所有能力(含 inputSchema / outputSchema / readOnlyHint / destructiveHint) |
tools/call | 调用某个能力(返回 content 人读文本 + 可选 structuredContent 机读结果) |
notifications/tools/list_changed | 服务端推送:能力列表变更 |
ping | 心跳 |
不支持的方法(Sigil 不暴露这些):
resources/*—— Sigil 不暴露文件资源prompts/*—— Sigil 不维护 Prompt 模板sampling/*—— Sigil 不做模型采样
只做凭据与能力代理——其他能力交给客户端自己实现。
工具列表怎么来的
调用 tools/list 时,Sigil 不是简单返回「所有内置能力」。清单要过三道收缩:
全部内置能力(约 160 个)
│
├─ ① 按金库现有凭据过滤 ← 没存 GitLab 凭据,就不给 gitlab_* 那 24 个
│
├─ ② 按 Token 的能力范围过滤 ← 只给了只读范围,写类工具它看不到
│
└─ ③ 按用户在「能力」页的开关过滤
│
└─→ 该客户端实际看到的工具列表范围越小,它看到的工具越少 —— 它甚至不知道还有别的工具存在。
按凭据渐进披露
上面第 ① 道值得单独说,因为这是你升级后会直接观察到的变化。
一台新装的 Sigil,金库是空的,AI 看到的工具就只有元工具和本地 Git 那几十个。 你往金库里存一条 GitLab Token,那 24 个 GitLab 工具立刻出现,不用重启。 删掉这条凭据,它们又收回去。
| 存了这类凭据 | 就会露出 |
|---|---|
gitlab_token | GitLab 那 24 个 |
s3_compatible | 对象存储(R2 / 腾讯云 COS) |
maven_central | Maven Central 发布相关 |
mqtt_broker | MQTT 设备相关 |
code_signing | 代码签名相关 |
为什么要这么做
这些工具对「没配对应凭据的人」是纯粹的噪声:它们占着工具列表的位置、每次对话都在消耗 上下文,而且给模型提供了几十个永远选不对的候选项。
工具面该跟着你配了什么走,而不是跟着代码里有什么走。
隐藏不是删除
被收起来的能力仍然在「能力」页里列着,只是标成禁用状态。你可以手动打开某一个 —— 手动开关过的能力会被记住,之后不再被自动收起来。你的选择优先于系统的推断。
导入类工具是例外
「从本地目录导入签名资产」「从 settings.xml 收编 Maven 配置」这两个工具的作用恰恰是 创建那类凭据。如果它们也按这个规则隐藏,就成了鸡生蛋 —— 所以它们始终露出。
写规则
光连上还不够。AI 知道「有这么个叫 sigil 的服务」,不代表它知道该怎么用好它 —— 它会去跑本地 git push(弹凭据窗卡死)、会问你要 Token、会猜一个不存在的工具名。
所以 Sigil 提供「写规则」:往 CLAUDE.md / AGENTS.md 这类 AI 的全局记忆文件里, 注入一段用法规则。内容包括:
- 推送 / 建仓 / 调 API 一律走 Sigil,绝不手拼明文 Token
- 不要跑会联网认证的本地 git 命令(会弹凭据窗卡住)
- 你金库里的凭据名与对应账号的映射表
- 当前可用的多平台统一工具清单
只动自己那一段
规则写在一对标记之间,写入时只替换标记之间的内容,你在同一文件里的其它内容原样保留 —— 这类文件往往早就有你自己写的一大堆规则。写之前还会自动备份一份 .sigil.bak。
如果目标文件读不出来(不是 UTF-8 编码、或正被别的编辑器独占打开),写入会中止并告诉你原因, 不会硬写。
升级后会提醒你更新
规则正文会随版本演进 —— 比如工具合并后,旧规则里写的名字就失效了。Sigil 会比对你文件里那段 规则与当前版本的差异,发现落后时主动弹窗提醒,一键更新即可。
这件事不靠「记得去点一下」:差异是自动算出来的,改了一个字就能发现。
接入配置失效自检
接入过的客户端,配置可能在你不知情的时候失效:换了安装路径、配置文件被别的工具改写、 端口变了、Token 被撤销。表现通常是「AI 说连不上 sigil」,但看不出是哪一环断了。
MCP 页会对每个已接入的客户端做自检,逐项标出状态:配置文件在不在、里面写的路径对不对、 Token 是否还有效、端点是否可达。发现问题给「一键修复」,重写正确的配置片段即可, 不用你去翻客户端的配置文件手改。
性能特征
- 单连接 RTT: < 5 ms(本机回环)
- 并发能力调用: 内部用 tokio 多任务,无明显瓶颈
- 内存占用: MCP Server 本身 < 30 MB(不含 Sigil UI)
写类能力(git_push / git_file_put 等)受限于目标服务的网络与执行时间,Sigil 不引入额外开销。
错误码
Sigil 遵循 MCP 标准错误响应,并增加了一组应用级 code:
| code | 说明 |
|---|---|
unauthorized | Bearer Token 无效 / 已撤销 |
not_in_scope | 该 Token 不允许调用此能力 |
credential_missing | 找不到合适的凭据 |
credential_expired | 凭据已过期 |
scope_policy_denied | 凭据的 Scope Policy 拒绝此能力 |
kill_switch_active | AI Kill Switch 已启用 |
confirmation_required | 写类能力需用户在 Sigil UI 确认 |
forbidden_command | 命中凭据的 Scope Policy 黑名单 |
客户端收到这些错误时,建议把 message 直接展示给用户——它们都是已经人化的中文描述。
远程网关(可选 / 进阶)
如果你需要让局域网其他机器(如手机、平板)也通过 MCP 访问本机 Sigil,可以在"设置 → 远程网关"启用:
- 监听地址改为
0.0.0.0:8421(或自定义网口) - 强制要求 Bearer Token 鉴权
- 建议同时启用"失败追踪"(连续 N 次错误后封禁源 IP)
如果要从公网访问,强烈建议自建反向代理(Caddy / Nginx)加 TLS + 双向 mTLS。Sigil 本身不内嵌 frpc / easytier 等内网穿透——这类二进制在不少国内杀软里被误报,体验不好。
远程网关是双刃剑。仅在你清楚知道自己在做什么时启用。