为什么需要MCP?

你有没有遇到过这样的场景:想让AI助手帮你查数据库,结果要自己写一堆胶水代码;想让ChatGPT调用内部API,却发现每个模型的接口都不一样;辛辛苦苦开发了工具,换个平台就完全不能用了。

这就是2024年之前AI工具集成的真实写照——碎片化。

每个AI应用都要为每个数据源开发自己的集成方案,每个模型的Function Calling格式都不一样。你今天为GPT-4写的工具,明天换Claude就得重写一遍。这种重复劳动不仅浪费时间,还让AI工具的生态无法形成规模效应。

MCP(Model Context Protocol)就是为了解决这个问题而生的。

想象一下:如果你的USB设备可以即插即用,不管接到哪个电脑都能用,那该多方便。MCP就是AI应用的"USB-C接口"——提供一个标准化的协议,让AI模型可以无缝连接各种外部工具和数据源。

2024年11月25日,Anthropic正式发布了MCP协议并将其开源。短短一年多时间,它已经成为了AI Agent开发的核心协议之一。2025年12月,Anthropic更是将MCP捐赠给了Linux基金会下的Agentic AI Foundation,标志着它从一个公司项目变成了行业标准。

掌握MCP,你就能:

  • 一次构建MCP Server,所有兼容客户端都能用
  • 轻松连接数据库、API、文件系统等外部资源
  • 构建可复用的AI工具生态系统
  • 在面试中展示对AI Agent架构的深入理解

接下来,我们将从零开始,手把手教你构建自己的MCP Server。无论你是想开发AI工具,还是想深入了解AI Agent架构,这篇文章都将为你提供实用的指导。


MCP核心概念与原理

MCP到底是什么?

简单来说,MCP是一个开源标准,用于连接AI应用与外部系统。它定义了一套统一的协议,让AI模型可以以标准化的方式访问工具、数据和提示词。

MCP的核心价值:

  • 统一协议:替代碎片化的集成方案
  • 一次构建,处处使用:构建一个MCP Server,所有兼容客户端都能调用
  • 关注点分离:将提供上下文与LLM交互本身分离
  • 标准化通信:使用JSON-RPC 2.0作为通信协议

MCP与Function Calling的详细对比

这是面试和实际开发中最常见的问题。理解它们的区别和联系,是掌握MCP的关键。

维度Function CallingMCP
定位模型级原语应用级协议
控制方LLM提供商(OpenAI、Anthropic等)独立的开源标准
工具定义嵌入在API请求中外化为可共享的服务
可移植性绑定特定模型跨模型、跨平台
工具发现静态定义,编译时确定动态发现,运行时查询
状态管理无状态支持有状态会话
安全模型基本的沙箱隔离完整的认证、授权、审计
适用场景简单的工具调用复杂的工具生态系统

关键区别详解:

  1. 协议层次不同
  • Function Calling:模型内部机制,如何请求工具的原语
  • MCP:应用层协议,标准化工具的发现、传输、会话管理
  1. 可移植性差异
  • Function Calling:为GPT-4写的工具,换Claude就得重写
  • MCP:一个MCP Server,所有支持MCP的客户端都能用
  1. 工具生命周期
  • Function Calling:工具定义随请求发送,无法动态更新
  • MCP:支持工具的动态注册、更新、移除
  1. 生态系统
  • Function Calling:各厂商各自为战,生态碎片化
  • MCP:统一标准,形成可复用的工具生态

何时选择MCP:

  • 需要跨平台使用工具
  • 需要动态发现和更新工具
  • 需要构建可复用的工具生态
  • 需要更完善的安全和会话管理

何时使用Function Calling:

  • 仅在单个模型平台使用
  • 工具简单且固定
  • 不需要跨平台兼容

MCP在AI Agent生态中的位置

AI Agent的架构可以分为四层:

MCP的定位:

  • Function Calling:模型级原语,处理模型如何请求工具
  • MCP:应用协议,标准化工具发现、传输、会话管理
  • Agent Skills:指导智能体如何执行任务的指令
  • A2A(Agent-to-Agent):智能体间通信协议

MCP是连接AI客户端与工具和数据的垂直连接层。它在Function Calling之上添加了标准化层,让工具可以跨平台共享。

MCP的设计理念

MCP的设计遵循四个核心理念:

  1. 开放标准:开源、社区驱动、厂商中立
  2. 模块化:将工具、资源、提示词作为独立原语
  3. 可组合:支持构建可组合的集成和工作流
  4. 安全性:内置安全考虑,包括用户同意和控制

