MCP协议 进阶 MCP 模型上下文协议 AI工具 协议规范

什么是MCP协议?模型上下文协议完全指南

AIEng Hub
阅读约 25 分钟

引言

随着AI应用的快速发展,如何让大语言模型(LLM)安全、标准化地访问外部工具和数据源,成为了一个关键问题。

MCP(Model Context Protocol,模型上下文协议) 是Anthropic推出的开放协议,旨在为AI模型与外部系统之间建立标准化的通信接口。

什么是MCP?

核心定义

MCP是一个开放协议,它标准化了AI模型如何连接外部数据源和工具的方式。通过MCP,开发者可以:

  • 为AI模型提供结构化工具
  • 让模型安全地访问外部资源
  • 实现跨平台的工具复用

类比理解

类比说明
USB接口就像USB统一了外设连接标准
HTTP协议就像HTTP统一了Web通信标准
SQL就像SQL统一了数据库查询标准

MCP正在成为AI工具连接的标准协议。

MCP vs Function Calling

对比分析

特性Function CallingMCP
厂商绑定特定厂商(如OpenAI)开放标准
工具复用难以跨平台复用一次开发,到处使用
安全性应用层自行实现协议层标准化
能力协商有限完整的协商机制
生态各自为政统一生态

Function Calling 示例

# OpenAI Function Calling
functions = [
    {
        "name": "get_weather",
        "description": "获取天气信息",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {"type": "string"},
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["location"]
        }
    }
]

response = openai.chat.completions.create(
    model="gpt-4",
    messages=messages,
    functions=functions,
    function_call="auto"
)

MCP 示例

{
  "tools": [
    {
      "name": "get_weather",
      "description": "获取天气信息",
      "inputSchema": {
        "type": "object",
        "properties": {
          "location": {"type": "string"},
          "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
        },
        "required": ["location"]
      }
    }
  ]
}

MCP的优势在于标准化可移植性

MCP架构概览

核心组件

┌─────────────────────────────────────────────────────────┐
│                    MCP 架构                              │
├─────────────────────────────────────────────────────────┤
│                                                          │
│   ┌──────────────┐         ┌──────────────┐            │
│   │  MCP Client  │◄───────►│  MCP Server  │            │
│   │   (客户端)    │  JSON-RPC │  (服务端)    │            │
│   └──────┬───────┘         └──────┬───────┘            │
│          │                        │                     │
│          │                        │                     │
│          ▼                        ▼                     │
│   ┌──────────────┐         ┌──────────────┐            │
│   │    LLM       │         │   外部资源    │            │
│   │  (大模型)    │         │  (工具/数据)  │            │
│   └──────────────┘         └──────────────┘            │
│                                                          │
└─────────────────────────────────────────────────────────┘

通信流程

1. 连接建立
   Client ──► Server: initialize
   Server ──► Client: initialize response

2. 能力协商
   Client ──► Server: tools/list
   Server ──► Client: 可用工具列表

3. 工具调用
   Client ──► Server: tools/call
   Server ──► Client: 执行结果

4. 资源访问
   Client ──► Server: resources/read
   Server ──► Client: 资源内容

MCP协议规范

1. 消息格式

MCP使用JSON-RPC 2.0作为通信协议:

// 请求消息
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "北京",
      "unit": "celsius"
    }
  }
}

// 响应消息
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "北京今天晴,25°C"
      }
    ],
    "isError": false
  }
}

2. 工具定义

{
  "tools": [
    {
      "name": "search_documents",
      "description": "搜索文档内容",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "搜索关键词"
          },
          "limit": {
            "type": "number",
            "description": "返回结果数量",
            "default": 10
          }
        },
        "required": ["query"]
      }
    }
  ]
}

3. 资源定义

{
  "resources": [
    {
      "uri": "file:///docs/api-reference.md",
      "name": "API参考文档",
      "mimeType": "text/markdown",
      "description": "完整的API接口文档"
    }
  ]
}

实战:搭建MCP Server

1. 环境准备

# 创建项目
mkdir my-mcp-server
cd my-mcp-server
npm init -y

# 安装依赖
npm install @modelcontextprotocol/sdk zod

# TypeScript支持
npm install -D typescript @types/node
npx tsc --init

2. 基础Server实现

// server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

// 定义工具参数
const CalculatorArgs = z.object({
  expression: z.string().describe("数学表达式"),
});

