FastMCP与FastAPI:构建自界说MCP服务器 [复制链接]
发表于 2025-9-21 21:37:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
FastMCP与FastAPI:构建自界说MCP服务器

模子上下文协议(Model Context Protocol, MCP)是一种让AI模子与外部工具和服务交互的标准。本文将先容FastMCP和FastAPI,并通过实例展示怎样创建自界说MCP服务器
MCP基础概念

MCP答应语言模子:

  • 访问外部工具和API
  • 执行实时计算和查询
  • 与文件体系和服务交互
简朴来说,MCP让AI模子能"走出"对话框,调用各种功能
FastMCP先容

FastMCP是一个Python库,简化了MCP服务器的构建。它提供了:

  • 易用的装饰器语法
  • 自动处置惩罚哀求/相应
  • 参数验证和错误处置惩罚
FastAPI先容

FastAPI是一个当代Web框架,用于构建API:

  • 性能(基于ASGI)
  • 自动天生交互式文档
  • 数据验证和序列化
  • 基于Python范例提示
FastMCP与FastAPI的联合

二者联合的优势:

  • FastAPI提供了Web服务器基础架构
  • FastMCP添加了模子交互能力
  • 共享相似的装饰器语法和范例体系
自界说MCP服务器示例
  1. # 示例1:基础计算器服务器
  2. from fastmcp import MCPServer, Request
  3. from fastapi import FastAPI
  4. from pydantic import BaseModel
  5. app = FastAPI()
  6. mcp_server = MCPServer(app)
  7. class CalculationRequest(BaseModel):
  8.     x: float
  9.     y: float
  10. @mcp_server.mcp_endpoint
  11. async def add(request: Request[CalculationRequest]) -> float:
  12.     """将两个数字相加"""
  13.     data = request.params
  14.     return data.x + data.y
  15. @mcp_server.mcp_endpoint
  16. async def subtract(request: Request[CalculationRequest]) -> float:
  17.     """从第一个数字中减去第二个数字"""
  18.     data = request.params
  19.     return data.x - data.y
  20. @mcp_server.mcp_endpoint
  21. async def multiply(request: Request[CalculationRequest]) -> float:
  22.     """将两个数字相乘"""
  23.     data = request.params
  24.     return data.x * data.y
  25. @mcp_server.mcp_endpoint
  26. async def divide(request: Request[CalculationRequest]) -> float:
  27.     """将第一个数字除以第二个数字"""
  28.     data = request.params
  29.     if data.y == 0:
  30.         raise ValueError("除数不能为零")
  31.     return data.x / data.y
  32. if __name__ == "__main__":
  33.     import uvicorn
  34.     uvicorn.run(app, host="0.0.0.0", port=8000)
  35. # 示例2:天气信息服务器
  36. from fastmcp import MCPServer, Request
  37. from fastapi import FastAPI
  38. from pydantic import BaseModel
  39. import random
  40. from datetime import datetime, timedelta
  41. app = FastAPI()
  42. mcp_server = MCPServer(app)
  43. class WeatherRequest(BaseModel):
  44.     city: str
  45.     days: int = 1
  46. class WeatherInfo(BaseModel):
  47.     date: str
  48.     temperature: float
  49.     condition: str
  50.     humidity: int
  51. @mcp_server.mcp_endpoint
  52. async def get_weather(request: Request[WeatherRequest]) -> list[WeatherInfo]:
  53.     """获取指定城市的天气预报"""
  54.     data = request.params
  55.    
  56.     # 这里使用模拟数据,实际应用中会调用真实的天气API
  57.     weather_conditions = ["晴朗", "多云", "小雨", "大雨", "雷雨", "小雪"]
  58.    
  59.     result = []
  60.     today = datetime.now()
  61.    
  62.     for i in range(data.days):
  63.         date = today + timedelta(days=i)
  64.         result.append(WeatherInfo(
  65.             date=date.strftime("%Y-%m-%d"),
  66.             temperature=round(random.uniform(15, 30), 1),
  67.             condition=random.choice(weather_conditions),
  68.             humidity=random.randint(30, 90)
  69.         ))
  70.    
  71.     return result
  72. if __name__ == "__main__":
  73.     import uvicorn
  74.     uvicorn.run(app, host="0.0.0.0", port=8001)
  75. # 示例3:文件操作服务器
  76. from fastmcp import MCPServer, Request
  77. from fastapi import FastAPI
  78. from pydantic import BaseModel
  79. import os
  80. import json
  81. app = FastAPI()
  82. mcp_server = MCPServer(app)
  83. # 模拟文件系统(实际应用中使用真实文件系统)
  84. file_system = {}
  85. class FileWriteRequest(BaseModel):
  86.     filename: str
  87.     content: str
  88. class FileReadRequest(BaseModel):
  89.     filename: str
  90. class FileListRequest(BaseModel):
  91.     directory: str = "/"
  92. class FileDeleteRequest(BaseModel):
  93.     filename: str
  94. @mcp_server.mcp_endpoint
  95. async def write_file(request: Request[FileWriteRequest]) -> bool:
  96.     """将内容写入文件"""
  97.     data = request.params
  98.     file_system[data.filename] = data.content
  99.     return True
  100. @mcp_server.mcp_endpoint
  101. async def read_file(request: Request[FileReadRequest]) -> str:
  102.     """读取文件内容"""
  103.     data = request.params
  104.     if data.filename not in file_system:
  105.         raise ValueError(f"文件 {data.filename} 不存在")
  106.     return file_system[data.filename]
  107. @mcp_server.mcp_endpoint
  108. async def list_files(request: Request[FileListRequest]) -> list[str]:
  109.     """列出指定目录中的文件"""
  110.     return list(file_system.keys())
  111. @mcp_server.mcp_endpoint
  112. async def delete_file(request: Request[FileDeleteRequest]) -> bool:
  113.     """删除文件"""
  114.     data = request.params
  115.     if data.filename not in file_system:
  116.         raise ValueError(f"文件 {data.filename} 不存在")
  117.     del file_system[data.filename]
  118.     return True
  119. if __name__ == "__main__":
  120.     import uvicorn
  121.     uvicorn.run(app, host="0.0.0.0", port=8002)
  122. # 示例4:综合应用 - 个人助手服务
  123. from fastmcp import MCPServer, Request
  124. from fastapi import FastAPI
  125. from pydantic import BaseModel
  126. from datetime import datetime
  127. import json
  128. import random
  129. app = FastAPI()
  130. mcp_server = MCPServer(app)
  131. # 模拟数据存储
  132. notes_db = []
  133. todos_db = []
  134. contacts_db = []
  135. class Note(BaseModel):
  136.     id: int = None
  137.     title: str
  138.     content: str
  139.     created_at: str = None
  140. class Todo(BaseModel):
  141.     id: int = None
  142.     task: str
  143.     completed: bool = False
  144.     due_date: str = None
  145. class Contact(BaseModel):
  146.     id: int = None
  147.     name: str
  148.     phone: str
  149.     email: str = None
  150. class SearchRequest(BaseModel):
  151.     query: str
  152. @mcp_server.mcp_endpoint
  153. async def add_note(request: Request[Note]) -> Note:
  154.     """添加一条笔记"""
  155.     note = request.params
  156.     note.id = len(notes_db) + 1
  157.     note.created_at = datetime.now().isoformat()
  158.     notes_db.append(note)
  159.     return note
  160. @mcp_server.mcp_endpoint
  161. async def get_notes(request: Request) -> list[Note]:
  162.     """获取所有笔记"""
  163.     return notes_db
  164. @mcp_server.mcp_endpoint
  165. async def add_todo(request: Request[Todo]) -> Todo:
  166.     """添加一个待办事项"""
  167.     todo = request.params
  168.     todo.id = len(todos_db) + 1
  169.     if not todo.due_date:
  170.         todo.due_date = (datetime.now() + timedelta(days=1)).isoformat()
  171.     todos_db.append(todo)
  172.     return todo
  173. @mcp_server.mcp_endpoint
  174. async def get_todos(request: Request) -> list[Todo]:
  175.     """获取所有待办事项"""
  176.     return todos_db
  177. @mcp_server.mcp_endpoint
  178. async def complete_todo(request: Request[int]) -> Todo:
  179.     """标记待办事项为已完成"""
  180.     todo_id = request.params
  181.     for todo in todos_db:
  182.         if todo.id == todo_id:
  183.             todo.completed = True
  184.             return todo
  185.     raise ValueError(f"待办事项 #{todo_id} 不存在")
  186. @mcp_server.mcp_endpoint
  187. async def add_contact(request: Request[Contact]) -> Contact:
  188.     """添加联系人"""
  189.     contact = request.params
  190.     contact.id = len(contacts_db) + 1
  191.     contacts_db.append(contact)
  192.     return contact
  193. @mcp_server.mcp_endpoint
  194. async def get_contacts(request: Request) -> list[Contact]:
  195.     """获取所有联系人"""
  196.     return contacts_db
  197. @mcp_server.mcp_endpoint
  198. async def search(request: Request[SearchRequest]) -> dict:
  199.     """搜索笔记、待办事项和联系人"""
  200.     query = request.params.query.lower()
  201.    
  202.     matching_notes = [note for note in notes_db if query in note.title.lower() or query in note.content.lower()]
  203.     matching_todos = [todo for todo in todos_db if query in todo.task.lower()]
  204.     matching_contacts = [contact for contact in contacts_db if query in contact.name.lower()]
  205.    
  206.     return {
  207.         "notes": matching_notes,
  208.         "todos": matching_todos,
  209.         "contacts": matching_contacts
  210.     }
  211. if __name__ == "__main__":
  212.     import uvicorn
  213.     uvicorn.run(app, host="0.0.0.0", port=8003)
