跳转至

MCP 协议与工具调用 · 运维手册

适用场景:开发 MCP Server 为 AI 应用提供工具能力,或集成 MCP Client 调用外部工具服务。


1. MCP 协议概述

1.1 什么是 MCP

MCP(Model Context Protocol)是 Anthropic 提出的开放协议,让 AI 模型能够安全、标准化地调用外部工具。

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  AI Host    │     │  MCP Client │     │  MCP Server │
│  (Claude等) │ ◄──►│  (集成层)    │ ◄──►│  (工具服务)  │
└─────────────┘     └─────────────┘     └─────────────┘

1.2 核心概念

概念 作用 示例
Tool 可调用的函数 check_service, query_metrics
Resource 可读取的数据源 文件、数据库、API 响应
Prompt 可复用的提示词模板 故障诊断流程、代码审查模板
Server 工具提供者 自定义 MCP Server
Client 工具消费者 Claude Desktop、Cursor

2. 协议架构

2.1 通信机制

Client ←── JSON-RPC 2.0 ──→ Server
         (stdio / HTTP / SSE)

传输方式: - stdio:标准输入输出(本地进程) - HTTP:RESTful API(远程服务) - SSE:Server-Sent Events(流式响应)

2.2 消息类型

// 初始化
{"jsonrpc": "2.0", "id": 1, "method": "initialize",
 "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}

// 工具列表
{"jsonrpc": "2.0", "method": "tools/list"}

// 工具调用
{"jsonrpc": "2.0", "method": "tools/call",
 "params": {"name": "check_service", "arguments": {"service": "nginx"}}}

// 工具返回
{"jsonrpc": "2.0", "result": {"content": [{"type": "text", "text": "nginx is running"}]}}

3. Python MCP Server 开发

3.1 环境搭建

pip install mcp[cli]

3.2 基础 Server

# server.py
from mcp.server import Server
from mcp.types import Tool, TextContent

app = Server("ops-agent")

@app.tool()
async def check_service(service_name: str) -> list[TextContent]:
    """检查服务状态"""
    import subprocess
    result = subprocess.run(
        ["systemctl", "status", service_name],
        capture_output=True, text=True
    )
    return [TextContent(type="text", text=result.stdout[:2000])]

@app.tool()
async def query_metrics(metric: str) -> list[TextContent]:
    """查询 Prometheus 指标"""
    import requests
    resp = requests.get(
        f"http://prometheus:9090/api/v1/query?query={metric}"
    )
    return [TextContent(type="text", text=resp.text[:2000])]

if __name__ == "__main__":
    app.run()

3.3 启动配置

// claude_desktop_config.json
{
  "mcpServers": {
    "ops-agent": {
      "command": "python",
      "args": ["server.py"],
      "env": {
        "PROMETHEUS_URL": "http://prometheus:9090"
      }
    }
  }
}

4. 高级功能

4.1 资源订阅

@app.resource()
async def get_system_info() -> TextContent:
    """系统信息"""
    import psutil
    info = {
        "cpu": psutil.cpu_percent(),
        "memory": psutil.virtual_memory().percent,
        "disk": psutil.disk_usage('/').percent
    }
    return TextContent(type="text", text=json.dumps(info))

4.2 流式响应

@app.tool()
async def streaming_query(query: str) -> AsyncGenerator[TextContent, None]:
    """流式查询"""
    async for chunk in llm.stream(query):
        yield TextContent(type="text", text=chunk)

4.3 错误处理

@app.tool()
async def safe_tool_call(name: str, args: dict) -> list[TextContent]:
    """安全的工具调用"""
    try:
        result = await execute_tool(name, args)
        return [TextContent(type="text", text=result)]
    except Exception as e:
        return [TextContent(
            type="text",
            text=f"Error: {str(e)}",
            isError=True
        )]

5. 安全最佳实践

5.1 工具白名单

ALLOWED_TOOLS = {
    "check_service",
    "query_metrics",
    "read_log",
    "disk_usage"
}

@app.tool()
async def dispatch_tool(name: str, args: dict):
    if name not in ALLOWED_TOOLS:
        raise ValueError(f"Tool {name} not allowed")
    # ... 执行逻辑

5.2 输入验证

import re

SAFE_PATTERN = re.compile(r'^[a-zA-Z0-9_\-\.]+$')

def validate_service_name(name: str) -> bool:
    return bool(SAFE_PATTERN.match(name))

5.3 超时控制

import asyncio

@app.tool()
async def timed_tool(name: str, args: dict):
    try:
        result = await asyncio.wait_for(
            execute_tool(name, args),
            timeout=30.0
        )
        return result
    except asyncio.TimeoutError:
        return [TextContent(type="text", text="Request timed out", isError=True)]

6. 调试与测试

6.1 启用调试日志

import logging
logging.basicConfig(level=logging.DEBUG)

6.2 本地测试

# 启动 server
python server.py

# 用 MCP Inspector 测试
npx @modelcontextprotocol/inspector

6.3 集成测试

import pytest
from mcp.client.stdio import stdio_client

@pytest.mark.asyncio
async def test_check_service():
    async with stdio_client(["python", "server.py"]) as (read, write):
        # 发送工具列表请求
        await write('{"jsonrpc":"2.0","id":1,"method":"tools/list"}')
        # 读取响应
        response = await read()
        assert "check_service" in response

7. 常见问题排查

问题 1:工具调用超时

排查: - 检查服务端日志 - 验证网络连通性 - 调整超时参数


问题 2:JSON-RPC 格式错误

排查: - 检查消息格式是否符合 2.0 规范 - 验证 id 字段唯一性 - 检查 content type 头


问题 3:工具返回空结果

排查: - 检查工具参数验证 - 验证数据源可达性 - 查看错误日志


8. 延伸阅读


FAQ

MCP 和 OpenAPI 有什么区别? OpenAPI 描述 REST API 结构,MCP 描述 AI 工具调用语义。MCP 支持流式响应、工具发现、资源订阅,专为 AI 设计。

如何开发 MCP Server? ① 定义 Tools/Resources/Prompts ② 实现 JSON-RPC 2.0 接口 ③ 注册到 Host。用 Python SDK(mcp python)或 TypeScript SDK。

MCP 安全性如何保障? ① 工具权限最小化 ② 输入验证沙箱 ③ 调用审计日志 ④ 资源访问控制。高危操作必须人工确认。

如何调试 MCP 连接问题? 检查stdio/stdout通信、验证JSON-RPC格式、启用debug日志、测试工具发现与调用流程。