mcpField
M
mcp-ops

mcp-ops

github.com/0xdarkmatter开发7843 次安装2 周前更新
代码仓库

关于 mcp-ops

mcp-ops 是面向 Python 和 TypeScript 开发者的 MCP 服务构建、测试与部署指南,涵盖架构、传输、认证及常见问题。它还提供参考文档与事实检查脚本,帮助维护随生态变化的实现知识。

主要功能

  1. 01Python 与 TypeScript 服务端指南
  2. 02传输方式与认证模式参考
  3. 03工具、资源和提示词设计指引
  4. 04测试、调试与常见问题说明
  5. 05MCP 事实漂移检查脚本

适用场景

  1. 01选择本地或远程服务传输方式
  2. 02设计 MCP 工具和资源
  3. 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/
.gitkeep
mcp-facts.json
references/
resources-prompts.md
server-architecture.md
testing-debugging.md
tool-handlers.md
transport-auth.md
scripts/
.gitkeep
check-mcp-facts.py
tests/
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

传输方式选择矩阵

特性stdioSSEStreamable HTTP
用例本地 CLI 工具、桌面应用Web 仪表板、开发生产 API
协议stdin/stdout 管道HTTP + EventSourceHTTP 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 defFastMCP 工具可以是同步或异步的,但 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~550stdio/SSE/HTTP 传输、会话管理、OAuth2、速率限制、TLS
references/testing-debugging.md~550MCP 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 失败。

另请参阅

评论

支持 Markdown