// 创建Server
const server = new Server(
  {
    name: "calculator-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// 处理工具列表请求
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "calculate",
        description: "计算数学表达式",
        inputSchema: {
          type: "object",
          properties: {
            expression: {
              type: "string",
              description: "数学表达式,如 '2 + 2'",
            },
          },
          required: ["expression"],
        },
      },
    ],
  };
});

// 处理工具调用请求
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "calculate") {
    const args = CalculatorArgs.parse(request.params.arguments);
    
    try {
      // 安全计算
      const result = eval(args.expression);
      return {
        content: [
          {
            type: "text",
            text: `结果: ${result}`,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: `计算错误: ${error}`,
          },
        ],
        isError: true,
      };
    }
  }
  
  throw new Error(`未知工具: ${request.params.name}`);
});

// 启动Server
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Calculator MCP Server running on stdio");
}

main().catch(console.error);

3. 配置文件

// mcp-config.json
{
  "mcpServers": {
    "calculator": {
      "command": "node",
      "args": ["dist/server.js"],
      "env": {
        "NODE_ENV": "production"
      }
    }
  }
}

MCP Client集成

Python Client示例

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

# 配置Server参数
server_params = StdioServerParameters(
    command="python",
    args=["server.py"],
    env=None
)

async def use_mcp_server():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            # 初始化
            await session.initialize()
            
            # 获取工具列表
            tools = await session.list_tools()
            print(f"可用工具: {[tool.name for tool in tools.tools]}")
            
            # 调用工具
            result = await session.call_tool(
                "calculate",
                arguments={"expression": "2 + 2"}
            )
            print(f"结果: {result}")

与LangChain集成

from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent

# 加载MCP工具
async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        
        # 转换为LangChain工具
        tools = await load_mcp_tools(session)
        
        # 创建Agent
        agent = create_react_agent(model, tools)
        
        # 使用Agent
        response = await agent.ainvoke(
            {"messages": "计算 15 * 23"}
        )

MCP工具生态

官方工具

工具功能链接
Filesystem文件系统操作github.com/modelcontextprotocol/servers
GitHubGitHub API集成github.com/modelcontextprotocol/servers
PostgreSQL数据库查询github.com/modelcontextprotocol/servers
Puppeteer浏览器自动化github.com/modelcontextprotocol/servers

社区工具

工具功能作者
Brave Search搜索功能community
SlackSlack集成community
NotionNotion集成community

MCP最佳实践

1. 工具设计原则

// 好的工具设计
{
  name: "search_code",
  description: "在代码库中搜索特定模式。" +
    "支持正则表达式和简单文本匹配。" +
    "返回匹配的文件路径和行号。",
  inputSchema: {
    type: "object",
    properties: {
      pattern: {
        type: "string",
        description: "搜索模式,可以是正则或普通字符串"
      },
      fileType: {
        type: "string",
        description: "文件类型过滤,如 '.ts', '.py'",
        optional: true
      }
    },
    required: ["pattern"]
  }
}

2. 错误处理

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    const result = await executeTool(request.params);
    return {
      content: [{ type: "text", text: result }],
      isError: false,
    };
  } catch (error) {
    return {
      content: [
        {
          type: "text",
          text: `错误: ${error.message}`,
        },
      ],
      isError: true,
    };
  }
});

3. 安全性考虑

// 输入验证
const safeEval = (expression: string): number => {
  // 只允许数字和基本运算符
  if (!/^[\d+\-*/.()\s]+$/.test(expression)) {
    throw new Error("非法字符");
  }
  return eval(expression);
};

// 权限控制
const checkPermission = (resource: string): boolean => {
  const allowedPaths = ["/home/user/docs", "/tmp"];
  return allowedPaths.some(path => resource.startsWith(path));
};

MCP的未来

发展趋势

  1. 标准化 - 成为AI工具连接的事实标准
  2. 生态繁荣 - 丰富的工具市场
  3. 多模态支持 - 支持图像、音频等资源
  4. 企业级特性 - 审计、监控、权限管理

与Agent的关系

MCP是Agent的基础设施:

Agent (决策层)


MCP (协议层)


Tools (执行层)

总结

MCP协议为AI工具连接提供了标准化解决方案

开放标准 - 不绑定特定厂商
工具复用 - 一次开发,到处使用
安全可靠 - 协议层安全机制
生态丰富 - growing tool ecosystem

下一步学习建议:


本文最后更新于 2024-01-25,如有问题欢迎在社区讨论。