复制代码
小白指南:逐步明白

1. 什么是MCP?

想象你的AI助手(如ChatGPT)是一个智慧的专家,但被关在一个房间里,只能通过纸条与外界互换。MCP就像是给这个专家配备了一部电话,让它能打电话给各种服务:查天气、计算数学标题、管理你的日程等。
2. FastMCP和FastAPI的脚色


  • FastAPI:提供电话线路和基础办法
  • FastMCP:界说通话协议,确保AI能准确拨号和明白复兴
3. 搭建MCP服务器的步骤


  • 安装须要的库:
    1. pip install fastmcp fastapi uvicorn
    复制代码
  • 创建服务器框架:
    1. from fastmcp import MCPServer
    2. from fastapi import FastAPI
    3. app = FastAPI()
    4. mcp_server = MCPServer(app)
    复制代码
  • 界说数据模子(哀求和相应的结构)
  • 建立功能端点(用@mcp_server.mcp_endpoint装饰器)
  • 启动服务器:
    1. import uvicorn
    2. uvicorn.run(app, host="0.0.0.0", port=8000)
    复制代码
现实应用场景


  • 数据分析助手:毗连数据处置惩罚工具
  • 客户服务呆板人:访问CRM体系和知识库
  • 智能文档助手:处置惩罚和天生各类文档
  • 个人生产力工具:管理日程、条记和待服务项
最佳实践


  • 明白界说数据模子:利用Pydantic确保输入输出格式准确
  • 添加具体文档:每个端点都应有清楚的形貌
  • 实现错误处置惩罚:优雅处置惩罚异常环境
  • 利用异步功能:充分利用FastAPI的异步特性
  • 添加验证和安全步调:掩护服务器不受恶意哀求攻击
结语

FastMCP和FastAPI的联合为AI模子提供了强大的扩展能力。通过本文先容的示例,纵然是编程新手也能构建自己的MCP服务器,让AI助手拥有更多实勤劳能。随着MCP生态体系的发展,我们可以等候更多创新应用的出现。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表