🎯 本章小结: MCP是一个标准化的AI工具集成协议,它解决了碎片化问题,让你的AI工具可以"一次构建,处处使用"。理解MCP的定位和设计理念,是掌握后续内容的基础。


Server/Client架构详解

三层模型

MCP采用Host → Client → Server的三层架构:

组件职责:

  • Host:发起连接的LLM应用(如Claude Desktop、VS Code、Cursor)
  • Client:宿主应用内的连接器,管理与服务器的通信
  • Server:提供上下文和能力的服务

详细交互流程:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐│    Host     │     │   Client    │     │    Server   ││  (Claude)   │────▶│  (协议层)   │────▶│  (工具服务)  │└─────────────┘     └─────────────┘     └─────────────┘       │                   │                   │       │  1. 用户请求      │                   │       │──────────────────▶│                   │       │                   │  2. 能力查询      │       │                   │──────────────────▶│       │                   │  3. 返回工具列表   │       │                   │◀──────────────────│       │  4. LLM决策调用   │                   │       │◀──────────────────│                   │       │  5. 执行工具      │                   │       │──────────────────▶│──────────────────▶│       │                   │  6. 返回结果      │       │                   │◀──────────────────│       │  7. 响应用户      │                   │       │◀──────────────────│                   │

通信机制

MCP使用JSON-RPC 2.0作为通信协议,包含三种消息类型:

  1. Requests:客户端到服务器的请求,包含id、method、params
  2. Responses:对请求的响应,包含result或error
  3. Notifications:单向通知,不期望响应

消息格式示例:

// Request{  "jsonrpc": "2.0",  "id": 1,  "method": "tools/list",  "params": {}}// Response{  "jsonrpc": "2.0",  "id": 1,  "result": {    "tools": [      {        "name": "add",        "description": "Add two numbers",        "inputSchema": {          "type": "object",          "properties": {            "a": {"type": "integer"},            "b": {"type": "integer"}          }        }      }    ]  }}

完整的通信流程:

传输方式

MCP支持两种传输方式:

特性stdioStreamable HTTP
部署方式本地子进程远程服务
并发支持单客户端多客户端
安全性进程隔离需要认证授权
扩展性有限高
适用场景开发测试生产部署
网络要求无需要网络连接
延迟低取决于网络

stdio传输详解:

  • 客户端将MCP服务器作为子进程启动

  • 服务器从stdin读取JSON-RPC消息

  • 向stdout写入响应

  • 适合本地开发和单用户桌面设置

Streamable HTTP传输详解:

  • 服务器作为独立进程运行

  • 处理多个客户端连接

  • 使用HTTP POST和GET请求

  • 可选SSE流式传输

  • 适合远程部署和生产环境

选择建议:

  • 开发测试阶段:使用stdio,简单快捷
  • 生产环境:使用Streamable HTTP,支持并发和扩展
  • 本地部署:stdio为主,必要时可切换到HTTP
  • 远程部署:必须使用Streamable HTTP

🎯 本章小结: MCP采用三层架构,使用JSON-RPC 2.0通信,支持stdio和HTTP两种传输方式。理解这些架构细节,能帮助你设计出更健壮的MCP Server。


三种原语详解

MCP定义了三种原语(Primitives),它们是Server向Client提供的核心能力。

Tools(工具)

定义:工具是AI应用可以调用以执行操作的可执行函数。

控制层级:模型控制(Model-controlled)

  • AI模型决定何时调用工具
  • 工具执行外部操作(如API调用、数据库查询)

代码示例:

@mcp.tool()def add(a: int, b: int) -> int:    """Add two numbers."""    return a + b

特点:

  • 可以执行任意代码
  • 可以修改外部状态
  • 需要适当的权限控制
  • 应被视为不受信任,除非来自受信任的服务器

安全考虑:

  • 工具应该有清晰的输入验证
  • 敏感操作需要额外的确认机制
  • 执行结果应该经过过滤,避免信息泄露
  • 考虑添加速率限制,防止滥用

Resources(资源)

定义:资源是提供额外上下文给AI应用的数据源。

控制层级:应用控制(Application-controlled)

  • 客户端应用决定如何和何时使用资源
  • 资源通常是只读的

代码示例:

@mcp.resource("greeting://{name}")def greeting(name: str) -> str:    """Greet someone by name."""    return f"Hello, {name}!"

资源类型:

  • 文件内容
  • 数据库记录
  • API响应
  • 实时系统数据
  • 截图和图像
  • 日志文件

URI格式:[protocol]://[host]/[path]

  • file:///home/user/documents/report.pdf
  • postgres://database/customers/schema
  • screen://localhost/display1

**资源订阅机制:**资源可以支持订阅,当资源内容变化时主动通知客户端。

@mcp.resource("logs://app", subscribe=True)def get_logs() -> str:    """Get application logs."""    return "\n".join(log_entries)

Prompts(提示词)

定义:提示词是预定义的模板或指令,用于引导语言模型交互。

控制层级:用户控制(User-controlled)

  • 用户通过UI元素(如斜杠命令、菜单选项)显式选择
  • 提供结构化的消息和工作流

代码示例:

@mcp.prompt()def summarize(text: str) -> str:    """Summarize a piece of text in one sentence."""    return f"Summarize the following text in one sentence:\n\n{text}"

特点:

  • 可以接受动态参数
  • 可以包含资源上下文
  • 可以链接多个交互
  • 指导特定任务

三种原语的区别

原语控制方用途示例适用场景安全级别
Tools模型执行操作API调用、数据库写入需要执行外部操作高风险
Resources应用提供数据文件内容、API响应提供上下文信息低风险
Prompts用户指导交互系统提示、少样本示例引导模型行为中等风险

选择指南:

  • 需要执行操作?用Tools
  • 需要提供数据?用Resources
  • 需要指导行为?用Prompts
  • 三者可以同时存在一个服务器中

最佳实践:

  1. 最小权限原则:工具只授予必要的权限
  2. 输入验证:所有输入都应该验证和清理
  3. 输出过滤:敏感信息不应该暴露给模型
  4. 日志记录:所有操作都应该有审计日志
  5. 错误处理:优雅地处理错误,避免泄露系统信息

🎯 本章小结: MCP的三种原语各有分工——Tools执行操作,Resources提供数据,Prompts指导交互。掌握它们的区别和适用场景,能让你设计出更合理的MCP Server。


MCP Server构建详解

环境准备

首先,确保你已经安装了Python 3.10+和uv(推荐的包管理工具)。

# 安装uv(如果还没有)curl -LsSf https://astral.sh/uv/install.sh | sh# 创建项目目录mkdir mcp-server-projectcd mcp-server-project# 初始化项目uv init# 添加MCP依赖uv add "mcp[cli]"

基本结构

一个最小的MCP Server只需要几行代码:

# simple_server.pyfrom mcp.server import MCPServermcp = MCPServer("Demo")@mcp.tool()def add(a: int, b: int) -> int:    """Add two numbers."""    return a + bif __name__ == "__main__":    import asyncio    from mcp.server.stdio import stdio_server        async def main():        async with stdio_server() as streams:            await mcp.run(                streams[0],                streams[1],                mcp.create_initialization_options()            )        asyncio.run(main())

Server生命周期管理

MCP Server的生命周期包括以下几个阶段:

生命周期钩子:

from mcp.server import MCPServerfrom contextlib import asynccontextmanager@asynccontextmanagerasync def lifespan(server: MCPServer):    """管理服务器生命周期"""    # 启动时执行    print("服务器启动中...")    await initialize_resources()        yield  # 服务器运行        # 关闭时执行    print("服务器关闭中...")    await cleanup_resources()mcp = MCPServer("Demo", lifespan=lifespan)

最佳实践:

  1. 优雅关闭:确保在关闭时释放所有资源
  2. 错误恢复:实现重试机制和降级策略
  3. 健康检查:定期检查服务器状态
  4. 资源监控:监控内存、CPU使用情况

运行服务器

MCP提供了三种运行模式:

# 开发模式(带Inspector,推荐)uv run mcp dev server.py# 生产模式(stdio)uv run mcp run server.py# 生产模式(HTTP)uv run mcp run server.py --transport streamable-http

开发模式会启动一个Web界面,让你可以交互式地测试工具、资源和提示词。这是开发阶段最常用的方式。

工具定义与注册

MCP Python SDK支持两种定义工具的方式:

方式一:装饰器(推荐)

@mcp.tool()def calculate(expression: str) -> str:    """Evaluate a mathematical expression.        Args:        expression: Mathematical expression to evaluate    """    try:        result = eval(expression)        return str(result)    except Exception as e:        return f"Error: {str(e)}"

方式二:手动注册

from mcp.types import Toolserver.add_tool(    Tool(        name="calculate",        description="Evaluate a mathematical expression",        inputSchema={            "type": "object",            "properties": {                "expression": {                    "type": "string",                    "description": "Mathematical expression to evaluate"                }            },            "required": ["expression"]        }    ),    handler=calculate_handler)

装饰器方式更简洁,会自动从函数签名和docstring生成输入模式。手动注册方式更灵活,适合需要精确控制Schema的场景。

错误处理

完善的错误处理是生产级MCP Server的关键。

from mcp.server import MCPServerfrom mcp.types import ToolErrormcp = MCPServer("Demo")@mcp.tool()async def risky_operation(data: str) -> str:    """Operation that might fail."""    try:        # 可能失败的操作        result = await perform_operation(data)        return result    except ValueError as e:        # 业务逻辑错误        raise ToolError(f"Invalid input: {str(e)}")    except ConnectionError as e:        # 连接错误        raise ToolError(f"Service unavailable: {str(e)}")    except Exception as e:        # 未知错误        raise ToolError(f"Internal error: {str(e)}")

错误类型分类:

  • ToolError:工具执行错误
  • ValidationError:输入验证错误
  • PermissionError:权限错误
  • TimeoutError:超时错误

错误处理最佳实践:

  1. 提供有意义的错误信息:帮助用户理解问题
  2. 不要暴露内部细节:避免泄露系统信息
  3. 记录错误日志:便于调试和监控
  4. 实现重试机制:对于临时性错误

资源定义与注册

静态资源:

@mcp.resource("config://app")def get_config() -> str:    """Get application configuration."""    return json.dumps({        "version": "1.0",        "debug": False,        "api_key": "hidden"    })

动态资源模板:

@mcp.resource("users://{user_id}/profile")def get_user_profile(user_id: str) -> str:    """Get user profile by ID."""    user = db.get_user(user_id)    return json.dumps(user)

资源订阅:

@mcp.resource("logs://app", subscribe=True)def get_logs() -> str:    """Get application logs."""    return "\n".join(log_entries)

提示词定义与注册

简单提示词:

@mcp.prompt()def code_review(code: str) -> str:    """Generate a code review prompt."""    return f"""Please review the following code and provide feedback:```python{code}

Focus on:

  1. Code quality and readability
  2. Potential bugs or issues
  3. Performance improvements
  4. Security concerns"“”
**带参数的提示词:**```python@mcp.prompt()def debug_error(error_message: str, stack_trace: str = None) -> str:    """Generate a debugging prompt for an error."""    prompt = f"Help me debug this error:\n\n{error_message}"    if stack_trace:        prompt += f"\n\nStack trace:\n{stack_trace}"    prompt += "\n\nPlease provide:\n1. Root cause analysis\n2. Potential solutions\n3. Prevention measures"    return prompt

🎯 本章小结: 使用Python SDK构建MCP Server非常简单。通过装饰器,你可以快速定义工具、资源和提示词。开发时使用mcp dev进行调试,生产环境选择stdio或HTTP传输。


完整项目实现

接下来,我们将构建两个完整的MCP Server项目:一个计算器服务器和一个用户数据服务器。这两个项目涵盖了MCP的三种原语,可以作为你开发实际项目的模板。

项目一:计算器MCP Server

这是一个功能完整的计算器服务器,包含基本的数学运算工具。

项目结构:

calculator-server/├── server.py├── requirements.txt└── README.md

requirements.txt:

mcp[cli]>=2.0.0

server.py:

# calculator-server/server.pyfrom mcp.server import MCPServerimport mathmcp = MCPServer("Calculator Server", version="1.0.0")@mcp.tool()def add(a: float, b: float) -> float:    """Add two numbers.        Args:        a: First number        b: Second number    """    return a + b@mcp.tool()def subtract(a: float, b: float) -> float:    """Subtract b from a.        Args:        a: Number to subtract from        b: Number to subtract    """    return a - b@mcp.tool()def multiply(a: float, b: float) -> float:    """Multiply two numbers.        Args:        a: First number        b: Second number    """    return a * b@mcp.tool()def divide(a: float, b: float) -> float:    """Divide a by b.        Args:        a: Dividend        b: Divisor    """    if b == 0:        raise ValueError("Cannot divide by zero")    return a / b@mcp.tool()def power(base: float, exponent: float) -> float:    """Raise base to the power of exponent.        Args:        base: Base number        exponent: Exponent    """    return math.pow(base, exponent)@mcp.tool()def square_root(number: float) -> float:    """Calculate the square root of a number.        Args:        number: Number to calculate square root of    """    if number < 0:        raise ValueError("Cannot calculate square root of negative number")    return math.sqrt(number)@mcp.tool()def calculate_expression(expression: str) -> str:    """Evaluate a mathematical expression safely.        Args:        expression: Mathematical expression to evaluate (e.g., "2 + 3 * 4")    """    # 简单的安全检查    allowed_chars = set("0123456789+-*/.() ")    if not all(c in allowed_chars for c in expression):        return "Error: Expression contains invalid characters"        try:        # ⚠️ 安全警告:eval函数存在代码注入风险,仅用于演示        # 生产环境应使用安全的数学表达式解析库(如simpleeval)        result = eval(expression, {"__builtins__": {}}, {"math": math})        return str(result)    except Exception as e:        return f"Error: {str(e)}"@mcp.resource("calculator://history")def get_history() -> str:    """Get calculator operation history."""    # 这里可以连接实际的历史记录存储    return '{"history": ["2 + 3 = 5", "10 / 2 = 5"]}'@mcp.prompt()def math_tutor(operation: str) -> str:    """Generate a math tutor prompt for a specific operation.        Args:        operation: The math operation to explain (e.g., "addition", "multiplication")    """    return f"""You are a math tutor. Explain the concept of {operation} in simple terms.Please provide:1. A clear definition2. Real-world examples3. Common mistakes to avoid4. Practice problemsMake your explanation engaging and easy to understand."""if __name__ == "__main__":    import asyncio    from mcp.server.stdio import stdio_server        async def main():        async with stdio_server() as streams:            await mcp.run(                streams[0],                streams[1],                mcp.create_initialization_options()            )        asyncio.run(main())

运行和测试:

# 进入项目目录cd calculator-server# 开发模式运行uv run mcp dev server.py# 在浏览器中打开 http://localhost:3000 进行测试

测试示例:

# 使用MCP Inspector测试# 1. 打开 http://localhost:3000# 2. 在Tools标签页选择"add"# 3. 输入参数:{"a": 5, "b": 3}# 4. 点击"Run Tool"# 5. 查看返回结果:8

项目二:用户数据MCP Server

这是一个用户数据管理服务器,展示了如何处理更复杂的业务逻辑和数据操作。

项目结构:

user-data-server/├── server.py├── database.py├── requirements.txt└── .env

requirements.txt:

mcp[cli]>=2.0.0python-dotenv>=1.0.0httpx>=0.24.0

.env:

API_KEY=your-api-key-hereDATABASE_URL=sqlite:///users.db

database.py:

# user-data-server/database.pyimport sqlite3import jsonfrom typing import Optional, Dict, Listclass UserDatabase:    def __init__(self, db_path: str = "users.db"):        self.db_path = db_path        self.init_db()        def init_db(self):        """Initialize the database with sample data."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()                # 创建用户表        cursor.execute('''            CREATE TABLE IF NOT EXISTS users (                id INTEGER PRIMARY KEY,                name TEXT NOT NULL,                email TEXT UNIQUE NOT NULL,                department TEXT,                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP            )        ''')                # 插入示例数据        sample_users = [            (1, "Alice", "alice@example.com", "Engineering"),            (2, "Bob", "bob@example.com", "Marketing"),            (3, "Charlie", "charlie@example.com", "Design"),            (4, "Diana", "diana@example.com", "Engineering"),            (5, "Eve", "eve@example.com", "Product")        ]                cursor.executemany(            "INSERT OR IGNORE INTO users (id, name, email, department) VALUES (?, ?, ?, ?)",            sample_users        )                conn.commit()        conn.close()        def get_user(self, user_id: int) -> Optional[Dict]:        """Get user by ID."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()        cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))        row = cursor.fetchone()        conn.close()                if row:            return {                "id": row[0],                "name": row[1],                "email": row[2],                "department": row[3],                "created_at": row[4]            }        return None        def list_users(self) -> List[Dict]:        """List all users."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()        cursor.execute("SELECT * FROM users")        rows = cursor.fetchall()        conn.close()                return [            {                "id": row[0],                "name": row[1],                "email": row[2],                "department": row[3],                "created_at": row[4]            }            for row in rows        ]        def create_user(self, name: str, email: str, department: str) -> Dict:        """Create a new user."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()                try:            cursor.execute(                "INSERT INTO users (name, email, department) VALUES (?, ?, ?)",                (name, email, department)            )            user_id = cursor.lastrowid            conn.commit()                        return {                "id": user_id,                "name": name,                "email": email,                "department": department            }        except sqlite3.IntegrityError:            raise ValueError(f"User with email {email} already exists")        finally:            conn.close()        def update_user(self, user_id: int, **kwargs) -> Optional[Dict]:        """Update user information."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()                # 构建更新语句        updates = []        values = []        for key, value in kwargs.items():            if key in ["name", "email", "department"]:                updates.append(f"{key} = ?")                values.append(value)                if not updates:            return self.get_user(user_id)                values.append(user_id)        query = f"UPDATE users SET {', '.join(updates)} WHERE id = ?"                cursor.execute(query, values)        conn.commit()        conn.close()                return self.get_user(user_id)        def delete_user(self, user_id: int) -> bool:        """Delete a user."""        conn = sqlite3.connect(self.db_path)        cursor = conn.cursor()        cursor.execute("DELETE FROM users WHERE id = ?", (user_id,))        deleted = cursor.rowcount > 0        conn.commit()        conn.close()        return deleted

server.py:

# user-data-server/server.pyfrom mcp.server import MCPServerfrom dotenv import load_dotenvimport osimport jsonfrom database import UserDatabase# 加载环境变量load_dotenv()# 创建服务器实例mcp = MCPServer("User Data Server", version="1.0.0")# 初始化数据库db = UserDatabase()# 工具定义@mcp.tool()def get_user(user_id: int) -> str:    """Get user information by ID.        Args:        user_id: The ID of the user to retrieve    """    user = db.get_user(user_id)    if user:        return json.dumps(user, indent=2)    raise ValueError(f"User with ID {user_id} not found")@mcp.tool()def create_user(name: str, email: str, department: str) -> str:    """Create a new user.        Args:        name: User's full name        email: User's email address        department: User's department    """    try:        user = db.create_user(name, email, department)        return json.dumps(user, indent=2)    except ValueError as e:        return f"Error: {str(e)}"@mcp.tool()def update_user(user_id: int, name: str = None, email: str = None, department: str = None) -> str:    """Update user information.        Args:        user_id: The ID of the user to update        name: New name (optional)        email: New email (optional)        department: New department (optional)    """    updates = {}    if name:        updates["name"] = name    if email:        updates["email"] = email    if department:        updates["department"] = department        if not updates:        return "Error: No fields to update"        user = db.update_user(user_id, **updates)    if user:        return json.dumps(user, indent=2)    raise ValueError(f"User with ID {user_id} not found")@mcp.tool()def delete_user(user_id: int) -> str:    """Delete a user by ID.        Args:        user_id: The ID of the user to delete    """    if db.delete_user(user_id):        return f"User with ID {user_id} deleted successfully"    raise ValueError(f"User with ID {user_id} not found")# 资源定义@mcp.resource("users://list")def list_users() -> str:    """Get list of all users."""    users = db.list_users()    return json.dumps(users, indent=2)@mcp.resource("users://{user_id}/profile")def user_profile(user_id: int) -> str:    """Get user profile by ID."""    user = db.get_user(user_id)    if user:        return json.dumps(user, indent=2)    raise ValueError(f"User with ID {user_id} not found")@mcp.resource("config://app")def app_config() -> str:    """Get application configuration."""    config = {        "version": "1.0.0",        "environment": os.getenv("ENVIRONMENT", "development"),        "api_key": "***hidden***",        "database": "SQLite",        "debug": os.getenv("DEBUG", "false").lower() == "true"    }    return json.dumps(config, indent=2)@mcp.resource("stats://users", subscribe=True)def user_stats() -> str:    """Get user statistics."""    users = db.list_users()    departments = {}    for user in users:        dept = user.get("department", "Unknown")        departments[dept] = departments.get(dept, 0) + 1        stats = {        "total_users": len(users),        "departments": departments,        "last_updated": "2026-09-15T10:00:00Z"    }    return json.dumps(stats, indent=2)# 提示词定义@mcp.prompt()def user_report(user_id: int) -> str:    """Generate a user report prompt.        Args:        user_id: The ID of the user to report on    """    user = db.get_user(user_id)    if not user:        return f"User with ID {user_id} not found"        return f"""Generate a comprehensive report for user:Name: {user['name']}Email: {user['email']}Department: {user['department']}Created: {user['created_at']}Please include:1. User overview2. Department context3. Activity summary4. RecommendationsFormat the report in a professional manner."""@mcp.prompt()def department_analysis(department: str) -> str:    """Generate a department analysis prompt.        Args:        department: The department to analyze    """    users = db.list_users()    dept_users = [u for u in users if u.get("department") == department]        return f"""Analyze the {department} department:Current members ({len(dept_users)}):{chr(10).join([f"- {u['name']} ({u['email']})" for u in dept_users])}Please provide:1. Team composition analysis2. Strengths and gaps3. Recommendations for improvement4. Growth opportunitiesFocus on actionable insights."""if __name__ == "__main__":    import asyncio    from mcp.server.stdio import stdio_server        async def main():        async with stdio_server() as streams:            await mcp.run(                streams[0],                streams[1],                mcp.create_initialization_options()            )        asyncio.run(main())

运行和测试:

# 进入项目目录cd user-data-server# 安装依赖uv add "mcp[cli]" python-dotenv httpx# 开发模式运行uv run mcp dev server.py# 在浏览器中测试各个工具和资源

🎯 本章小结: 通过这两个项目,你已经掌握了构建MCP Server的完整流程。第一个项目展示了基础工具的实现,第二个项目展示了更复杂的业务逻辑、数据库操作和资源管理。这些代码可以直接复用到你的实际项目中。


主流客户端集成

构建好MCP Server后,下一步就是将它集成到各种AI客户端中。以下是主流客户端的配置方法。

Claude Desktop

配置文件位置:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

配置示例:

{  "mcpServers": {    "calculator": {      "command": "python",      "args": ["/path/to/calculator-server/server.py"],      "env": {}    },    "user-data": {      "command": "python",      "args": ["/path/to/user-data-server/server.py"],      "env": {        "API_KEY": "your-api-key"      }    }  }}

VS Code

配置文件位置:

  • 工作区:.vscode/mcp.json
  • 用户:~/Library/Application Support/Code/User/mcp.json

配置示例:

{  "servers": {    "my-calculator": {      "command": "python",      "args": ["/path/to/calculator-server/server.py"],      "env": {}    }  }}

Cursor

配置文件位置:~/.cursor/mcp.json

配置示例:

{  "mcpServers": {    "calculator": {      "command": "python",      "args": ["/path/to/calculator-server/server.py"]    }  }}

其他支持MCP的客户端

客户端配置文件位置支持状态
Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json原生支持
VS Code.vscode/mcp.json原生支持
Cursor~/.cursor/mcp.json原生支持
Windsurf~/.codeium/windsurf/mcp_config.json原生支持
ChatGPT设置 > 连接器远程MCP服务器
Zed~/.config/zed/settings.json原生支持
Gemini CLI~/.gemini/settings.json原生支持

🎯 本章小结: MCP Server的集成非常简单,只需在客户端配置文件中指定服务器命令即可。一次构建的MCP Server可以在所有支持MCP的客户端中使用,这正是MCP"一次构建,处处使用"理念的体现。


生产实践

将MCP Server从开发环境部署到生产环境,需要考虑更多因素。

部署方案

本地部署:

# 开发环境uv run mcp dev server.py# 生产环境(stdio)uv run mcp run server.py

远程部署:

# HTTP模式uv run mcp run server.py --transport streamable-http# Docker部署docker run -p 8000:8000 my-mcp-server

云部署选项:

平台优势适用场景
AWS Lambda无服务器、自动扩展事件驱动、低流量
Google Cloud Run容器化、自动扩展Web服务、API
Azure Container Instances简单部署、按需付费快速原型、测试
Kubernetes高可用、复杂编排企业级、大规模

安全性考虑

认证与授权:

# OAuth2配置示例mcp_config = {    "auth": {        "enabled": True,        "type": "oauth2",        "issuer": "https://auth.example.com",        "client_id": "your-client-id",        "client_secret": "your-client-secret"    }}

网络安全:

  1. TLS加密:使用HTTPS加密通信
  2. 网络隔离:绑定到特定IP(如127.0.0.1)
  3. 防火墙:限制访问IP范围
  4. 速率限制:防止DDoS攻击

数据安全:

  1. 输入验证:验证所有输入参数
  2. 输出过滤:过滤敏感信息
  3. 日志脱敏:记录日志时隐藏敏感数据
  4. 审计跟踪:记录所有操作

性能优化

连接池管理:

# 数据库连接池配置db_config = {    "pool_size": 10,    "max_overflow": 20,    "pool_timeout": 30,    "pool_recycle": 1800}

缓存策略:

  1. 结果缓存:缓存工具执行结果
  2. 资源缓存:缓存资源读取结果
  3. 元数据缓存:缓存工具和资源列表

异步处理:

# 异步工具执行@mcp.tool()async def async_operation(data: str) -> str:    """Asynchronous operation."""    result = await perform_async_task(data)    return result

