Appearance
第7天:MCP协议发布(2024年底)
学习目标
- 理解MCP(Model Context Protocol)的诞生背景
- 掌握MCP协议的核心思想和架构
- 了解MCP Server和Client的实现
- 理解MCP与Claude Desktop的集成
- 掌握MCP的应用场景和最佳实践
课程内容
1. MCP的诞生背景
1.1 AI Agent的集成挑战
1.1.1 集成复杂度高
问题:
- 每个工具都需要单独集成
- API接口不统一
- 数据格式不一致
- 错误处理机制各异
示例:
python
# 集成文件系统
def read_file(path):
# 实现文件读取
pass
# 集成数据库
def query_database(sql):
# 实现数据库查询
pass
# 集成API
def call_api(url, params):
# 实现API调用
pass
# 每个工具都需要单独实现1.1.2 可扩展性差
问题:
- 添加新工具需要修改核心代码
- 工具之间难以协作
- 难以动态加载工具
- 维护成本高
1.1.3 标准缺失
问题:
- 没有统一的协议
- 各家实现不兼容
- 难以共享工具
- 生态碎片化
1.2 MCP的诞生
2024年底:Anthropic发布MCP(Model Context Protocol)
核心思想:
- 标准化AI Agent与外部系统的交互
- 提供统一的接口规范
- 降低集成复杂度
- 促进工具生态发展
目标:
- 简化工具集成
- 提高互操作性
- 促进生态繁荣
- 降低开发成本
2. MCP协议详解
2.1 MCP的核心概念
2.1.1 定义
MCP(Model Context Protocol):一个开放协议,用于标准化AI模型与外部系统(如工具、数据库、API等)之间的交互。
2.1.2 核心组件
MCP Server:
- 提供工具和资源的端点
- 实现MCP协议
- 暴露能力给AI模型
MCP Client:
- 连接到MCP Server
- 调用Server提供的工具
- 访问Server提供的资源
MCP Host:
- 托管MCP Client的环境
- 如Claude Desktop、VS Code等
2.1.3 核心能力
工具(Tools):
- 可执行的操作
- 带参数和返回值
- 类似函数调用
资源(Resources):
- 可访问的数据
- 支持读取和更新
- 类似文件系统
提示(Prompts):
- 预定义的提示模板
- 可参数化
- 简化常用任务
2.2 MCP协议架构
2.2.1 整体架构
┌─────────────────────────────────────────────────┐
│ MCP Host │
│ (Claude Desktop, VS Code) │
└────────────────┬────────────────────────────┘
│
│ MCP Protocol
│
┌────────────────▼────────────────────────────┐
│ MCP Client │
│ (连接到MCP Server) │
└────────────────┬────────────────────────────┘
│
│ MCP Protocol
│
┌────────────────▼────────────────────────────┐
│ MCP Server │
│ (提供工具和资源) │
│ ┌──────────────────────────────────┐ │
│ │ Tools (工具) │ │
│ │ - file_read │ │
│ │ - file_write │ │
│ │ - database_query │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ Resources (资源) │ │
│ │ - files/ │ │
│ │ - database/ │ │
│ │ - api/ │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ Prompts (提示) │ │
│ │ - summarize_file │ │
│ │ - analyze_data │ │
│ └──────────────────────────────────┘ │
└──────────────────────────────────────────┘2.2.2 通信流程
1. 初始化:
Client → Server: initialize
Server → Client: server_info2. 工具调用:
Client → Server: tools/list
Server → Client: tools_list
Client → Server: tools/call
Server → Client: tool_result3. 资源访问:
Client → Server: resources/list
Server → Client: resources_list
Client → Server: resources/read
Server → Client: resource_content
Client → Server: resources/write
Server → Client: write_result4. 提示使用:
Client → Server: prompts/list
Server → Client: prompts_list
Client → Server: prompts/get
Server → Client: prompt_content2.3 MCP协议规范
2.3.1 JSON-RPC 2.0
MCP基于JSON-RPC 2.0协议。
请求格式:
json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "file_read",
"arguments": {
"path": "/path/to/file.txt"
}
},
"id": 1
}响应格式:
json
{
"jsonrpc": "2.0",
"result": {
"content": "file content here"
},
"id": 1
}错误格式:
json
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid params"
},
"id": 1
}2.3.2 工具定义
工具列表:
json
{
"tools": [
{
"name": "file_read",
"description": "Read a file from the filesystem",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
}
},
"required": ["path"]
}
},
{
"name": "file_write",
"description": "Write content to a file",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
},
"content": {
"type": "string",
"description": "Content to write"
}
},
"required": ["path", "content"]
}
}
]
}工具调用:
json
{
"name": "file_read",
"arguments": {
"path": "/path/to/file.txt"
}
}工具结果:
json
{
"content": [
{
"type": "text",
"text": "file content here"
}
]
}2.3.3 资源定义
资源列表:
json
{
"resources": [
{
"uri": "file:///path/to/file.txt",
"name": "file.txt",
"description": "A text file",
"mimeType": "text/plain"
},
{
"uri": "database://users",
"name": "users",
"description": "User database",
"mimeType": "application/json"
}
]
}资源读取:
json
{
"uri": "file:///path/to/file.txt"
}资源内容:
json
{
"contents": [
{
"uri": "file:///path/to/file.txt",
"mimeType": "text/plain",
"text": "file content here"
}
]
}2.3.4 提示定义
提示列表:
json
{
"prompts": [
{
"name": "summarize_file",
"description": "Summarize a file",
"arguments": [
{
"name": "path",
"description": "Path to the file",
"required": true
}
]
},
{
"name": "analyze_data",
"description": "Analyze data",
"arguments": [
{
"name": "data",
"description": "Data to analyze",
"required": true
}
]
}
]
}提示获取:
json
{
"name": "summarize_file",
"arguments": {
"path": "/path/to/file.txt"
}
}提示内容:
json
{
"messages": [
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "file:///path/to/file.txt"
}
}
},
{
"role": "user",
"content": {
"type": "text",
"text": "Please summarize this file."
}
}
]
}3. MCP Server开发
3.1 Server基础
3.1.1 Server初始化
python
from mcp.server import Server
from mcp.types import Tool, Resource
# 创建Server
server = Server(
name="my-mcp-server",
version="1.0.0"
)
# 定义工具
@server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="file_read",
description="Read a file from the filesystem",
inputSchema={
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
}
},
"required": ["path"]
}
),
Tool(
name="file_write",
description="Write content to a file",
inputSchema={
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
},
"content": {
"type": "string",
"description": "Content to write"
}
},
"required": ["path", "content"]
}
)
]
# 定义资源
@server.list_resources()
async def list_resources() -> list[Resource]:
return [
Resource(
uri="file:///path/to/file.txt",
name="file.txt",
description="A text file",
mimeType="text/plain"
)
]
# 启动Server
if __name__ == "__main__":
import asyncio
asyncio.run(server.run())3.1.2 工具实现
python
import os
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "file_read":
path = arguments.get("path")
try:
with open(path, 'r') as f:
content = f.read()
return content
except Exception as e:
return f"Error reading file: {str(e)}"
elif name == "file_write":
path = arguments.get("path")
content = arguments.get("content")
try:
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(content)
return f"Successfully wrote to {path}"
except Exception as e:
return f"Error writing file: {str(e)}"
else:
return f"Unknown tool: {name}"3.1.3 资源实现
python
@server.read_resource()
async def read_resource(uri: str) -> str:
if uri.startswith("file://"):
path = uri[7:] # Remove "file://" prefix
try:
with open(path, 'r') as f:
content = f.read()
return content
except Exception as e:
return f"Error reading resource: {str(e)}"
else:
return f"Unsupported URI scheme: {uri}"
@server.write_resource()
async def write_resource(uri: str, content: str) -> str:
if uri.startswith("file://"):
path = uri[7:] # Remove "file://" prefix
try:
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(content)
return f"Successfully wrote to {path}"
except Exception as e:
return f"Error writing resource: {str(e)}"
else:
return f"Unsupported URI scheme: {uri}"3.2 高级功能
3.2.1 数据库集成
python
import sqlite3
# 数据库工具
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "database_query":
sql = arguments.get("sql")
try:
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
conn.close()
return str(results)
except Exception as e:
return f"Error executing query: {str(e)}"
# ... 其他工具
# 数据库资源
@server.read_resource()
async def read_resource(uri: str) -> str:
if uri.startswith("database://"):
table = uri[11:] # Remove "database://" prefix
try:
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(f"SELECT * FROM {table}")
results = cursor.fetchall()
conn.close()
return str(results)
except Exception as e:
return f"Error reading database: {str(e)}"
# ... 其他资源3.2.2 API集成
python
import requests
# API工具
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "api_call":
url = arguments.get("url")
method = arguments.get("method", "GET")
params = arguments.get("params", {})
headers = arguments.get("headers", {})
data = arguments.get("data", {})
try:
if method == "GET":
response = requests.get(url, params=params, headers=headers)
elif method == "POST":
response = requests.post(url, json=data, headers=headers)
else:
return f"Unsupported method: {method}"
return response.text
except Exception as e:
return f"Error calling API: {str(e)}"
# ... 其他工具3.2.3 提示模板
python
@server.list_prompts()
async def list_prompts() -> list[dict]:
return [
{
"name": "summarize_file",
"description": "Summarize a file",
"arguments": [
{
"name": "path",
"description": "Path to the file",
"required": True
}
]
},
{
"name": "analyze_data",
"description": "Analyze data",
"arguments": [
{
"name": "data",
"description": "Data to analyze",
"required": True
}
]
}
]
@server.get_prompt()
async def get_prompt(name: str, arguments: dict) -> list[dict]:
if name == "summarize_file":
path = arguments.get("path")
return [
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": f"file://{path}"
}
}
},
{
"role": "user",
"content": {
"type": "text",
"text": "Please summarize this file."
}
}
]
# ... 其他提示4. MCP Client开发
4.1 Client基础
4.1.1 连接Server
python
from mcp.client import Client
# 创建Client
client = Client(
name="my-mcp-client",
version="1.0.0"
)
# 连接到Server
async def connect_to_server():
await client.connect("stdio") # 或 "tcp://localhost:8080"
# 获取Server信息
server_info = await client.get_server_info()
print(f"Connected to server: {server_info['name']}")
# 运行Client
if __name__ == "__main__":
import asyncio
asyncio.run(connect_to_server())4.1.2 调用工具
python
async def call_tools():
# 列出可用工具
tools = await client.list_tools()
print("Available tools:")
for tool in tools:
print(f" - {tool['name']}: {tool['description']}")
# 调用工具
result = await client.call_tool(
name="file_read",
arguments={
"path": "/path/to/file.txt"
}
)
print(f"Tool result: {result}")
# 调用另一个工具
result = await client.call_tool(
name="file_write",
arguments={
"path": "/path/to/output.txt",
"content": "Hello, MCP!"
}
)
print(f"Tool result: {result}")4.1.3 访问资源
python
async def access_resources():
# 列出可用资源
resources = await client.list_resources()
print("Available resources:")
for resource in resources:
print(f" - {resource['uri']}: {resource['name']}")
# 读取资源
content = await client.read_resource(
uri="file:///path/to/file.txt"
)
print(f"Resource content: {content}")
# 写入资源
result = await client.write_resource(
uri="file:///path/to/output.txt",
content="Hello, MCP!"
)
print(f"Write result: {result}")4.2 高级功能
4.2.1 批量操作
python
async def batch_operations():
# 批量调用工具
results = await asyncio.gather(
client.call_tool("file_read", {"path": "/file1.txt"}),
client.call_tool("file_read", {"path": "/file2.txt"}),
client.call_tool("file_read", {"path": "/file3.txt"}),
)
for i, result in enumerate(results):
print(f"File {i+1}: {result}")4.2.2 错误处理
python
async def safe_tool_call(name: str, arguments: dict):
try:
result = await client.call_tool(name, arguments)
return result
except Exception as e:
print(f"Error calling tool {name}: {str(e)}")
return None
async def safe_resource_read(uri: str):
try:
content = await client.read_resource(uri)
return content
except Exception as e:
print(f"Error reading resource {uri}: {str(e)}")
return None4.2.3 事件监听
python
@client.on("notification")
async def handle_notification(notification):
print(f"Received notification: {notification}")
@client.on("error")
async def handle_error(error):
print(f"Received error: {error}")5. MCP与Claude Desktop集成
5.1 Claude Desktop配置
5.1.1 配置文件位置
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
5.1.2 配置文件格式
json
{
"mcpServers": {
"filesystem": {
"command": "python",
"args": ["/path/to/filesystem_server.py"]
},
"database": {
"command": "python",
"args": ["/path/to/database_server.py"]
},
"api": {
"command": "python",
"args": ["/path/to/api_server.py"]
}
}
}5.1.3 配置示例
json
{
"mcpServers": {
"my-custom-server": {
"command": "python",
"args": ["/Users/username/mcp-servers/my_server.py"],
"env": {
"API_KEY": "your-api-key",
"DATABASE_URL": "postgresql://user:password@localhost/db"
}
}
}
}5.2 Claude Desktop使用
5.2.1 使用工具
在Claude Desktop中,你可以直接调用MCP Server提供的工具。
示例对话:
用户:请读取 /path/to/file.txt 文件的内容
Claude:[调用 file_read 工具]
文件内容如下:
[文件内容]
用户:请将这段内容写入 /path/to/output.txt
Claude:[调用 file_write 工具]
已成功写入文件。5.2.2 访问资源
Claude Desktop可以自动访问MCP Server提供的资源。
示例对话:
用户:请分析 database://users 资源
Claude:[读取 database://users 资源]
数据库内容如下:
[数据库内容]
分析结果:
[分析结果]5.2.3 使用提示
Claude Desktop可以使用MCP Server提供的预定义提示。
示例对话:
用户:请使用 summarize_file 提示来总结 /path/to/file.txt
Claude:[调用 summarize_file 提示]
文件总结如下:
[总结内容]6. MCP的应用场景
6.1 文件系统操作
场景:AI Agent需要读写文件。
工具:
file_read: 读取文件file_write: 写入文件file_list: 列出文件file_delete: 删除文件
示例:
python
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "file_read":
path = arguments.get("path")
with open(path, 'r') as f:
return f.read()
elif name == "file_write":
path = arguments.get("path")
content = arguments.get("content")
with open(path, 'w') as f:
f.write(content)
return f"Successfully wrote to {path}"
elif name == "file_list":
path = arguments.get("path", ".")
files = os.listdir(path)
return "\n".join(files)
elif name == "file_delete":
path = arguments.get("path")
os.remove(path)
return f"Successfully deleted {path}"6.2 数据库操作
场景:AI Agent需要查询和更新数据库。
工具:
database_query: 执行SQL查询database_execute: 执行SQL语句database_schema: 获取数据库schema
示例:
python
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "database_query":
sql = arguments.get("sql")
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
conn.close()
return str(results)
elif name == "database_execute":
sql = arguments.get("sql")
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
conn.close()
return "Successfully executed SQL"
elif name == "database_schema":
table = arguments.get("table")
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(f"PRAGMA table_info({table})")
schema = cursor.fetchall()
conn.close()
return str(schema)6.3 API调用
场景:AI Agent需要调用外部API。
工具:
api_get: GET请求api_post: POST请求api_put: PUT请求api_delete: DELETE请求
示例:
python
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "api_get":
url = arguments.get("url")
params = arguments.get("params", {})
headers = arguments.get("headers", {})
response = requests.get(url, params=params, headers=headers)
return response.text
elif name == "api_post":
url = arguments.get("url")
data = arguments.get("data", {})
headers = arguments.get("headers", {})
response = requests.post(url, json=data, headers=headers)
return response.text
# ... 其他HTTP方法6.4 云服务集成
场景:AI Agent需要与云服务交互。
工具:
aws_s3_upload: 上传文件到S3aws_s3_download: 从S3下载文件gcp_storage_upload: 上传文件到GCSazure_blob_upload: 上传文件到Azure Blob
示例:
python
import boto3
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "aws_s3_upload":
bucket = arguments.get("bucket")
key = arguments.get("key")
file_path = arguments.get("file_path")
s3 = boto3.client('s3')
s3.upload_file(file_path, bucket, key)
return f"Successfully uploaded {file_path} to s3://{bucket}/{key}"
elif name == "aws_s3_download":
bucket = arguments.get("bucket")
key = arguments.get("key")
file_path = arguments.get("file_path")
s3 = boto3.client('s3')
s3.download_file(bucket, key, file_path)
return f"Successfully downloaded s3://{bucket}/{key} to {file_path}"7. MCP的最佳实践
7.1 Server开发最佳实践
7.1.1 错误处理
python
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
try:
# 验证参数
if "path" not in arguments:
return "Error: Missing required parameter 'path'"
# 执行操作
result = execute_tool(name, arguments)
return result
except FileNotFoundError as e:
return f"Error: File not found - {str(e)}"
except PermissionError as e:
return f"Error: Permission denied - {str(e)}"
except Exception as e:
return f"Error: {str(e)}"7.1.2 参数验证
python
from pydantic import BaseModel, ValidationError
class FileReadArgs(BaseModel):
path: str
class FileWriteArgs(BaseModel):
path: str
content: str
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
try:
if name == "file_read":
args = FileReadArgs(**arguments)
return read_file(args.path)
elif name == "file_write":
args = FileWriteArgs(**arguments)
return write_file(args.path, args.content)
except ValidationError as e:
return f"Error: Invalid arguments - {str(e)}"7.1.3 日志记录
python
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
logger.info(f"Calling tool {name} with arguments {arguments}")
try:
result = execute_tool(name, arguments)
logger.info(f"Tool {name} executed successfully")
return result
except Exception as e:
logger.error(f"Error executing tool {name}: {str(e)}")
return f"Error: {str(e)}"7.2 Client开发最佳实践
7.2.1 连接管理
python
class MCPClientManager:
def __init__(self):
self.clients = {}
async def connect(self, name: str, config: dict):
if name in self.clients:
return self.clients[name]
client = Client(name=name, version="1.0.0")
await client.connect(config.get("transport", "stdio"))
self.clients[name] = client
return client
async def disconnect(self, name: str):
if name in self.clients:
await self.clients[name].disconnect()
del self.clients[name]
async def disconnect_all(self):
for name in list(self.clients.keys()):
await self.disconnect(name)7.2.2 重试机制
python
import asyncio
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
async def call_tool_with_retry(client: Client, name: str, arguments: dict) -> str:
return await client.call_tool(name, arguments)7.2.3 缓存
python
from functools import lru_cache
class CachedMCPClient:
def __init__(self, client: Client):
self.client = client
self.cache = {}
@lru_cache(maxsize=100)
async def call_tool_cached(self, name: str, arguments: tuple) -> str:
return await self.client.call_tool(name, dict(arguments))
async def call_tool(self, name: str, arguments: dict) -> str:
# 将arguments转换为可哈希的tuple
args_tuple = tuple(sorted(arguments.items()))
return await self.call_tool_cached(name, args_tuple)实践任务
任务1:实现文件系统MCP Server
目标:实现一个文件系统MCP Server。
要求:
- 实现文件读写工具
- 实现文件列表工具
- 实现文件删除工具
- 实现文件资源
- 测试Server功能
代码框架:
python
from mcp.server import Server
from mcp.types import Tool, Resource
import os
# 创建Server
server = Server(
name="filesystem-server",
version="1.0.0"
)
# 定义工具
@server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="file_read",
description="Read a file from the filesystem",
inputSchema={
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file"
}
},
"required": ["path"]
}
),
# ... 其他工具
]
# 实现工具
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "file_read":
path = arguments.get("path")
try:
with open(path, 'r') as f:
return f.read()
except Exception as e:
return f"Error: {str(e)}"
# ... 其他工具
# 定义资源
@server.list_resources()
async def list_resources() -> list[Resource]:
resources = []
for root, dirs, files in os.walk("."):
for file in files:
path = os.path.join(root, file)
resources.append(
Resource(
uri=f"file://{path}",
name=file,
description=f"File: {path}",
mimeType="text/plain"
)
)
return resources
# 启动Server
if __name__ == "__main__":
import asyncio
asyncio.run(server.run())任务2:实现数据库MCP Server
目标:实现一个数据库MCP Server。
要求:
- 实现数据库查询工具
- 实现数据库执行工具
- 实现数据库schema工具
- 实现数据库资源
- 测试Server功能
代码框架:
python
from mcp.server import Server
from mcp.types import Tool, Resource
import sqlite3
# 创建Server
server = Server(
name="database-server",
version="1.0.0"
)
# 定义工具
@server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="database_query",
description="Execute a SQL query",
inputSchema={
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "SQL query to execute"
}
},
"required": ["sql"]
}
),
# ... 其他工具
]
# 实现工具
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> str:
if name == "database_query":
sql = arguments.get("sql")
try:
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
conn.close()
return str(results)
except Exception as e:
return f"Error: {str(e)}"
# ... 其他工具
# 启动Server
if __name__ == "__main__":
import asyncio
asyncio.run(server.run())任务3:集成到Claude Desktop
目标:将MCP Server集成到Claude Desktop。
要求:
- 实现一个MCP Server
- 配置Claude Desktop
- 测试工具调用
- 测试资源访问
- 测试提示使用
配置文件:
json
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["/path/to/my_server.py"]
}
}
}课后作业
作业1:MCP Server开发
题目:开发一个特定领域的MCP Server。
要求:
- 选择一个领域(如天气、新闻、股票等)
- 设计工具和资源
- 实现MCP Server
- 测试Server功能
- 集成到Claude Desktop
作业2:MCP Client开发
题目:开发一个MCP Client应用。
要求:
- 实现MCP Client
- 连接到多个Server
- 实现工具调用
- 实现资源访问
- 测试Client功能
作业3:MCP生态调研
题目:调研MCP生态。
要求:
- 调研现有的MCP Server
- 分析Server的功能和特点
- 比较不同Server的优劣
- 撰写2000字调研报告
参考资料
必读文献
Anthropic (2024). "Model Context Protocol (MCP) Specification".
- MCP协议规范
Anthropic (2024). "MCP Server Development Guide".
- MCP Server开发指南
Anthropic (2024). "MCP Client Development Guide".
- MCP Client开发指南
推荐阅读
JSON-RPC 2.0 Specification: https://www.jsonrpc.org/specification
- JSON-RPC 2.0规范
Claude Desktop Documentation: https://docs.anthropic.com/claude/docs/mcp
- Claude Desktop MCP文档
在线资源
MCP GitHub: https://github.com/modelcontextprotocol
- MCP GitHub组织
MCP Examples: https://github.com/modelcontextprotocol/servers
- MCP Server示例
MCP SDK: https://github.com/modelcontextprotocol/python-sdk
- MCP Python SDK
扩展阅读
MCP前沿
Anthropic (2024). "MCP Best Practices".
- MCP最佳实践
Community (2024). "MCP Server Showcase".
- MCP Server展示
协议设计
Fielding, R. T. (2000). "Architectural Styles and the Design of Network-based Software Architectures". PhD Dissertation.
- REST架构设计
W3C (2006). "Web Services Addressing (WS-Addressing)".
- Web服务协议
下节预告
下一节我们将学习Skills标准发布(2025年),了解Anthropic Skills标准的诞生背景、核心思想、文档驱动开发理念,以及它如何标准化AI能力的描述和发现。

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态
