Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Library Lab

这是一个面向学习者的 MCP(Model Context Protocol)完整示例。它不是生产级图书系统,而是一间足够小、可以逐行读懂的“教学图书馆”。

项目使用官方 Python SDK mcp 2.x 和 MCP 2026-07-28 协议。服务端同时兼容旧握手协议客户端。

你能学到什么

MCP 概念 本项目中的位置 作用
Server / Client server.py / client_demo.py 能力提供方与能力消费方
Tools search_bookscheckout_book 允许模型触发计算或副作用
Structured Output Pydantic 返回模型 同时生成 outputSchemastructuredContent
Tool Annotations 每个 @server.tool 声明只读、幂等、破坏性和开放世界提示
Resources library://catalog 应用控制的只读上下文
Resource Templates library://books/{book_id} 带参数的资源 URI
Prompts make-research-plan 可发现、可参数化的消息模板
Elicitation Resolve(ask_checkout_approval) 绕过模型,直接向用户确认敏感操作
Progress audit_inventory 长任务进度通知
Errors ToolError 区分可公开业务错误与内部异常
Transports in-process、stdio、Streamable HTTP 测试、本地宿主和网络部署
Discovery list_tools/resources/prompts 客户端运行时能力发现
Protocol negotiation client.protocol_version v2 自动发现并兼容旧协议

代码地图

src/mcp_library/
├── domain.py       # 纯业务层,不依赖 MCP
├── server.py       # MCP 能力注册与两种传输入口
└── client_demo.py  # 发现、读取、调用、确认和进度处理
tests/
└── test_server.py  # 使用进程内传输的协议集成测试

建议按 domain.pyserver.pyclient_demo.pytests 的顺序阅读。

环境与安装

本仓库当前验证环境是 Python 3.13 和 mcp 2.1.1。使用当前终端的 Python 安装:

python -m pip install -e ".[dev]"

也可以使用 uv:

uv sync

确认解释器与 SDK:

python -c "import sys, mcp; print(sys.executable); print(mcp.__file__)"
python -m pip show mcp

最快体验:进程内 Client

不启动端口,Client 与 Server 仍经过完整的 MCP 类型和分发层:

$env:PYTHONPATH = "src"
python -m mcp_library.client_demo

这个演示会依次完成协议协商、能力发现、资源读取、工具调用、Prompt 获取、借阅确认,以及盘点进度通知。

stdio 传输

stdio 适合 Claude Desktop、Codex 等本地宿主拉起子进程。协议消息走标准输入输出,因此服务端不要向 stdout 随意 print,日志应写 stderr。

$env:PYTHONPATH = "src"
python -m mcp_library.server --transport stdio

客户端配置示例(路径按实际解释器修改):

{
  "mcpServers": {
    "teaching-library": {
      "command": "E:\\aaa_SpecializedSoftware\\MiniConda\\envs\\python_3_13\\python.exe",
      "args": ["-m", "mcp_library.server", "--transport", "stdio"],
      "cwd": "E:\\program\\agent\\0000personal-projects\\08MCP",
      "env": {"PYTHONPATH": "src"}
    }
  }
}

Streamable HTTP 传输

终端一:

$env:PYTHONPATH = "src"
python -m mcp_library.server --transport streamable-http --host 127.0.0.1 --port 8000

终端二:

$env:PYTHONPATH = "src"
python -m mcp_library.client_demo --url http://127.0.0.1:8000/mcp

网络部署时需要进一步增加 HTTPS、认证、Host/Origin 校验、限流、超时和持久化存储。本项目只监听 127.0.0.1,不应直接暴露到公网。

使用 MCP Inspector

服务启动后,可用 Inspector 检查 schema 和手动发起调用:

npx -y @modelcontextprotocol/inspector

连接 Streamable HTTP 地址 http://127.0.0.1:8000/mcp。Inspector 是独立的 Node 工具,因此首次运行需要 Node.js 和联网下载。

三种原语如何选择

  • Tool:模型决定何时调用;适合搜索、计算、写入或外部 API。
  • Resource:应用决定何时提供;适合文件、记录、配置和稳定上下文。
  • Prompt:用户或应用选择模板;适合固化高质量工作流提示。

不要仅因为某个 Python 函数容易写,就把它注册成 Tool。涉及写操作时应最小化权限、明确注解,并在真正执行前确认。

v2 协议值得注意的变化

  • FastMCP 在 SDK v2 中更名为 MCPServer
  • 默认 Client 会先尝试 server/discoverclient.protocol_version 可查看协商结果。
  • 现代协议没有长期会话和服务端主动回调通道。
  • Resolve(...) 可把 elicitation 变成多轮请求结果,在新旧协议中使用同一套工具实现。
  • 旧式 ctx.elicit()、sampling、roots 和协议级 logging 属于旧协议时代能力;学习遗留系统时仍会遇到,但不应作为新项目主路径。

错误处理与安全

SDK 会隐藏普通未处理异常,只向客户端返回通用工具错误,以免泄露堆栈或内部数据。可预期、可以公开的业务错误应转换为 ToolError。不要把密钥、数据库异常或内部路径放进 ToolError

ToolAnnotations 是给客户端和模型的提示,不是权限控制。生产环境仍需独立实现身份认证、授权、参数校验、审计和速率限制。

运行测试

python -m pytest -q

测试不占用端口,覆盖能力发现、结构化输出、参数化资源、elicitation、副作用、进度通知和错误结果。

推荐练习

  1. 增加 library://loans/{member_id} 资源模板。
  2. 为搜索加入游标分页,并观察 list API 自身的分页结构。
  3. 把内存 Library 替换为 SQLite,同时保持 MCP 层不变。
  4. 给 HTTP 服务增加 OAuth 资源服务器配置。
  5. 编写一个会拒绝借阅的 elicitation callback,并断言库存不变化。
  6. 人为抛出普通异常,对比它与 ToolError 的客户端结果和服务端日志。

参考资料

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages