teaching-library
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@teaching-librarysearch for books about MCP"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Library Lab
这是一个面向学习者的 MCP(Model Context Protocol)完整示例。它不是生产级图书系统,而是一间足够小、可以逐行读懂的“教学图书馆”。
项目使用官方 Python SDK mcp 2.x 和 MCP 2026-07-28 协议。服务端同时兼容旧握手协议客户端。
你能学到什么
MCP 概念 | 本项目中的位置 | 作用 |
Server / Client |
| 能力提供方与能力消费方 |
Tools |
| 允许模型触发计算或副作用 |
Structured Output | Pydantic 返回模型 | 同时生成 |
Tool Annotations | 每个 | 声明只读、幂等、破坏性和开放世界提示 |
Resources |
| 应用控制的只读上下文 |
Resource Templates |
| 带参数的资源 URI |
Prompts |
| 可发现、可参数化的消息模板 |
Elicitation |
| 绕过模型,直接向用户确认敏感操作 |
Progress |
| 长任务进度通知 |
Errors |
| 区分可公开业务错误与内部异常 |
Transports | in-process、stdio、Streamable HTTP | 测试、本地宿主和网络部署 |
Discovery |
| 客户端运行时能力发现 |
Protocol negotiation |
| v2 自动发现并兼容旧协议 |
Related MCP server: BooksAPI-MCP
代码地图
src/mcp_library/
├── domain.py # 纯业务层,不依赖 MCP
├── server.py # MCP 能力注册与两种传输入口
└── client_demo.py # 发现、读取、调用、确认和进度处理
tests/
└── test_server.py # 使用进程内传输的协议集成测试建议按 domain.py → server.py → client_demo.py → tests 的顺序阅读。
环境与安装
本仓库当前验证环境是 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/discover;client.protocol_version可查看协商结果。现代协议没有长期会话和服务端主动回调通道。
Resolve(...)可把 elicitation 变成多轮请求结果,在新旧协议中使用同一套工具实现。旧式
ctx.elicit()、sampling、roots 和协议级 logging 属于旧协议时代能力;学习遗留系统时仍会遇到,但不应作为新项目主路径。
错误处理与安全
SDK 会隐藏普通未处理异常,只向客户端返回通用工具错误,以免泄露堆栈或内部数据。可预期、可以公开的业务错误应转换为 ToolError。不要把密钥、数据库异常或内部路径放进 ToolError。
ToolAnnotations 是给客户端和模型的提示,不是权限控制。生产环境仍需独立实现身份认证、授权、参数校验、审计和速率限制。
运行测试
python -m pytest -q测试不占用端口,覆盖能力发现、结构化输出、参数化资源、elicitation、副作用、进度通知和错误结果。
推荐练习
增加
library://loans/{member_id}资源模板。为搜索加入游标分页,并观察 list API 自身的分页结构。
把内存
Library替换为 SQLite,同时保持 MCP 层不变。给 HTTP 服务增加 OAuth 资源服务器配置。
编写一个会拒绝借阅的 elicitation callback,并断言库存不变化。
人为抛出普通异常,对比它与
ToolError的客户端结果和服务端日志。
参考资料
Available Tools
4 toolsaudit_inventory盘点库存ARead-onlyIdempotent
模拟耗时盘点,并逐步报告进度
| Name | Required | Description | Default |
|---|---|---|---|
| delay_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds value by stating that the operation is simulated, time-consuming, and reports progress incrementally. This is consistent with the annotations and gives the agent a clear sense of runtime and output behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence that states what the tool does and its key behavioral trait. No filler or redundant information is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, annotations, and a single self-explanatory parameter, the description is mostly sufficient for a simple simulation tool. However, it omits explicit guidance on how the progress reporting is delivered and when an agent should choose this tool over siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not explicitly explain delay_seconds. However, the phrase '耗时盘点' implies the delay parameter controls simulated duration, and the parameter name plus default value make its purpose reasonably inferable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('simulate') and resource ('inventory count'), and adds the distinct behavior of reporting progress step by step. This clearly separates audit_inventory from the book-focused siblings search_books, checkout_book, and return_book.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for simulating an inventory audit, but it does not state when to use it versus alternatives, nor does it mention any exclusions or preconditions. An agent must infer usage context from the word 'simulate'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
checkout_book借阅图书A
借阅一本可用图书;执行前必须由用户确认
| Name | Required | Description | Default |
|---|---|---|---|
| book_id | Yes | ||
| member_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | |
| book_id | Yes | |
| loan_id | Yes | |
| member_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a non-read-only, non-destructive mutation. The description adds a meaningful behavioral guardrail—user confirmation is mandatory before execution—which is not available from annotations or schema alone. It does not detail side effects like inventory changes, but the availability wording partially implies them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence with the action stated first and the confirmation requirement after. No filler, repetition, or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter checkout tool with an output schema and annotations, the description is nearly complete. It could be improved by stating what happens if the book is unavailable or how confirmation is elicited, but these are not essential for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explicitly explain the roles of book_id and member_id. However, the parameter names are self-explanatory, and 'available book' implies book_id should refer to a borrowable copy, so there is minimal but useful implicit guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific action, '借阅' (checkout), with a clear resource, '一本可用图书' (an available book), which distinguishes it from sibling tools like return_book, search_books, and audit_inventory. It also adds a condition beyond the title: the book must be available.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear execution context: borrow an available book, and user confirmation is required before execution. It does not explicitly name alternatives or when-not-to-use cases, but the domain and sibling tool names make the intended usage reasonably clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
return_book归还图书AIdempotent
根据借阅单归还图书;重复调用结果不变
| Name | Required | Description | Default |
|---|---|---|---|
| loan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | |
| book_id | Yes | |
| loan_id | Yes | |
| member_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, and the description restates idempotency ('重复调用结果不变') without adding new behavioral context such as side effects on book availability, permissions required, or error behavior. The description does not contradict annotations, but it also does not enrich the safety profile beyond what structured data provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no filler. It front-loads the core action ('根据借阅单归还图书') and appends the idempotency note, which is directly relevant. Every word contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with output schema and annotations covering idempotency and non-destructiveness, the description is mostly sufficient. It lacks explicit mention of error cases or prerequisites (e.g., loan must exist and be active), but the simplicity of the tool and the supporting structured data make it reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only the bare parameter name loan_id with no description, and schema description coverage is 0%. The description's '借阅单' (loan slip) gives a hint that loan_id references a loan slip, adding a small amount of meaning beyond the schema. However, it does not explain the format, where to obtain it, or how it relates to the returned book, leaving the agent partially in the dark.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb (归还/return) and resource (图书/book), and clarifies the basis (借阅单/loan slip). It clearly distinguishes itself from sibling tools like checkout_book by representing the inverse operation, and from search_books and audit_inventory which do not mutate loans.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied: a book is returned after being checked out, using the loan slip. However, there is no explicit guidance about when to use this tool versus alternatives, nor any mention of prerequisites such as the loan being active or already returned. The route to the right tool is obvious from the name and description but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_books搜索图书ARead-onlyIdempotent
按标题、作者或标签搜索书目
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| books | Yes | |
| query | Yes | |
| total | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds meaningful behavioral context by specifying that the search operates on title, author, or tag fields, which goes beyond the schema's simple 'query' string. It does not disclose pagination or result ordering, but this is minor for a simple search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, compact sentence that delivers the essential information immediately. Every word earns its place and there is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter search tool with an output schema and safety-revealing annotations, the description provides sufficient context to call the tool correctly. The search criteria are specified, required parameters are evident from the schema, and the output schema covers return values. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the underspecified 'query' parameter. It does so by clarifying that query can be a title, author, or tag. However, it does not explain the 'limit' parameter at all; although the default value provides some hint, the description leaves that semantic gap open.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('search') with a clear resource ('book catalog/bibliography') and explicitly lists the searchable criteria (title, author, or tag). This makes it easily distinguishable from the sibling tools, which are mutations or inventory audits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for finding books by title, author, or tag, which sets context against the mutation siblings (checkout_book, return_book). It does not explicitly state when not to use it or provide alternative selection criteria, but the sibling names make the distinction obvious enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
每个工具对应一个独立且清晰的动作:搜索、借出、归还、盘点,边界分明,无功能重叠,代理可以轻松区分选择。
所有工具均采用小写snake_case且遵循动词_名词模式,如search_books、checkout_book,命名风格高度一致,可预测性强。
4个工具数量精简,每个工具都在借阅流程中扮演必要角色,没有冗余,符合教学库的定位和范围。
核心借阅工作流(搜索、借出、归还)已覆盖,但缺少图书的增删改以及查看当前借阅列表等基本管理操作,存在明显但非致命的覆盖缺口。
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
The Mercado Pago MCP Server implements the Model Context Protocol to provide AI agents and LLMs with access to Mercado Pago's APIs and tools within compatible development environments. It acts as an intermediary that translates Mercado Pago resources into executable functions (tools) that AI applications can invoke to perform actions and automate flows. The server simplifies integration, enables using documentation to implement or improve code, and optimizes operations through natural language interactions without manual implementations.
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn educational implementation of a Model Context Protocol server that demonstrates how to build a functional MCP server for integrating with various LLM clients like Claude Desktop.1163MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server implementation built with Python and FastAPI for educational purposes. Demonstrates MCP server functionality through a books API interface.MIT
- FlicenseAqualityDmaintenanceA demo server that allows AI models to manage a personal reading list stored in a local SQLite database. It provides tools for searching, adding, and updating books while demonstrating core Model Context Protocol features like resources and tools.5
- FlicenseNot gradedqualityDmaintenanceA foundational implementation of a Model Context Protocol (MCP) server designed for educational purposes. It demonstrates the complete interaction between an LLM, an inference engine, and a client during an agentic call.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/debuger00/MCPdemo'
If you have feedback or need assistance with the MCP directory API, please join our Discord server