无状态MCP重新引起了我的兴趣(并启发了mcp-explorer和datasette-mcp)
摘要
Simon Willison讨论了简化协议实现的无状态MCP(MCP 2.0)规范,并介绍了他的新工具mcp-explorer和datasette-mcp,这些工具利用该规范构建。
暂无内容
查看缓存全文
缓存时间: 2026/08/03 01:29
# 无状态 MCP 重新引起了我的兴趣(并催生了 mcp-explorer 和 datasette-mcp)
来源:https://simonwillison.net/2026/Jul/31/stateless-mcp/
2026 年 7 月 31 日,星期二,是无状态 MCP 日(https://x.com/ade_oshineye/status/2082129440943866149)——MCP 2.0 的正式发布,或者用更正式但更难记的名字:2026-07-28 Model Context Protocol 规范(https://blog.modelcontextprotocol.io/posts/2026-07-28/)。这是 MCP 规范自首次发布以来最重要的一次变更,也重新点燃了我个人对该协议的兴趣。
背景介绍:MCP 即 Model Context Protocol(模型上下文协议),它描述了一种向基于 LLM 的智能体框架暴露新工具的标准方式。该协议由 Anthropic 于 2024 年 11 月推出(https://www.anthropic.com/news/model-context-protocol),在 2025 年大部分时间里引起了*巨大*的关注热潮,但随后在人们发现一个能访问终端和 `curl` 的智能体框架可以用更灵活的方式完成 MCP 能做的绝大部分事情后,MCP 多少被 Skills(https://simonwillison.net/2025/Oct/16/claude-skills/)(同样是 Anthropic 的发明)所掩盖。我在 2025 年回顾(https://simonwillison.net/2025/Dec/31/the-year-in-llms/#the-only-year-of-mcp)中写过这件事。
现在我又回到了 MCP。给智能体一个可以访问互联网的 shell 环境充满了风险(https://simonwillison.net/2026/Jul/22/openai-cyberattack/),而且需要一个足够强大的模型来有效驱动这样的环境。MCP 工具更容易审计和控制,而且足够简单,即使是能在笔记本上运行的较小模型也能很好地驱动它们。新的无状态 MCP 规范也大大降低了实现客户端和服务器的复杂度。我这周就构建了三个这样的工具!
#### 无状态 MCP 带来了哪些便利
有状态和无状态 MCP 之间差异的最佳演示,在这篇介绍新规范 RC 版的 5 月 21 日博客文章(https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/)中。它包含了一个清晰的"前后对比"示例。
较旧的有状态 MCP(我称之为"遗留 MCP")需要两个 HTTP 请求——第一个用于初始化会话并获得 `Mcp-Session-Id`,第二个才真正调用工具:
```
POST /mcp HTTP/1.1
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": { },
"clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
POST /mcp HTTP/1.1
Mcp-Session-Id: 1868a90c-3a3f-4f5b
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
}
}
}
```
新的无状态方式只需要一个 HTTP 请求,看起来像这样:
```
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
},
"_meta": {
"io.modelcontextprotocol/clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
}
```
从客户端和服务器端的实现角度来看,这都简洁得多。它也更适合构建可扩展的 Web 应用,因为现在你不再需要维护服务器端状态来追踪那些会话 ID,也不必担心将同一会话路由到同一台后端机器。
#### mcp-explorer
我找不到一个很好的 CLI 工具来交互式地探查 MCP 服务器,所以让 Codex 帮我构建了一个。**mcp-explorer(https://github.com/simonw/mcp-explorer)** 就是成果。它是一个无状态的 Python CLI 工具,所以你甚至不需要安装就可以试用——它可以像这样通过 uvx(https://docs.astral.sh/uv/guides/tools/#running-tools)运行:
```
uvx mcp-explorer list https://agentic-mermaid.dev/mcp
```
这会查询 Ade Oshineye 的 agentic-mermaid.dev(https://agentic-mermaid.dev/)演示 MCP。上面的命令会返回以下工具列表:
```
execute(code: string, timeoutMs?: integer) - Execute Mermaid SDK code
Run JavaScript in an isolated sandbox; return a value.
describe_sdk(family: string, detail?: string) - Describe Mermaid SDK operations
Return version-matched mutation operations for one diagram family.
render_svg(source: string, options?: object) - Render Mermaid as SVG
Render a Mermaid source string to themeable SVG. Returns { ok, svg }.
render_ascii(source: string, useAscii?: boolean, targetWidth?: integer, options?: object) - Render Mermaid as text
Render a Mermaid source string to text. Returns { ok, text }.
render_png(source: string, scale?: number, background?: string, fitTo?: object, options?: object) - Render Mermaid as PNG
Rasterize a Mermaid source string to PNG. Returns { ok, png_base64 }.
...
```
然后要查看某个工具的详细信息:
```
uvx mcp-explorer inspect render_svg
```
这会输出大量信息,包括输入和输出的 JSON schema。要调用该工具并传入参数:
```
uvx mcp-explorer call \
https://agentic-mermaid.dev/mcp \
render_svg \
-a source 'graph TD; A-->B' \
-a options '{"padding":24}'
```
返回结果:
```
{"ok":true,"svg":"<svg ...>...</svg>"}
```
我实现了一个 `-a name '{"json": "or text"}'` 的参数语法,因为 JSON 字符串的 shell 转义太繁琐了。文档(https://github.com/simonw/mcp-explorer/blob/main/README.md)中有更多关于不同参数传递方式的详细说明。
`list`、`inspect` 和 `call` 这三个子命令涵盖了 95% 的"让我看看这个 MCP 服务器能做什么"的需求。也许这就是我真正需要的全部功能。
#### datasette-mcp
现在无状态 MCP 让实现 MCP 服务器变得如此容易,我忍不住为 Datasette 构建了一个官方插件。**datasette-mcp(https://github.com/simonw/datasette-mcp)** 目前版本为 0.1a0,它基于新的无状态规范,并做了以下两件事:
1. 它利用新的 plugin hook(https://docs.datasette.io/en/latest/plugin_hooks.html)暴露任意 SQL 查询工具
2. 它引入了 `tree` 工具,用于发现模式(并已被安全加固以绕过 Datasette 的默认权限系统)
这给了我一个非常有趣的演示机制。例如,在 https://datasette.simonwillison.net/-/mcp 处有一个运行 demo 的实例。以下是我在 Claude Code 中一直使用的一个提示词:
> `list tables in simonwillison.net`
然后:
> `what has Simon said recently about MCP?`
它运行了 7 个单独的 SQL 查询来得出答案。
#### llm-mcp-client
我的 LLM 工具(https://llm.datasette.io/)早就该有一个官方的 MCP 集成了。新的 alpha 版 llm-mcp-client(https://github.com/simonw/llm-mcp-client)插件就是我对这件事的尝试:
```
llm install llm-mcp-client
llm -T 'MCP("https://datasette.simonwillison.net/-/mcp")' 'count the notes'
```
以下是输出(包括推理过程,我使用的是 LLM 0.32rc2(https://simonwillison.net/2026/Jul/30/llm-rc2/)):
> ***考虑笔记数量***
> *我看到"count the notes"这个问题很可能是在要求我统计博客笔记的数量。也可能是指已发布的笔记或草稿,所以存在一些歧义。我需要弄清楚笔记的总数,可能需要对已发布的笔记和草稿分别计数,才能得到明确的答案。让我们执行这个计数吧!*
>
> 一共有 **151 条笔记**。
以及该提示词的 llm logs 输出(https://gist.github.com/simonw/4e8f558766150658ce35eab4f0fc3e04)。一旦这个插件完全成熟,我考虑把它直接整合进 LLM 核心。我也很期待在 Datasette Agent(https://agent.datasette.io/)和 llm-coding-agent(https://github.com/simonw/llm-coding-agent)中试验 MCP。
#### MCP 是一种更安全的智能体构建方式
在 MCP 首次发布几个月后,我写了 Model Context Protocol has prompt injection security problems(https://simonwillison.net/2025/Apr/9/mcp-prompt-injection/),在文中我指出,让最终用户自行混搭工具的模式,把防止数据外泄攻击的责任推给了用户自己。当时我还没有发明"致命三重奏"(Lethal Trifecta,https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/)这个说法,但那绝对是我心中所想。
随后,具有任意 shell 和 `curl` 访问权限的通用智能体出现了,而这在安全方面要难得多!
我对 MCP 逐渐欣赏的一点是,与在开放网络环境中执行任意命令相比——这是当今大多数通用和编码智能体工具的默认方式——MCP 更容易推理智能体的能力以及可能出问题的地方。我计划在基于 LLM 构建敏感应用时大量使用 MCP。
相似文章
@Saboo_Shubham_: MCP 刚刚变为无状态。这非常合理。
MCP(模型上下文协议)已更新为无状态,这一变化使其更加高效和合理。
新版MCP规范解决企业采用的主要障碍
模型上下文协议(MCP)发布了新规范,采用无状态改造以适配企业级规模,并引入弃用策略,旨在简化大规模部署。
@svpino: MCP 并没有消亡。对于那些总说“但 MCP 会在你的上下文里塞垃圾”的人,这个抱怨已经过时了:现……
为 MCP(模型上下文协议)辩护,反驳其会向上下文注入垃圾信息的批评。指出 Claude Code、Codex 和 Cursor 等现代工具已实现渐进式披露,并按需加载 MCP 工具,使该抱怨过时。作者认为 MCP 最适合需要身份验证和可发现性的云端托管平台。
MCP 2026-07-28 规范:传输层变为无状态
MCP 发布了新的规范版本 2026-07-28,从双向有状态协议转变为无状态的请求/响应核心,提升了可扩展性和可靠性。更新内容包括自描述请求、服务器发现、缓存提示和授权增强,并更新了 TypeScript、Python、Go 和 C# 的 SDK。
2026-07-28 MCP 规范发布候选版(阅读时间9分钟)
2026-07-28 的 MCP 规范发布候选版引入了无状态核心、MCP Apps 和 Tasks 等扩展、改进的授权机制以及正式的弃用策略,从而支持无需粘性会话的可扩展 HTTP 基础设施。