MCP 是一种通信协议。它允许一个 AI 应用程序(“客户端”)在一次调用(“推理”)中访问另一个应用程序(“服务器”)。在 MCP 出现之前,这个过程需要至少两个步骤,即“客户端”应用程序首先访问“服务器”,获取结果,然后再进行 AI 调用。
MCP 由 Anthropic 创建,并于 2024年11月25日 宣布。自那时起,它获得了广泛的认可,并被竞争对手如 OpenAI 和 Google 以及框架如 Langchain 等采用。
让我们通过代码来看看它是如何工作的。在这个文本中,我们将使用 OpenAI 的框架,因为它是最受欢迎的之一,但同样的逻辑也适用于其他许多框架。
一个 AI 调用(“推理”)如下所示:
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt-5-nano",
input="当前 NVDA 股票的价格是多少?"
)
print(response.output_text)
(参见 exemplo_01.ipynb)
显然,上述脚本不会返回股票价格,因为模型无法访问请求的股票当前价格。
在 MCP 之前,需要分两步完成此查询。下面的脚本查询了 Alpha Vantage 服务,执行了一个 request,然后将结果注入到 AI 调用的提示中(要获取 Alpha Vantage 的 API 密钥,请点击 这里。免费版每天允许 25 次调用)。
from openai import OpenAI
import os
import requests
url = f"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=NVDA&apikey={os.getenv('ALPHAVANTAGE_API_KEY')}"
r = requests.get(url)
data = r.json()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt- 5-nano",
input=f"当前 NVDA 股票的价格是多少?{data}"
)
print(response.output_text)
(参见 exemplo_02.ipynb)
而在下面的例子中,脚本使用了 MCP,而不是 Alpha Vantage 的 API,将参数直接包含在 AI 调用中,从而将过程简化为一步。
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt-5-nano",
input="当前 NVDA 股票的价格是多少?",
tools=[
{
"type": "mcp",
"server_label": "alphavantage",
"server_url": f"https://mcp.alphavantage.co/mcp?apikey={os.getenv('ALPHAVANTAGE_API_KEY')}",
"require_approval": "never"
}
]
)
print(response.output_text)
(参见 exemplo_03.ipynb)
Postman 现在也支持 MCP。也就是说,除了用于测试 API 端点外,它还可以连接到 MCP 服务器进行测试。
为此,请点击“File” > “New”,并选择“MCP”选项。然后只需提供 MCP 的端点。
对于远程 MCP 服务器,选择“HTTP”类型;对于本地 MCP 服务器,选择“STDIO”。稍后会详细介绍本地 MCP 服务器,因为前面提到的例子都是处理远程服务器的。
到目前为止,我们已经看到了如何消费 MCP,即看到了客户端的代码。现在我们将看到服务器端的代码,即创建一个 MCP 服务器。为此,我们将使用一个流行的框架,FastMCP。
在开始之前,重要的是要解释一下 1.0 版和 2.0 版的区别。FastMCP 在 2024 年率先实现了 Python 中的 MCP 服务器,因此 1.0 版被纳入了 官方 SDK。这里展示的是 2.0 版,它包含了比 1.0 版更多的功能。
一个简单的 MCP 服务器代码如下:
from fastmcp import FastMCP
import os
import requests
mcp = FastMCP("Teste")
@mcp.tool
def cotacao(ticker: str) -> float:
"""返回给定股票代码(ticker)的报价"""
url = f"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={ticker}&apikey={os.getenv('ALPHAVANTAGE_API_KEY')}"
r = requests.get(url)
data = r.json()
return float(data["Global Quote"]["05. price"])
if __name__ == "__main__":
mcp.run(transport="http", port=8000)
(参见 exemplo_04.ipynb)
请注意,这与“FastAPI”的语法相似,函数前有一个“装饰器”@mcp.tool。
运行此脚本时,将在指定的端口上创建一个本地服务器,例如 http://127.0.0.1:8000。
该地址可以在 Postman 中进行初步测试(如前所述,在地址末尾添加 /mcp)。
Postman 可以无问题地连接到 http://127.0.0.1:8000/mcp 地址。
然而,这个地址在 OpenAI 的 responses 调用中不起作用,会出现以下错误:
Error retrieving tool list from MCP server: 'alphavantage'. Http status code: 424 (Failed Dependency)
这是因为 responses 执行的 MCP 服务器是在 OpenAI 的远程环境中运行的,显然它无法访问本地主机。需要将此代码发布到一个服务器(例如 Docker 容器)并在此调用中使用该地址。
然而,为了测试目的,可以使用 Ngrok 创建一个“隧道”。这是一个免费资源,安装后只需在另一会话中运行以下命令:
ngrok http 8000
它将生成一个 Web 端点,例如 https://a092444f0de5.ngrok-free.app。
下面是客户端脚本的样子:
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt-5-nano",
input="当前 NVDA 股票的价格是多少?",
tools=[
{
"type": "mcp",
"server_label": "cotacao",
"server_url": "https://a092444f0de5.ngrok-free.app/mcp",
"require_approval": "never"
}
]
)
print(response.output_text)
(参见 exemplo_05.ipynb)
可以实现认证协议。FastMCP 提供了许多 功能,以下脚本是最 简单的:
from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import StaticTokenVerifier
mcp = FastMCP("Teste")
verifier = StaticTokenVerifier(
tokens={
"tk-abcdef123456": {
"client_id": "lorem_ipsum"
}
},
)
mcp = FastMCP(name="Teste", auth=verifier, stateless_http=True)
@mcp.tool
def cotacao(ticker: str) -> float:
"""返回给定股票代码(ticker)的报价"""
return 250.00 # 示例中的固定值
if __name__ == "__main__":
mcp.run(transport="http", port=8000)
(参见 exemplo_06.ipynb)
要在 Postman 中测试此服务器,需要在“Headers”中包括:
Authorization | Bearer tk-abcdef123456
在 responses 中,脚本如下:
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt-5-nano",
input="当前 NVDA 股票的价格是多少?",
tools=[
{
"type": "mcp",
"server_label": "cotacao",
"server_url": "https://a092444f0de5.ngrok-free.app/mcp",
"require_approval": "never",
"headers": {
"Authorization": "Bearer tk-abcdef123456"
}
}
]
)
print(response.output_text)
(参见 exemplo_07.ipynb)
我们展示了如何使用 FastMCP 运行本地服务器以及如何使用 Ngrok 进行连接。
还有许多现成的 MCP 服务器可供下载并在本地运行。MCP Servers 提供了大量的此类服务器,不仅有 Python 编写的,还有其他语言如 Node.js 编写的。因此,可以下载这些代码,在本地运行,并使用 Ngrok 创建“隧道”,就像我们对 FastMCP 做的一样。
在下面的例子中,我们将首先下载并运行 Playwright 的 MCP,这是一个著名的网页抓取框架。为此,只需执行以下命令(需要在机器上安装 Node):
npx @playwright/mcp@latest --port 8931
就这样!现在可以在 Postman 中通过地址 http://localhost:8931/sse 进行测试。
要创建 Ngrok 的“隧道”,需要传递额外的指令:
ngrok http --host-header=rewrite 8931
客户端脚本如下:
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.responses.create(
model="gpt-5-nano",
input="当前 NVDA 股票的价格是多少?",
tools=[
{
"type": "mcp",
"server_label": "playwright",
"server_url": "https://a092444f0de5.ngrok-free.app/sse",
"require_approval": "never"
}
]
)
print(response.output_text)
(参见 exemplo_08.ipynb)
正如预期的那样,MCP 服务器正在呈指数级增长,类似于网站的现象。
为管理这种多样性的 MCP 服务器,出现了 MCP 网关解决方案。
我专门建立了一个关于 MCP 网关的仓库。点击 这里 访问。
到目前为止,我们展示了如何使用 OpenAI 的 responses 访问 MCP 服务器。然而,还有许多其他方式可以访问 MCP 服务器。
下面的脚本展示了如何访问 MCP 服务器(在这种情况下是 exemplo_04.py):
import asyncio
from fastmcp import Client
client = Client("http://localhost:8000/mcp")
async def main():
async with client:
result = await client.call_tool("cotacao", {"ticker": "NVDA"})
print(result)
await main()
(参见 exemplo_09.ipynb)
几乎所有的 IDE(集成开发环境)都创建了连接 MCP 的资源。其主要用途是让程序员能够在更专业的上下文中与开发代理(“vibe coding”)互动。例如,可以在 VS Code 中安装一个 MySQL 的 MCP,并使用自然语言与数据库表进行交互。程序员无需离开 IDE 就可以解决关于表名、列名等问题。
有许多 MCP 服务器供程序员使用,如 GitHub、Postgres、Jira 等。访问这些服务器的方式各不相同,有些是远程的(有 URL),有些则需要下载并本地安装。
像 ChatGPT、Claude 等机器人,在它们的“客户端”版本(已下载)中可以连接到 MCP 服务器,无论是远程还是本地。因此,可以创建一个 MCP 服务器,并允许人们使用他们自己的聊天机器人与其互动。这创造了一种新的编程范式,应用程序可以没有前端界面。只需开发 MCP 服务器,人们就可以使用聊天机器人作为前端,以自然语言进行交互。
使用 OpenAI API 开发 MCP 客户端时需要注意两点:
responses 支持 MCP。不能使用 chat.completion 或 assistants。responses 只支持“工具”。MCP 协议还包括“资源”和“提示”,但不能与 responses 一起使用。MCP 服务器,正如其名称所示(“模型上下文协议”),旨在为 AI 调用增加更多上下文。也就是说,它们是从“读取”视角设计的,即从特定服务中读取数据并将其添加到 LLM 的上下文中。
然而,MCP 服务器也可以从“写入”视角设计。它们可以例如将数据写入数据库,修改记录,移动资源,并执行任何类型的行动,根据程序员的意愿。
一个 MCP 服务器还可以执行另一个 AI 代理。也就是说,一个 AI 代理可以通过 MCP 分发给其他 AI 代理使用。
这些视角远远超出了简单地增加上下文,允许高度复杂和高级的使用场景。
https://docs.claude.com/en/docs/agents-and-tools/remote-mcp-servers
https://github.com/modelcontextprotocol/servers