监控指标:

  • 请求响应时间
  • 错误率
  • 并发连接数
  • 资源使用率

可观测性

日志记录:

import logginglogging.basicConfig(    level=logging.INFO,    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')logger = logging.getLogger(__name__)@mcp.tool()def logged_operation(data: str) -> str:    """Operation with logging."""    logger.info(f"Starting operation with data: {data}")    try:        result = process_data(data)        logger.info(f"Operation completed successfully")        return result    except Exception as e:        logger.error(f"Operation failed: {str(e)}")        raise

健康检查:

@mcp.resource("health://check")def health_check() -> str:    """Health check endpoint."""    return json.dumps({        "status": "healthy",        "timestamp": datetime.now().isoformat(),        "version": "1.0.0"    })

🎯 本章小结: 生产环境部署MCP Server需要考虑安全性、性能和可观测性。通过合理的架构设计和监控,可以确保你的MCP Server稳定可靠地运行。


面试准备

掌握MCP不仅能提升你的开发能力,还能在面试中展示你对AI Agent架构的深入理解。

MCP是什么?答题模板

**基础回答:**MCP(Model Context Protocol)是Anthropic在2024年11月发布的一个开源标准,用于连接AI应用与外部系统。它就像AI应用的USB-C接口,提供了一种标准化的方式来连接AI模型与不同的数据源和工具。

**深入回答:**MCP解决了AI工具集成碎片化的问题。在MCP出现之前,每个AI应用需要为每个数据源开发自己的集成方案,导致开发复杂、难以扩展。MCP通过提供统一的协议标准,实现了"一次构建,处处使用"。

架构要点:

  1. 三层架构:Host(宿主)、Client(客户端)、Server(服务器)
  2. 三种原语:Tools(工具)、Resources(资源)、Prompts(提示词)
  3. 通信协议:基于JSON-RPC 2.0
  4. 传输方式:stdio(本地)和Streamable HTTP(远程)

技术细节:

  • Tools:模型控制的可执行函数,用于执行外部操作
  • Resources:应用控制的数据源,提供只读上下文
  • Prompts:用户控制的模板,指导模型交互行为

应用场景:

  • 连接数据库、API、文件系统等外部资源
  • 构建可复用的工具生态系统
  • 实现跨平台的AI工具集成

Server/Client通信原理的深入回答

通信流程:

  1. 连接建立:Client启动连接(stdio子进程或HTTP请求)
  2. 初始化握手:发送initialize请求,包含客户端能力
  3. 能力协商:服务器响应其支持的能力(工具、资源、提示词)
  4. 正常操作:根据需要发送请求/接收响应
  5. 关闭连接:优雅终止连接

消息格式:

  • Request:包含id、method、params
  • Response:包含id、result或error
  • Notification:单向通知,无id

传输机制:

  • stdio:通过标准输入/输出流通信,适合本地部署
  • Streamable HTTP:通过HTTP POST/GET通信,支持SSE流式传输,适合远程部署

安全性考虑:

  • 用户同意和控制
  • 工具行为描述应被视为不受信任
  • 服务器不应看到完整的提示词
  • 实施最小权限原则

常见问题与解决方案

**Q1:MCP与Function Calling有什么区别?**A:Function Calling是LLM提供商的内置功能,工具定义嵌入在API请求中。MCP是独立的协议标准,将工具外化为可共享的服务。Function Calling是模型级能力,MCP是应用级协议。

**Q2:如何选择stdio和Streamable HTTP?**A:stdio适合本地开发和单用户场景,简单安全。Streamable HTTP适合远程部署、多用户环境和生产场景,支持并发和扩展。

**Q3:MCP Server如何保证安全性?**A:1)实施认证和授权;2)使用最小权限原则;3)对工具执行进行沙箱隔离;4)监控和日志记录;5)定期安全审计。

**Q4:如何调试MCP Server?**A:1)使用MCP Inspector进行交互式测试;2)查看服务器日志;3)使用mcp dev命令进行开发调试;4)检查JSON-RPC消息格式。

**Q5:MCP Server如何扩展?**A:1)模块化设计,将工具、资源、提示词分离;2)使用装饰器简化注册;3)支持动态发现;4)实现健康检查和监控。

🎯 本章小结: 准备面试时,不仅要记住MCP的定义,还要理解它的架构设计和解决的问题。通过实际项目经验,你能更自信地回答相关问题。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

在这里插入图片描述

Logo

AtomGit AI 社区提供模型库、数据集、Agent、Token等资源

更多推荐