模型上下文协议实现

一个完整的Python实现的模型上下文协议(MCP),提供服务器和客户端组件,用于构建AI集成应用。

  • by coop-columb
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 coop-columb/mcp-project

使用说明

MCP项目

Python中模型上下文协议(MCP)的完整实现,为服务器和客户端组件提供了一套丰富的功能,用于构建AI集成应用程序。

概述

模型上下文协议(MCP)是由Anthropic开发的一个开放标准,它规范了人工智能应用程序如何为大型语言模型(LLM)提供上下文。该项目在Python中提供了一个完整的、可用于生产的MCP实现。

特性

🚀 完成MCP实施

  • 完全协议支持:实施MCP规范版本2025-03-26
  • JSON-RPC 2.0:基于行业标准JSON-RPC构建,实现可靠通信
  • 多个传输:支持TCP、WebSocket和stdio传输

🔧 服务器组件

  • 资源管理:将文件、URL和动态内容作为MCP资源提供
  • 工具集成:将函数作为LLM的可调用工具公开
  • 提示模板:提供具有参数替换的可重用提示模板
  • 内置处理器:用于常见操作(文件系统、shell命令等)的预构建处理程序

💻 客户端组件

  • 异步客户端:用于连接MCP服务器的全功能异步客户端
  • 会话管理:具有连接池的高级会话管理
  • 简单API:简化界面,实现快速集成
  • CLI工具:用于服务器探索和交互的命令行工具

🛠️ 开发者体验

  • 类型安全:支持mypy的完整类型提示
  • 丰富的日志记录:具有丰富控制台输出的结构化日志记录
  • 综合测试:带有pytest的广泛测试套件
  • 例子:常见用例的工作示例

快速开始

安装

# Install from source
git clone <repository-url>
cd mcp-project
pip install -e ".[dev]"

基本服务器

import asyncio
from mcp_project.server import MCPServer

async def main():
    server = MCPServer()
    
    # Register a simple tool
    server.tools.register_simple_tool(
        name="greet",
        description="Greet someone by name",
        handler=lambda args: f"Hello, {args.get('name', 'World')}!",
        name={"type": "string", "description": "Name to greet"}
    )
    
    await server.start()
    print("Server started on port 8000")
    
    # Start TCP server (in real usage, you'd use the CLI)
    # mcp-server tcp --port 8000

if __name__ == "__main__":
    asyncio.run(main())

基本客户端

import asyncio
from mcp_project.client import MCPSession

async def main():
    session = MCPSession()
    
    async with session.connect_tcp("localhost", 8000) as client:
        # List available tools
        tools = await client.list_tools()
        print(f"Available tools: {[t['name'] for t in tools]}")
        
        # Call a tool
        result = await client.call_tool("greet", {"name": "Alice"})
        print(f"Result: {result['content'][0]['text']}")

asyncio.run(main())

CLI使用情况

启动服务器

# TCP server
mcp-server tcp --host localhost --port 8000

# Stdio server (for direct integration)
mcp-server stdio

探索服务器

# See what's available
mcp-client explore --host localhost --port 8000

# Call a tool
mcp-client call-tool greet --arg name="World" --host localhost --port 8000

# Read a resource
mcp-client read-resource "file:///path/to/file.txt" --host localhost --port 8000

# Get a prompt
mcp-client get-prompt code_review --arg code="print('hello')" --host localhost --port 8000

建筑

┌─────────────────┐    JSON-RPC 2.0    ┌─────────────────┐
│   MCP Client    │◄─────────────────►│   MCP Server    │
├─────────────────┤                    ├─────────────────┤
│ • Session Mgmt  │                    │ • Resource Reg  │
│ • Request/Resp  │                    │ • Tool Registry │
│ • Error Handling│                    │ • Prompt Reg    │
│ • Transport     │                    │ • Transport     │
└─────────────────┘                    └─────────────────┘
        │                                       │
        └───────────────┬───────────────────────┘
                        │
                ┌───────▼────────┐
                │   Transport    │
                │ • TCP          │
                │ • WebSocket    │
                │ • Stdio        │
                └────────────────┘

核心概念

资源

资源是LLM可以读取的数据源:

# Static resource
server.resources.register_static_resource(
    uri="data://greeting",
    name="Greeting Message",
    content="Hello from MCP!",
    mime_type="text/plain"
)

