一、MCP是什么
MCP(Model Calling Protocol) 是一种模型与工具之间通信的标准协议。它允许模型根据任务需求动态调用外部工具(如 API、数据库等),从而增强模型能力。
在这个项目中,我们创建了一个例子 MCP Server,提供图书座位相关的服务能力,供 AI 模型或客户端调用。
二、什么是FastMCP?
FastMCP 是一个基于MCP协议构建的快速开发框架,旨在简化创建高效、可扩展的服务端程序的过程。它封装了许多底层细节,使得开发者可以专注于业务逻辑的实现,而不需要过多关心网络通信、并发控制等方面的问题。
易用性:提供了简洁的API接口,易于上手。
高性能:优化了性能,适合高并发场景。
扩展性强:支持自定义配置和服务功能扩展。
三、先给代码,在做讲解
import json
import requests
from datetime import datetime
from typing import Optional
from mcp.server.fastmcp import FastMCP
# 初始化MCP服务
mcp = FastMCP("LibrarySeatService",
description=f"图书馆座位服务启动时间:{datetime.now().strftime('%Y-%m-%d %H:%M')}",
port=8082)
# 后端API基础地址
API_BASE = "http://library-api.example.com/seat"
@mcp.tool()
async def query_available_seats(
building: str,
date: str,
time_range: str,
floor: Optional[str] = None,
seat_type: Optional[str] = None,
token: Optional[str] = None
) -> str:
"""
查询可用座位信息
:param building: 楼栋名称(如:A栋)
:param date: 查询日期(格式:YYYY-MM-DD)
:param time_range: 时间段(格式:HH:mm~HH:mm)
:param floor: 楼层(可选,如:3楼)
:param seat_type: 座位类型(如:普通座、VIP座)
:param token: 用户身份令牌
:return: JSON 字符串表示的空闲座位列表
"""
params = {
"building": building,
"date": date,
"timeRange": time_range,
"floor": floor,
"seatType": seat_type
}
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(f"{API_BASE}/available", headers=headers, params=params)
return format_response(response)
@mcp.tool()
async def book_seat(
seat_id: str,
date: str,
time_range: str,
student_name: str,
contact: str,
token: Optional[str] = None
) -> str:
"""
预约指定座位
:param seat_id: 座位唯一标识(如:S12345)
:param date: 预约日期
:param time_range: 使用时间段
:param student_name: 学生姓名
:param contact: 联系方式
:param token: 用户身份令牌
:return: 是否预约成功
"""
data = {
"seatId": seat_id,
"date": date,
"timeRange": time_range,
"studentName": student_name,
"contact": contact
}
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.post(f"{API_BASE}/book", headers=headers, json=data)
return format_response(response, success_key="bookingId")
@mcp.tool()
async def get_my_bookings(
token: Optional[str] = None
) -> str:
"""
获取用户当前预约记录
:param token: 用户身份令牌
:return: 当前用户的预约记录列表
"""
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(f"{API_BASE}/my-bookings", headers=headers)
return format_response(response)
def format_response(response, success_key=None):
"""
标准化响应处理函数
"""
if response.status_code == 200:
data = response.json()
if success_key and success_key in data:
return json.dumps({"status": "success", "data": data}, ensure_ascii=False)
elif isinstance(data, list) or isinstance(data, dict):
return json.dumps({"status": "success", "data": data}, ensure_ascii=False)
else:
return json.dumps({"status": "error", "message": "未找到有效数据"}, ensure_ascii=False)
return json.dumps({
"status": "error",
"code": response.status_code,
"message": response.text
}, ensure_ascii=False)
if __name__ == "__main__":
mcp.run(transport="sse")
四、核心代码解析
1. 初始化MCP服务
mcp = FastMCP("LibrarySeatService",
description="...",
port=8082)
- 创建名为 LibrarySeatService 的服务实例。
- 设置服务端口号为 8082。
这里有几个关键点需要注意:
名称和服务描述:为服务命名并提供简短描述有助于理解和维护。
端口号:指定服务监听的端口,默认情况下是公开访问的(host="0.0.0.0"),这使得该服务可以从任何地方访问。
此外,通过装饰器 @mcp.tool() 定义了一系列工具函数(如 query_available_seats, book_seat, get_my_bookings),这些函数实际上是对后端API的具体调用逻辑进行了封装。每个工具函数都代表了一种服务能力,客户端可以通过MCP协议调用这些服务。
2. 定义工具函数(Tool Function)
a. 查询空闲座位
@mcp.tool()
async def query_available_seats(...)
- 调用 /available 接口,传入楼宇、日期、时间段等参数。
- 返回空闲座位列表。
b. 预约座位
@mcp.tool()
async def book_seat(...)
- 调用 /book 接口提交预约请求。
- 包含座位ID、时间、学生信息。
c. 查询个人预约记录
@mcp.tool()
async def get_my_bookings(...)
- 调用 /my-bookings 接口,获取当前用户的所有预约。
3. 响应格式标准化处理
def format_response(response, success_key=None)
统一处理HTTP响应,返回标准JSON格式。
支持错误码处理、字段匹配校验。
五、服务启动方式
if __name__ == "__main__":
mcp.run(transport="sse")
使用 SSE(Server-Sent Events)作为传输协议。
可扩展支持HTTPS、并发配置等生产级设置。