
MCP是一种让大语言模型与现实工具、数据和服务的交互方式。
可以这样理解:
- 你通过HTTP公开一个Python函数
- 大语言模型按照定义好的输入格式调用你的接口
- 你的代码执行后返回响应,大语言模型继续推理
此时你就成了人工智能与现实世界之间循环的一部分。
⚙️ 使用 FastAPI 实现 MCP 服务器架构
创建支持大语言模型(LLM)查询的服务器,示例查询:
💬 "What's the weather in Paris?"
🔧 步骤 1:安装 FastAPI
bash
pip install fastapi uvicorn
🔧 步骤 2:实现服务端逻辑 (main.py)
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import requests
app = FastAPI()
# Models
class WeatherRequest(BaseModel):
city: str
class CryptoRequest(BaseModel):
token: str
class MovieRequest(BaseModel):
title: str
# Weather Endpoint using Open-Meteo (No API Key Required)
@app.post("/get-weather")
def get_weather(req: WeatherRequest):
geocode_url = f"<https://geocoding-api.open-meteo.com/v1/search?name={req.city}>"
geo_response = requests.get(geocode_url)
if geo_response.status_code != 200 or not geo_response.json().get("results"):
raise HTTPException(status_code=404, detail="City not found.")
location = geo_response.json()["results"][0]
latitude = location["latitude"]
longitude = location["longitude"]
weather_url = f"<https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true>"
weather_response = requests.get(weather_url)
if weather_response.status_code != 200:
raise HTTPException(status_code=500, detail="Weather data retrieval failed.")
weather_data = weather_response.json()["current_weather"]
return {
"city": req.city,
"temperature": weather_data["temperature"],
"windspeed": weather_data["windspeed"],
"weather_code": weather_data["weathercode"]
}
# Crypto Price Endpoint using CoinGecko (No API Key Required)
@app.post("/get-crypto-price")
def get_crypto_price(req: CryptoRequest):
token = req.token.lower()
price_url = f"<https://api.coingecko.com/api/v3/simple/price?ids={token}&vs_currencies=usd>"
price_response = requests.get(price_url)
if price_response.status_code != 200 or token not in price_response.json():
raise HTTPException(status_code=404, detail="Token not found.")
price = price_response.json()[token]["usd"]
return {
"token": req.token.upper(),
"price_usd": price
}
# Movie Info Endpoint using OMDb API (API Key Required)
@app.post("/get-movie-info")
def get_movie_info(req: MovieRequest):
api_key = "your_omdb_api_key" # Replace with your OMDb API key
movie_url = f"<http://www.omdbapi.com/?t={req.title}&apikey={api_key}>"
movie_response = requests.get(movie_url)
if movie_response.status_code != 200 or movie_response.json().get("Response") == "False":
raise HTTPException(status_code=404, detail="Movie not found.")
data = movie_response.json()
return {
"title": data.get("Title"),
"year": data.get("Year"),
"genre": data.get("Genre"),
"director": data.get("Director"),
"plot": data.get("Plot"),
"imdb_rating": data.get("imdbRating")
}
▶️ 步骤 3:启动服务
bash
uvicorn main:app --reload --host 0.0.0.0 --port 8000
现在MCP 服务器已启动运行,并提供以下接口:
POST /get-weather
POST /get-crypto-price
POST /get-movie-info
🔑 API 凭证管理
- Open-Meteo :无需凭证 Open-Meteo
- CoinGecko :免认证 CoinGecko API
- OMDb API :需免费API密钥 注册获取
🤖 OpenAI API 客户端实现
现在,让我们创建一个Python脚本,该脚本使用OpenAI的API来处理用户提示,并相应地与我们的MCP服务器进行交互。
🔧 安装依赖
bash
pip install openai requests
🔧 创建客户端脚本 (client.py)
python
import openai
import requests
openai.api_key = "your_openai_api_key" # Replace with your OpenAI API key
def get_response(prompt):
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are an assistant that routes user queries to appropriate APIs."},
{"role": "user", "content": prompt}
]
)
return response.choices[0].message["content"]
def main():
while True:
user_input = input("Ask a question (or type 'exit'): ")
if user_input.lower() == "exit":
break
response = get_response(user_input)
print(f"Response: {response}")
if __name__ == "__main__":
main()
**注意:**请将 "your_openai_api_key" 替换为你实际的OpenAI API密钥。你可以通过在OpenAI平台注册账户获取密钥。
该脚本接收用户输入,将其发送至OpenAI的API,并打印返回结果。如需与MCP服务器完全集成,需要实现以下逻辑:解析API返回的响应内容,并根据解析出的意图向MCP服务器相应的接口端点发起请求。
以下是需要添加的功能:
-
LLM解析用户意图
大语言模型分析用户输入的深层需求
-
解析LLM的回答以确定调用的MCP接口
通过解析LLR返回结果,明确需要调用的MCP端点(天气/加密货币/电影)
-
调用对应的MCP API
根据解析结果激活相应的MCP服务接口:
- 天气数据接口
- 加密货币行情接口
- 电影信息接口
-
将MCP响应注入最终输出
将MCP接口返回的数据整合到LLM的最终回复中
🧠 实现策略选项
主要有两种策略:
🔁选项 1:LLM 返回结构化命令,例如:
bash
{"action": "get_weather", "city": "Delhi"}
你可以在 Python 中解析这个 JSON,并据此调用 MCP。
🧠选项 2:使用 OpenAI 的 tool_calling
功能调用(推荐使用 GPT-4 或更高版本时采用)
不过现在,让我们使用选项 1(更简单,适用于纯文本输出解析):
🛠 修改后的 client.py 脚本(包含 MCP 集成功能)
python
import openai
import requests
import json
openai.api_key = "your_openai_api_key" # Replace with your key
MCP_BASE_URL = "<http://localhost:8000>" # Replace with actual server URL if deployed
def call_mcp(action, data):
if action == "get_weather":
response = requests.post(f"{MCP_BASE_URL}/get-weather", json={"city": data["city"]})
elif action == "get_crypto_price":
response = requests.post(f"{MCP_BASE_URL}/get-crypto-price", json={"token": data["token"]})
elif action == "get_movie_info":
response = requests.post(f"{MCP_BASE_URL}/get-movie-info", json={"title": data["title"]})
else:
return {"error": "Unknown action"}
return response.json()
def extract_action_response(prompt):
system_instruction = (
"You are an intelligent router. When a user asks something, reply ONLY with a JSON like:\\n"
'{"action": "get_weather", "city": "London"}\\n'
'or {"action": "get_crypto_price", "token": "bitcoin"}\\n'
'or {"action": "get_movie_info", "title": "Inception"}'
)
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": system_instruction},
{"role": "user", "content": prompt}
]
)
content = response.choices[0].message["content"]
try:
return json.loads(content)
except json.JSONDecodeError:
return {"error": "Could not parse intent."}
def main():
while True:
user_input = input("\\nAsk a question (or type 'exit'): ")
if user_input.lower() == "exit":
break
parsed = extract_action_response(user_input)
if "error" in parsed:
print("❌ Could not understand your intent.")
continue
mcp_result = call_mcp(parsed["action"], parsed)
print("✅ Response from MCP:", mcp_result)
# Final beautified answer using OpenAI + MCP result
final_response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "Use the following MCP data to craft a helpful human-readable answer."},
{"role": "user", "content": f"Prompt: {user_input}\\nMCP Result: {mcp_result}"}
]
)
print("\\n💡 Final Answer:", final_response.choices[0].message["content"])
if __name__ == "__main__":
main()
🧪 示例交互流程
bash
User: What's the weather in Bangalore?
→ GPT returns: {"action": "get_weather", "city": "Bangalore"}
→ MCP call made to /get-weather with Bangalore
→ GPT gets MCP result: {"temperature": 29.5, "windspeed": 10.2, ...}
→ Final GPT prompt: Prompt: What's the weather in Bangalore? MCP Result: {...}
→ Final Answer: The current temperature in Bangalore is 29.5°C with a windspeed of 10.2 km/h.
MCP 天气接口URL:
bash
<http://localhost:8000/get-weather>
可以使用以下命令测试:
bash
curl -X POST <http://localhost:8000/get-weather> \\
-H "Content-Type: application/json" \\
-d '{"city": "London"}'
🔁添加更多 MCP 工具(接口)
📈加密货币价格查询器
python
@app.get("/price")
def get_price(token: str = "BTC"):
# You could integrate a real crypto API here
return {"token": token.upper(), "price_usd": "45210.75"}
调用方式:
bash
GET /price?token=eth
📅 简单日期格式化器
python
@app.post("/format-date")
def format_date(payload: dict):
from datetime import datetime
raw_date = payload.get("date", "")
try:
parsed = datetime.fromisoformat(raw_date)
return {"formatted": parsed.strftime("%B %d, %Y")}
except:
return {"error": "Invalid date format"}
🌍将其公开化
为了让像 Claude 这样的 AI 智能体也能使用你的工具:
🔹使用 Ngrok(用于快速测试)
bash
ngrok http 8000
Ngrok 会给你一个公共 URL,例如:
bash
<https://abc123.ngrok.io/get-weather>
你可以将这个 URL 注册到支持工具调用功能的 LLM 中(如 OpenAI 的函数调用或 Claude 的工具使用)。
💡 5 个你可以构建的简单 MCP 服务器工具
工具想法 | 端点 (Endpoint) | 输入 (Input) | 功能描述 |
---|---|---|---|
📍 时区查询 | /get-timezone |
{"city": "Tokyo"} |
返回当地时间 |
📦 包裹追踪 | /track-package |
{"carrier": "UPS", "tracking_id": "1Z..."} |
获取包裹状态 |
🔐 密码生成器 | /generate-password |
{"length": 12} |
生成高强度密码 |
✨ Markdown转HTML | /md-to-html |
{"markdown": "# Hello"} |
将 Markdown 转换为 HTML |
🎬 电影信息查询 | /movie-info |
{"title": "Inception"} |
获取剧情简介、评分等信息 |
🔐 想收费访问?
用 Stripe 实现起来非常简单:
- 为API端点添加付费访问控制
- 生成访问令牌 (
access tokens
) - 只需几个装饰器 (
decorators
) 即可添加用户认证
🔚 最后感想
构建 MCP 服务器不仅仅是为了追赶 AI 热潮------它关乎掌控权。
✅ 你定义你的 AI 智能体能做什么。
✅ 你选择它获取什么数据。
✅ 你决定如何以及在哪里部署它。
✅ 而且你可以做到这一切,无需复制任何其他人的技术栈。