掌控AI工具链:用 Python + API 构建 AI MCP 服务器

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}&current_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 凭证管理

🤖 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服务器相应的接口端点发起请求。

以下是需要添加的功能:

  1. LLM解析用户意图

    大语言模型分析用户输入的深层需求

  2. 解析LLM的回答以确定调用的MCP接口

    通过解析LLR返回结果,明确需要调用的MCP端点(天气/加密货币/电影)

  3. 调用对应的MCP API

    根据解析结果激活相应的MCP服务接口:

    • 天气数据接口
    • 加密货币行情接口
    • 电影信息接口
  4. 将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 智能体能做什么。

你选择它获取什么数据。

你决定如何以及在哪里部署它。

✅ 而且你可以做到这一切,无需复制任何其他人的技术栈。

相关推荐
点云SLAM5 分钟前
Eigen 中矩阵的拼接(Concatenation)与 分块(Block Access)操作使用详解和示例演示
人工智能·线性代数·算法·矩阵·eigen数学工具库·矩阵分块操作·矩阵拼接操作
木枷1 小时前
NAS-Bench-101: Towards Reproducible Neural Architecture Search
人工智能·物联网
BAOYUCompany2 小时前
暴雨服务器更懂人工智能+
运维·服务器·人工智能
飞哥数智坊2 小时前
Coze实战第17讲:工资条自动拆分+一对一邮件发送
人工智能·coze
cwn_2 小时前
自然语言处理NLP (1)
人工智能·深度学习·机器学习·自然语言处理
点云SLAM2 小时前
PyTorch中flatten()函数详解以及与view()和 reshape()的对比和实战代码示例
人工智能·pytorch·python·计算机视觉·3d深度学习·张量flatten操作·张量数据结构
智海观潮2 小时前
Unity Catalog与Apache Iceberg如何重塑Data+AI时代的企业数据架构
大数据·人工智能·ai·iceberg·catalog
爱分享的飘哥2 小时前
第三篇:VAE架构详解与PyTorch实现:从零构建AI的“视觉压缩引擎”
人工智能·pytorch·python·aigc·教程·生成模型·代码实战
柏峰电子3 小时前
市政道路积水监测系统:守护城市雨天出行安全的 “智慧防线”
大数据·人工智能·安全
蓑雨春归3 小时前
自主智能Agent如何重塑工作流自动化:技术、经济与未来展望
人工智能·chatgpt·自动化