CoPaw MCP 集成详解
CoPaw MCP (Model Context Protocol) 集成详解
CoPaw 支持 MCP (Model Context Protocol),这是一个开放的标准协议,让 AI 助手能够与外部工具和服务进行无缝集成。通过 MCP,你可以扩展 CoPaw 的能力,访问数据库、API、文件系统等外部资源。
MCP 概述
什么是 MCP?
MCP (Model Context Protocol) 是一个标准化的协议,用于 AI 模型与外部系统之间的通信。它提供:
- 统一的接口规范
- 工具调用和结果返回
- 上下文传递和管理
- 错误处理和重试机制
MCP 的优势
| 特性 | 说明 | 优势 |
|------|------|------|
| 标准化 | 统一的协议 | 工具可跨平台使用 |
| 可扩展 | 易于添加新工具 | 快速集成外部服务 |
| 类型安全 | 支持类型检查 | 减少运行时错误 |
| 安全 | 权限控制 | 保护敏感资源 |
MCP 架构
┌─────────────┐
│ CoPaw │
│ (Agent) │
└──────┬──────┘
│ MCP
↓
┌──────────────────┐
│ MCP Server │
│ (工具管理器) │
└──────┬───────────┘
│
┌───┴───┐
│ │
┌──┴──┐ ┌──┴──┐
│工具1│ │工具2│ ...
└─────┘ └─────┘
MCP 配置
基本配置
编辑配置文件:
{
"mcp": {
"enabled": true,
"server": {
"host": "localhost",
"port": 8080,
"timeout": 30
},
"clients": [
{
"name": "database",
"type": "postgres",
"connection_string": "postgresql://user:pass@localhost:5432/db"
},
{
"name": "api",
"type": "http",
"base_url": "https://api.example.com",
"api_key": "sk-xxxxx"
}
],
"security": {
"enable_auth": true,
"allowed_tools": ["*"],
"rate_limit": 100
}
}
}
通过控制台配置
# 启用 MCP
/config set mcp.enabled true
# 设置服务器地址
/config set mcp.server.host localhost
/config set mcp.server.port 8080
# 启用认证
/config set mcp.security.enable_auth true
# 保存配置
/config save
MCP 工具开发
工具结构
MCP 工具是一个可执行的程序或服务,实现了 MCP 协议。
基本工具模板
#!/usr/bin/env python3
"""
MCP 工具示例
"""
import json
import sys
def get_schema():
"""返回工具的 schema 定义"""
return {
"name": "example_tool",
"description": "示例 MCP 工具",
"version": "1.0.0",
"parameters": {
"input": {
"type": "string",
"description": "输入参数"
}
},
"returns": {
"type": "object",
"properties": {
"result": {"type": "string"},
"status": {"type": "string"}
}
}
}
def execute(parameters):
"""执行工具逻辑"""
input_data = parameters.get("input", "")
# 工具的具体逻辑
result = f"处理结果: {input_data}"
return {
"result": result,
"status": "success"
}
def main():
"""主入口"""
# 读取输入
input_line = sys.stdin.readline()
data = json.loads(input_line)
# 获取命令
command = data.get("command", "execute")
if command == "schema":
schema = get_schema()
print(json.dumps(schema))
elif command == "execute":
parameters = data.get("parameters", {})
result = execute(parameters)
print(json.dumps(result))
else:
print(json.dumps({
"error": "Unknown command"
}), file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
数据库工具示例
#!/usr/bin/env python3
"""
PostgreSQL MCP 工具
"""
import json
import sys
import psycopg2
from typing import Dict, Any
def get_schema():
return {
"name": "postgres_query",
"description": "执行 PostgreSQL 查询",
"version": "1.0.0",
"parameters": {
"query": {
"type": "string",
"description": "SQL 查询语句",
"required": True
},
"database": {
"type": "string",
"description": "数据库名称",
"required": False,
"default": "default_db"
}
},
"returns": {
"type": "array",
"items": {
"type": "object"
}
}
}
def execute(parameters: Dict[str, Any]) -> Dict[str, Any]:
query = parameters["query"]
database = parameters.get("database", "default_db")
try:
# 连接数据库
conn = psycopg2.connect(
host="localhost",
database=database,
user="user",
password="password"
)
cursor = conn.cursor()
cursor.execute(query)
# 获取结果
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
result = []
for row in rows:
result.append(dict(zip(columns, row)))
cursor.close()
conn.close()
return {
"status": "success",
"data": result,
"row_count": len(result)
}
except Exception as e:
return {
"status": "error",
"error": str(e)
}
def main():
input_line = sys.stdin.readline()
data = json.loads(input_line)
command = data.get("command", "execute")
if command == "schema":
print(json.dumps(get_schema()))
elif command == "execute":
result = execute(data.get("parameters", {}))
print(json.dumps(result))
if __name__ == "__main__":
main()
HTTP API 工具示例
#!/usr/bin/env python3
"""
HTTP API MCP 工具
"""
import json
import sys
import requests
from typing import Dict, Any
def get_schema():
return {
"name": "http_request",
"description": "发送 HTTP 请求",
"version": "1.0.0",
"parameters": {
"url": {
"type": "string",
"description": "请求 URL",
"required": True
},
"method": {
"type": "string",
"description": "HTTP 方法",
"enum": ["GET", "POST", "PUT", "DELETE"],
"default": "GET"
},
"headers": {
"type": "object",
"description": "请求头",
"default": {}
},
"body": {
"type": "object",
"description": "请求体(JSON)",
"default": None
}
},
"returns": {
"type": "object",
"properties": {
"status_code": {"type": "integer"},
"body": {"type": "any"},
"headers": {"type": "object"}
}
}
}
def execute(parameters: Dict[str, Any]) -> Dict[str, Any]:
url = parameters["url"]
method = parameters.get("method", "GET").upper()
headers = parameters.get("headers", {})
body = parameters.get("body")
try:
response = requests.request(
method=method,
url=url,
headers=headers,
json=body
)
return {
"status_code": response.status_code,
"body": response.json() if response.headers.get("content-type", "").startswith("application/json") else response.text,
"headers": dict(response.headers)
}
except Exception as e:
return {
"status": "error",
"error": str(e)
}
def main():
input_line = sys.stdin.readline()
data = json.loads(input_line)
command = data.get("command", "execute")
if command == "schema":
print(json.dumps(get_schema()))
elif command == "execute":
result = execute(data.get("parameters", {}))
print(json.dumps(result))
if __name__ == "__main__":
main()
MCP 工具注册
注册工具
# 注册工具
/mcp register --name database --type postgres --path /path/to/postgres_tool.py
# 查看已注册工具
/mcp list
# 查看工具详情
/mcp show database
通过配置文件注册
{
"mcp": {
"enabled": true,
"tools": [
{
"name": "postgres_query",
"type": "executable",
"path": "/path/to/postgres_tool.py",
"enabled": true,
"permissions": {
"allowed_users": ["*"],
"max_calls_per_minute": 100
}
},
{
"name": "http_request",
"type": "executable",
"path": "/path/to/http_tool.py",
"enabled": true,
"permissions": {
"allowed_users": ["*"],
"allowed_domains": ["api.example.com"]
}
}
]
}
}
通过控制台配置
# 添加工具
/config set mcp.tools.[0].name postgres_query
/config set mcp.tools.[0].type executable
/config set mcp.tools.[0].path /path/to/postgres_tool.py
/config set mcp.tools.[0].enabled true
# 保存配置
/config save
# 重启 MCP 服务
/mcp restart
使用 MCP 工具
在对话中调用
# 直接调用工具
用户: 查询用户信息
CoPaw: 我来查询数据库...
# 自动调用 postgres_query 工具
/mcp execute postgres_query --parameters '{"query": "SELECT * FROM users LIMIT 10"}'
返回结果:
{
"status": "success",
"data": [...],
"row_count": 10
}
查询结果:找到 10 个用户...
通过命令调用
# 执行工具
/mcp execute <工具名称> --parameters '{"key": "value"}'
# 示例:查询数据库
/mcp execute postgres_query --parameters '{"query": "SELECT * FROM products"}'
# 示例:发送 HTTP 请求
/mcp execute http_request --parameters '{"url": "https://api.example.com/users", "method": "GET"}'
批量执行
# 批量执行多个工具
/mcp batch << 'EOF'
postgres_query: {"query": "SELECT COUNT(*) FROM users"}
postgres_query: {"query": "SELECT * FROM orders LIMIT 10"}
http_request: {"url": "https://api.example.com/stats"}
EOF
MCP 常用工具
1. 文件系统工具
#!/usr/bin/env python3
"""文件系统 MCP 工具"""
import json
import sys
import os
def execute(parameters):
action = parameters.get("action")
path = parameters.get("path")
if action == "read":
with open(path, 'r') as f:
content = f.read()
return {"content": content}
elif action == "write":
content = parameters.get("content")
with open(path, 'w') as f:
f.write(content)
return {"status": "success"}
elif action == "list":
files = os.listdir(path)
return {"files": files}
elif action == "exists":
exists = os.path.exists(path)
return {"exists": exists}
2. 邮件工具
#!/usr/bin/env python3
"""邮件 MCP 工具"""
import json
import sys
import smtplib
from email.mime.text import MIMEText
def execute(parameters):
to = parameters.get("to")
subject = parameters.get("subject")
body = parameters.get("body")
msg = MIMEText(body)
msg['Subject'] = subject
msg['To'] = to
msg['From'] = "copaw@example.com"
# 发送邮件
smtp = smtplib.SMTP('localhost', 25)
smtp.send_message(msg)
smtp.quit()
return {"status": "success"}
3. 云存储工具
#!/usr/bin/env python3
"""云存储 MCP 工具(S3)"""
import json
import sys
import boto3
def execute(parameters):
action = parameters.get("action")
bucket = parameters.get("bucket")
key = parameters.get("key")
s3 = boto3.client('s3')
if action == "upload":
file_path = parameters.get("file_path")
s3.upload_file(file_path, bucket, key)
return {"status": "success"}
elif action == "download":
file_path = parameters.get("file_path")
s3.download_file(bucket, key, file_path)
return {"status": "success"}
elif action == "list":
objects = s3.list_objects_v2(Bucket=bucket, Prefix=key)
return {"objects": objects.get('Contents', [])}
MCP 高级功能
工具链
#!/usr/bin/env python3
"""工具链示例"""
import json
import sys
def execute(parameters):
# 第一步:获取数据
data1 = execute_tool("fetch_data", parameters)
# 第二步:处理数据
data2 = execute_tool("process_data", data1)
# 第三步:保存结果
result = execute_tool("save_data", data2)
return result
工具组合
{
"tool_chain": [
{
"name": "fetch_data",
"parameters": {"source": "database"}
},
{
"name": "transform",
"parameters": {"format": "json"}
},
{
"name": "save",
"parameters": {"destination": "s3://bucket/data.json"}
}
]
}
错误处理
def execute(parameters):
try:
# 尝试执行
result = do_something(parameters)
return {"status": "success", "data": result}
except ValueError as e:
return {"status": "error", "error_type": "validation", "message": str(e)}
except Exception as e:
return {"status": "error", "error_type": "runtime", "message": str(e)}
重试机制
import time
def execute(parameters, max_retries=3):
for attempt in range(max_retries):
try:
result = do_something(parameters)
return {"status": "success", "data": result}
except Exception as e:
if attempt == max_retries - 1:
raise
# 指数退避
wait_time = 2 ** attempt
time.sleep(wait_time)
return {"status": "error", "message": "Max retries exceeded"}
MCP 最佳实践
1. 定义清晰的 Schema
def get_schema():
return {
"name": "my_tool",
"description": "清晰的描述工具的功能",
"parameters": {
"input": {
"type": "string",
"description": "详细说明每个参数的作用",
"required": True
}
}
}
2. 返回标准化的结果
def execute(parameters):
try:
result = do_something()
return {
"status": "success",
"data": result,
"timestamp": time.time()
}
except Exception as e:
return {
"status": "error",
"error": str(e),
"timestamp": time.time()
}
3. 添加日志记录
import logging
logger = logging.getLogger(__name__)
def execute(parameters):
logger.info(f"Executing tool with parameters: {parameters}")
try:
result = do_something()
logger.info(f"Tool executed successfully")
return result
except Exception as e:
logger.error(f"Tool execution failed: {e}")
raise
4. 实现权限控制
def execute(parameters, user=None):
# 检查用户权限
if not check_permission(user, "use_tool"):
return {
"status": "error",
"error": "Permission denied"
}
# 执行工具逻辑
result = do_something(parameters)
return result
5. 使用类型提示
from typing import Dict, Any, Optional
def execute(parameters: Dict[str, Any], user: Optional[str] = None) -> Dict[str, Any]:
"""执行工具逻辑
Args:
parameters: 工具参数
user: 用户 ID
Returns:
执行结果
"""
pass
MCP 故障排查
Q1: 工具无法注册?
# 检查工具路径
/file exists /path/to/tool.py
# 检查工具权限
/chmod +x /path/to/tool.py
# 查看注册日志
/mcp logs --level debug
Q2: 工具执行失败?
# 手动执行工具测试
/path/to/tool.py <<< '{"command": "schema"}'
# 查看工具日志
/mcp logs <工具名称>
# 启用详细日志
/config set mcp.debug true
Q3: 工具响应超时?
# 调整超时时间
/config set mcp.server.timeout 60
# 保存配置
/config save
# 重启 MCP 服务
/mcp restart
Q4: 权限问题?
# 检查工具权限
/mcp show <工具名称> --permissions
# 更新权限配置
/mcp update <工具名称> --permissions '{"allowed_users": ["*"]}'
Q5: 如何调试工具?
# 启用调试模式
/mcp set <工具名称> --debug true
# 手动执行
/mcp execute <工具名称> --parameters '{}' --debug
# 查看详细输出
/mcp logs <工具名称> --verbose
总结
通过本教程,你应该已经掌握了:
- ✅ MCP 的基本概念和架构
- ✅ MCP 工具的开发方法
- ✅ 工具注册和配置
- ✅ 工具的调用和使用
- ✅ 常用工具示例
- ✅ 高级功能(工具链、错误处理、重试)
- ✅ 最佳实践和故障排查
下一章
在下一章中,我们将学习 CoPaw 配置管理详解,了解如何管理和维护 CoPaw 的配置文件。
相关资源
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