# Dynamic resource
async def get_weather():
    return [ResourceContent(
        uri="weather://current",
        mime_type="application/json",
        text='{"temp": 72, "condition": "sunny"}'
    )]

server.resources.register_resource(
    uri="weather://current",
    name="Current Weather",
    handler=get_weather
)

工具

工具是LLM可以调用以执行操作的函数:

async def file_search(args):
    pattern = args["pattern"]
    # Search logic here
    return f"Found files matching {pattern}"

server.tools.register_tool(
    name="search_files",
    description="Search for files by pattern",
    input_schema={
        "type": "object",
        "properties": {
            "pattern": {"type": "string", "description": "Search pattern"}
        },
        "required": ["pattern"]
    },
    handler=file_search
)

鼓励

提示是可以用参数填充的模板:

server.prompts.register_template_prompt(
    name="code_review",
    description="Generate a code review prompt",
    template="Review this {language} code:\n\n{code}",
    arguments=[
        {"name": "language", "description": "Programming language"},
        {"name": "code", "description": "Code to review"}
    ]
)

例子

这 examples/ 目录包含完整的工作示例:

  • basic_server.py:具有资源、工具和提示的简单服务器
  • basic_client.py:探索服务器并与之交互的客户端
  • file_server.py:文件系统服务器将文件作为资源和工具公开

运行示例:

# Terminal 1: Start server
python examples/basic_server.py

# Terminal 2: Run client
python examples/basic_client.py

发展

设置开发环境

# Clone repository
git clone <repository-url>
cd mcp-project

# Install in development mode
make install-dev

# Run tests
make test

# Run type checking
make type-check

# Format code
make format

# Run all checks
make all-checks

项目结构

mcp-project/
├── src/mcp_project/          # Main package
│   ├── protocol/             # Protocol implementation
│   ├── server/               # Server components
│   ├── client/               # Client components
│   └── tools/                # Built-in tools
├── examples/                 # Usage examples
├── tests/                    # Test suite
├── docs/                     # Documentation
└── pyproject.toml           # Project configuration

运行测试

# Run all tests
pytest tests/

# Run with coverage
pytest --cov=src tests/ --cov-report=html

# Run specific test file
pytest tests/test_server.py -v

运输选项

TCP传输

最适合基于网络的集成:

# Server
async with session.connect_tcp("localhost", 8000) as client:
    # Use client

# Client  
mcp-client explore --host localhost --port 8000

标准运输

最适合子流程集成:

# Start as subprocess
process = subprocess.Popen([
    "python", "-m", "mcp_project.server.cli", "stdio"
], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

WebSocket传输

最适合web应用程序:

async with session.connect_websocket("ws://localhost:8080/mcp") as client:
    # Use client

错误处理

MCP项目提供全面的错误处理:

from mcp_project.protocol import MCPError, ToolNotFound, ResourceNotFound

try:
    result = await client.call_tool("unknown_tool", {})
except ToolNotFound as e:
    print(f"Tool not found: {e}")
except MCPError as e:
    print(f"MCP error {e.code}: {e.message}")

配置

服务器配置

config = MCPServerConfig(
    name="my-server",
    version="1.0.0",
    max_connections=100,
    request_timeout=30.0,
    enable_logging=True
)
server = MCPServer(config)

客户端配置

config = MCPClientConfig(
    name="my-client",
    version="1.0.0",
    request_timeout=30.0,
    max_retries=3
)
session = MCPSession(config)

安全考虑

  • 输入验证:所有输入均使用Pydantic模型进行验证
  • 资源访问:在资源处理程序中实施适当的访问控制
  • 工具执行:工具应验证输入并限制范围
  • 网络安全:将TLS用于生产TCP/Webocket连接

贡献

  1. 分叉存储库
  2. 创建要素分支(git checkout -b feature/amazing-feature)
  3. 进行更改
  4. 添加新功能的测试
  5. 运行测试套件(make all-checks)
  6. 提交您的更改(git commit -m 'Add amazing feature')
  7. 推到分支(git push origin feature/amazing-feature)
  8. 打开拉取请求

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。

致谢

  • Anthropic 用于创建模型上下文协议规范
  • MCP社区提供反馈和贡献
  • JSON-RPC和asyncio生态系统的贡献者

链接