关于 mcp-ops
mcp-ops 是面向 Python 和 TypeScript 开发者的 MCP 服务构建、测试与部署指南,涵盖架构、传输、认证及常见问题。它还提供参考文档与事实检查脚本,帮助维护随生态变化的实现知识。
主要功能
- 01Python 与 TypeScript 服务端指南
- 02传输方式与认证模式参考
- 03工具、资源和提示词设计指引
- 04测试、调试与常见问题说明
- 05MCP 事实漂移检查脚本
适用场景
- 01选择本地或远程服务传输方式
- 02设计 MCP 工具和资源
- 03测试并排查服务端问题
MCP 相关
该技能汇总 MCP 服务端的构建、测试和部署模式,并提供 Python 与 TypeScript SDK 示例。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ 0xdarkmatter/ claude-mods --skill mcp-ops安装后在 Claude Code 中输入/mcp-ops确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/.gitkeepmcp-facts.jsonreferences/resources-prompts.mdserver-architecture.mdtesting-debugging.mdtool-handlers.mdtransport-auth.mdscripts/.gitkeepcheck-mcp-facts.pytests/run.sh详细介绍
MCP 运维
在 Python 和 TypeScript 中构建、测试和部署 Model Context Protocol 服务的全面实践模式。
生态信息经核实,截至 2026-07-05(独立版 FastMCP 主版本为 3)。
MCP 架构快速参考
┌─────────────────────────────────────────────────────────┐
│ MCP Host │
│ (Claude Desktop, Claude Code, Custom App) │
│ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Client A │ │ Client B │ │ Client C │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
└────────┼───────────────┼───────────────┼────────────────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│Transport│ │Transport│ │Transport│
│ (stdio) │ │ (SSE) │ │ (HTTP) │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌────────┴──┐ ┌──────┴────┐ ┌──────┴────┐
│ Server A │ │ Server B │ │ Server C │
│ │ │ │ │ │
│ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ │ Tools │ │ │ │Resources│ │ │ │Prompts │ │
│ └────────┘ │ │ └────────┘ │ │ └────────┘ │
│ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ │Resources│ │ │ │Prompts │ │ │ │ Tools │ │
│ └────────┘ │ │ └────────┘ │ │ └────────┘ │
└────────────┘ └────────────┘ └────────────┘
Protocol: JSON-RPC 2.0 over chosen transport
Flow: Client → request → Server → response → Client
服务类型决策树
What transport does your MCP server need?
│
├─ Local CLI tool / single-user desktop integration?
│ └─ stdio
│ - Simplest setup, no networking
│ - Claude Desktop, Claude Code native support
│ - Process lifecycle managed by host
│
├─ Web dashboard / browser-based client?
│ └─ SSE (Server-Sent Events)
│ - HTTP-based, works through firewalls
│ - Persistent connection for server→client events
│ - Good for development and internal tools
│
└─ Production API / multi-tenant / cloud deployment?
└─ Streamable HTTP
- HTTP POST for requests, SSE for streaming responses
- Supports stateless and stateful modes
- Full auth support, load balancer friendly
- Recommended for production deployments
工具、资源与提示词决策树
What does the LLM need to do?
│
├─ Perform an action or computation?
│ └─ TOOL
│ - Has side effects (API calls, file writes, DB mutations)
│ - Accepts structured input, returns results
│ - Examples: run_query, create_issue, send_email
│
├─ Read data or context?
│ └─ RESOURCE
│ - Read-only data retrieval
│ - Identified by URI (file://, db://, api://)
│ - Examples: config://app, schema://users, file://readme.md
│
└─ Guide the LLM's behavior or workflow?
└─ PROMPT
- Templated instructions with arguments
- Suggests conversation starters or workflows
- Examples: code_review(language, file), summarize(topic)
Python SDK 快速入门
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-server")
@mcp.tool()
def search_docs(query: str) -> str:
"""Search documentation by keyword."""
results = perform_search(query)
return "\n".join(f"- {r.title}: {r.snippet}" for r in results)
@mcp.tool()
def create_ticket(title: str, body: str, priority: str = "medium") -> str:
"""Create a support ticket."""
ticket = api.create(title=title, body=body, priority=priority)
return f"Created ticket #{ticket.id}: {ticket.url}"
@mcp.resource("config://app")
def get_config() -> str:
"""Return current application configuration."""
return json.dumps(load_config(), indent=2)
@mcp.resource("schema://db/{table}")
def get_table_schema(table: str) -> str:
"""Return the schema for a database table."""
return json.dumps(get_schema(table), indent=2)
@mcp.prompt()
def code_review(language: str, filepath: str) -> str:
"""Generate a code review prompt for the given file."""
return f"Review this {language} code in {filepath} for bugs, style issues, and performance."
if __name__ == "__main__":
mcp.run() # Defaults to stdio transport
安装并运行:
uv init my-mcp-server && cd my-mcp-server
uv add mcp[cli]
# Run with: uv run python server.py
# Or: uv run mcp run server.py
有两个 Python FastMCP,请确认你使用的是哪一个。 官方 mcp SDK 捆绑了冻结在 1.x 时代的 FastMCP(from mcp.server.fastmcp import FastMCP,上文示例中使用的版本——稳定、精简)。独立的 fastmcp 包(gofastmcp.com)是活跃开发所在,目前主版本为 3:装饰器接口相同,另外还提供身份验证、代理、OpenAPI 生成和测试客户端。使用方法如下:
uv add fastmcp
from fastmcp import FastMCP # standalone FastMCP 3 — not mcp.server.fastmcp
mcp = FastMCP("my-server") # v3: constructor is identity/behaviour only;
# transport config moved to run()/serve time
FastMCP 3 的重大变更(相较于 2.x):移除了 16 个已弃用的构造函数关键字参数(传输设置现在在服务时传入),ui= 替换为 app=,ctx.set_state()/ctx.get_state() 现在是异步的,持久化范围为会话级别,元数据命名空间从 _fastmcp 更改为 fastmcp。
TypeScript SDK 快速入门
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "my-server",
version: "1.0.0",
});
// Register a tool
server.tool(
"search_docs",
"Search documentation by keyword",
{ query: z.string().describe("Search query") },
async ({ query }) => {
const results = await performSearch(query);
return {
content: [{ type: "text", text: results.join("\n") }],
};
}
);
// Register a resource
server.resource(
"config",
"config://app",
{ description: "Current application configuration" },
async (uri) => ({
contents: [{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(loadConfig(), null, 2),
}],
})
);
// Register a prompt
server.prompt(
"code_review",
"Generate a code review prompt",
{ language: z.string(), filepath: z.string() },
async ({ language, filepath }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Review this ${language} code in ${filepath} for bugs and style issues.`,
},
}],
})
);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
安装并运行:
npm init -y
npm install @modelcontextprotocol/sdk zod
npx tsx server.ts
传输方式选择矩阵
| 特性 | stdio | SSE | Streamable HTTP |
|---|---|---|---|
| 用例 | 本地 CLI 工具、桌面应用 | Web 仪表板、开发 | 生产 API |
| 协议 | stdin/stdout 管道 | HTTP + EventSource | HTTP POST + SSE |
| 身份验证支持 | 仅环境变量 | Bearer 令牌 | 完整 OAuth2/PKCE |
| 部署 | 本地进程 | 单个服务 | 负载均衡 |
| 重新连接 | 重启进程 | 自动重新连接 | 无状态、具备弹性 |
| 多客户端 | 仅 1:1 | 多个客户端 | 可水平扩展 |
| 防火墙 | 不适用(本地) | 适用于 HTTP | 适用于 HTTP |
| 状态 | 进程生命周期 | 连接生命周期 | 会话级或无状态 |
| 最适用于 | Claude Desktop/Code | 内部工具 | 云端/企业 |
身份验证模式快速参考
# Pattern 1: API keys from environment
import os
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("api-server")
@mcp.tool()
def call_api(endpoint: str) -> str:
"""Call external API with configured credentials."""
api_key = os.environ["MY_API_KEY"] # Set in client config
resp = httpx.get(f"https://api.example.com/{endpoint}",
headers={"Authorization": f"Bearer {api_key}"})
return resp.text
# Pattern 2: OAuth2 token refresh (in-memory cache)
import time
_token_cache: dict = {}
async def get_valid_token() -> str:
if _token_cache.get("expires_at", 0) > time.time() + 60:
return _token_cache["access_token"]
resp = await httpx.AsyncClient().post("https://auth.example.com/token", data={
"grant_type": "refresh_token",
"refresh_token": os.environ["REFRESH_TOKEN"],
"client_id": os.environ["CLIENT_ID"],
})
data = resp.json()
_token_cache.update({
"access_token": data["access_token"],
"expires_at": time.time() + data["expires_in"],
})
return data["access_token"]
// Claude Desktop config with env vars
{
"mcpServers": {
"my-server": {
"command": "uv",
"args": ["run", "--directory", "/path/to/server", "python", "server.py"],
"env": {
"MY_API_KEY": "sk-...",
"DATABASE_URL": "postgresql://..."
}
}
}
}
常见问题
| 问题 | 原因 | 修复方法 |
|---|---|---|
| 工具未显示在客户端中 | inputSchema 包含无效的 JSON Schema | 使用 jsonschema 库验证架构;使用 Pydantic/Zod 生成 |
| 工具返回原始对象 | 结果必须是包含带类型条目的 content 列表 | 始终返回 {"content": [{"type": "text", "text": "..."}]} |
| 长时间操作超时 | 客户端默认超时通常为 30-60s | 添加进度通知;拆分为较小的操作 |
| 并发请求失败 | 工具处理程序使用了共享的可变状态 | 使用 asyncio 锁,或让处理程序保持无状态 |
| 大型响应导致客户端崩溃 | MCP 消息存在实际大小限制 | 对结果分页;返回摘要,并提供用于获取详情的工具 |
| 错误被静默吞掉 | 处理程序中的异常会返回通用错误 | 在响应中设置 isError: true;在内容中包含错误消息 |
| SSE 连接断开 | 缺少保活或重新连接逻辑 | 实现心跳;客户端会在 SSE 连接断开后自动重新连接 |
| 客户端忽略新工具 | 工具变更后未更新能力 | 调用 server.request_context.session.send_resource_list_changed() |
| 工具名称冲突 | 两个服务注册了同名工具 | 为工具添加命名空间:使用 myserver_search,而不只是 search |
| 资源 URI 过于笼统 | data://info 含义不明确 | 使用具体的方案:db://myapp/users、config://myapp/settings |
处理程序缺少 async def | FastMCP 工具可以是同步或异步的,但 I/O 操作应使用异步方式 | 任何执行网络/文件 I/O 的处理程序都使用 async def |
| 服务在本地正常运行,但在 Claude Desktop 中失败 | 工作目录或 PATH 不同 | 使用绝对路径;在启动时记录 os.getcwd() |
参考文件
| 文件 | 行数 | 内容 |
|---|---|---|
references/server-architecture.md | ~700 | 服务生命周期、FastMCP/TS SDK 设置、功能、中间件、错误处理 |
references/tool-handlers.md | ~650 | 架构设计、验证、返回类型、组合、副作用、示例 |
references/resources-prompts.md | ~550 | 资源 URI、静态/动态资源、模板、提示词、订阅 |
references/transport-auth.md | ~550 | stdio/SSE/HTTP 传输、会话管理、OAuth2、速率限制、TLS |
references/testing-debugging.md | ~550 | MCP Inspector、单元/集成测试、协议调试、CI、性能 |
过时情况验证器
此技能包含变化迅速的信息(MCP SDK 包名称 + 规范 URL)。scripts/check-mcp-facts.py 可防止这些信息悄然过时:
# Structural (PR CI, no network): every catalogued package's prose_token is
# still named in this skill's prose, the spec URL is still cited, and the
# currency note still carries a year.
python scripts/check-mcp-facts.py --offline # exit 0 consistent, 10 drift
# Live (freshness job, never blocks a PR): each SDK still resolves on
# npm/PyPI, no tracked major has moved off the sampled major, spec URL 200.
python scripts/check-mcp-facts.py --live # exit 10 drift, 7 registries unreachable
权威事实集位于 assets/mcp-facts.json;添加或移除软件包时,请同步更新该文件,否则 --offline 会导致 CI 失败。
另请参阅
- MCP 规范:https://modelcontextprotocol.io/specification/latest(旧的 spec.modelcontextprotocol.io 子域名已无法访问)
- Python SDK:https://github.com/modelcontextprotocol/python-sdk
- TypeScript SDK:https://github.com/modelcontextprotocol/typescript-sdk
- 官方 MCP 服务:https://github.com/modelcontextprotocol/servers
- MCP Inspector:
npx @modelcontextprotocol/inspector - FastMCP 文档:https://gofastmcp.com
- 相关技能:
claude-code-hooks(接入 Claude Code)、claude-code-debug(调试 Claude Code 问题)