OpenAPI MCP服务器
- 脚手架 - 快速开始 - 小心 - VSCode - 配置 - 什么是MCP服务器? - 架构图 - 它是如何工作的(上图) - 深入 - 1.命名工具 - 2.取消提及 $ref 指针 - 3. serve 对比 chat --每种模式的实际作用是什么 - 聊天模式流程 - 4.“MCP服务器注册这些工具”——哪些工具? - 5.stdio是什么? - 6. list_tools 和 call_tool --两条MCP消息 - 光标作为MCP客户端 - 步骤1——创建配置文件 - 步骤2--重新启动Cursor - 步骤3--在Cursor聊天中使用它 - 到底发生了什么 - 小心 - 你什么时候运行每个命令?
暴露 任何REST API (由OpenAPI 3.x规范描述)作为MCP服务器, 因此任何兼容MCP的LLM客户端(Claude Desktop等)都可以将其称为工具。
支持 奥拉玛 (当地)和 谷歌双子星 作为LLM后端。
脚手架
ai-dev-openapi-mcp-server/
├── pyproject.toml ← uv-compatible, src layout
├── .env.example ← all config options documented
├── README.md
├── claude_desktop_config.example.json
├── src/openapi_mcp_server/
│ ├── cli.py ← typer CLI (serve / chat / list-tools)
│ ├── server.py ← MCP server + agentic loop
│ ├── spec_loader.py ← loads & dereferences any OpenAPI spec
│ ├── api_client.py ← async httpx REST caller
│ └── llm_backends.py ← Ollama + Gemini, swappable factory
└── tests/
└── test_spec_loader.py快速开始
# Install dependencies and create .venv folder
uv sync
# Serve mode
# ----------------------------------------------------
# Run with remote OpenAPI spec
uv run openapi-mcp serve --spec https://petstore3.swagger.io/api/v3/openapi.json \
# Run with local OpenAPI spec
uv run openapi-mcp serve --spec ./my-api.yaml \
# Or use a .env file
cp .env.example .env # fill in values
uv run openapi-mcp serve --spec ./my-api.yaml
# Chat mode
# ----------------------------------------------------
uv run openapi-mcp chat \
--spec https://petstore3.swagger.io/api/v3/openapi.json \
--llm ollama --ollama-model llama3.1:8b小心
LLM的原因是谁作为MCP客户端(Cursor、Claude Desktop等)连接, 不是你的服务器.
VSCode
VSCode扩展:
ms-python.python:微软官方扩展。处理智能感知、调试、测试发现和环境选择。ms-python.vscode-pylance:支持类型检查和自动补全的语言服务器。通常会自动安装Python扩展,但值得确认它是否处于活动状态。charliermarsh.ruff:linter和格式化器,用Rust编写,速度极快。tamasfe.even-better-toml:pyproject.toml的语法高亮显示和验证,这是uv存储其所有配置的地方。
编辑 settings.json:
{
"python.defaultInterpreterPath": ".venv/bin/python",
"python.terminal.activateEnvironment": true,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
}由于紫外线会产生 .venv 默认情况下,文件夹为 uv venv 或 uv sync,当您打开项目时,VS Code会自动拾取它,不需要扩展。
这为您在保存时提供了自动格式化和自动导入排序功能 Ruff,与 uv 管理下面的环境。
配置
所有选项都可以通过CLI标志进行设置 或 一 .env 文件:
| Env-var | CLI标志 | 描述 |
|---|---|---|
OPENAPI_SPEC | --spec | OpenAPI JSON/YAML的URL或路径 |
LLM_BACKEND | --llm | ollama 或 gemini |
OLLAMA_BASE_URL | --ollama-url | 默认值 http://localhost:11434 |
OLLAMA_MODEL | --ollama-model | 默认值 llama3.2 |
GEMINI_API_KEY | --gemini-key | 您的Google Gemini API密钥 |
GEMINI_MODEL | --gemini-model | 默认值 gemini-1.5-flash |
API_BASE_URL | --api-base | 覆盖API基础URL |
API_KEY | --api-key | 目标API的承载令牌 |
MCP_HOST | --host | MCP服务器主机(默认 127.0.0.1) |
MCP_PORT | --port | MCP服务器端口(默认 8765) |
什么是MCP服务器?
MCP(模型上下文协议)服务器是一种小型服务,它使用标准协议(基于stdio的JSON或HTTP)向LLM客户端公开具有类型输入的命名函数工具。LLM决定何时调用工具以及传递什么参数;MCP服务器处理实际执行。这干净利落地分开了 _“模型思考”_ 从 _“模范行为”_.
将其视为AI插件的USB-C标准:一种协议,任何工具。
架构图
它是如何工作的(上图)
- CLI读取您的
.env标志,然后通过以下方式加载OpenAPI规范spec_loader.py,这将取消引用所有$ref指针,并将每个操作转换为一个命名工具。 - MCP服务器注册这些工具,并在stdio上监听
list_tools/call_tool来自客户端(Claude Desktop或您自己的应用程序)的消息。 - 当调用工具时,
api_client.py将参数映射到path/query/body parameters并发出真正的HTTP请求。 - 在聊天模式下,代理循环会询问LLM后端(Ollama或Gemini,可通过配置切换)要调用哪个工具,反馈结果,并重复直到模型给出最终答案。
深入
1.命名工具
当规范加载器读取您的OpenAPI文件时,每个HTTP操作都会变成一个 命名工具,LLM可以按名称调用的函数。 例如,OpenAPI规范在YAML(或JSON)中这样描述您的API:
paths:
/pets/{id}:
get:
operationId: getPetById
summary: Find a pet by ID
parameters:
- name: id
in: path
required: true
schema:
type: integerspec加载器读取该内容并创建 命名工具,本质上是一张功能卡,上面写着: *“存在一个名为 getPetById,它接受一个名为的整数参数 id,它的作用如下。"* 该卡被交给LLM,以便它知道该工具的存在以及如何调用它 operationId 在你的规范中成为一个工具名称。
2.取消提及 $ref 指针
OpenAPI规范经常重用定义 $ref 为了避免重复:
parameters:
- $ref: '#/components/parameters/PetId' # a pointer, not the real thing
components:
parameters:
PetId:
name: id
in: path
required: true
schema:
type: integer这 $ref 它只是一个指针,就像文件系统中的符号链接。 _“取消引用”_ 意味着跟随每个指针,并用它指向的实际内容替换它,这样读取规范的代码就会看到一个平坦、完整的结构,没有悬空的引用。如果没有这一步,你会在阅读时崩溃 param["name"] 在一个 {"$ref": "..."} 对象。
3. serve 对比 chat --每种模式的实际作用是什么
这是两个完全不同的用例:
serve 模式 --您启动流程并让它运行。它使用MCP协议,并等待客户端(如Claude Desktop)连接到它并发送请求。你从不自己打字。这是一项后台服务。
chat 模式 --你会得到一个交互式终端提示。你用简单的英语输入一个问题,服务器计算出要调用哪个API,调用它,然后打印答案给你。这是一个命令行聊天机器人 直接连接 到您的API, 完全不涉及MCP服务器,用自然语言与API对话.
聊天模式流程
关键见解:在聊天模式下 完全不涉及MCP协议一切都在一个Python进程中运行。您的消息 从不 转到MCP服务器,它直接转到 Ollama,它决定调用哪个工具,然后 api_client.py 直接进行HTTP调用。MCP服务器代码(server.py)在聊天模式下不使用。
虚线框显示 cli.py, Ollama,以及 REST API 调用都发生在同一个运行进程中。把它想象成一个自包含的代理循环:你→ LLM → HTTP调用→ you.
服务模式 是说MCP协议并等待Claude Desktop连接的程序。 聊天模式 只是一个独立的终端聊天机器人,碰巧共享相同的工具定义。
4.“MCP服务器注册这些工具”——哪些工具?
正是规范加载器提取的工具-每个API端点一个。当MCP服务器启动时,它“告诉”MCP协议层: *“这是我的可用工具列表。”* 该列表是以下内容的直接输出 extract_tools() 在OpenAPI规范上运行。如果您的规范有30个操作,MCP服务器将注册30个工具。没有更多,也没有更少。
5.stdio是什么?
stdio (标准输入/输出)是两个进程之间最简单的通信通道:一个进程将文本写入其标准输出,另一个进程从其标准输入读取文本。这与shell中的管道命令机制相同(cat file | grep foo).
MCP协议使用这一点是因为它是普遍可用的,并且不需要任何网络设置。Claude Desktop只是将MCP服务器作为子进程生成,两者通过管道进行通信。
6. list_tools 和 call_tool --两条MCP消息
MCP协议故意设计得很小。这里真正重要的只有两条信息:
list_tools --客户端(Claude Desktop)询问: *“你能做什么?”* 服务器会回复完整的目录:每个注册工具的名称、描述和输入模式。克劳德就是这样知道的 getPetById 存在以及它需要什么论据。
call_tool --客户说: *“使用这些参数运行此工具。”* 服务器执行真正的HTTP调用并返回结果。因此,Claude Desktop和您的MCP服务器之间的完整对话如下:启动时,它会问“您有什么工具?”并返回目录。然后,每当LLM决定使用一个时,它都会发送一个 call_tool 消息,您的服务器进行HTTP调用,并将结果发送回。这就是整个协议。
光标作为MCP客户端
Cursor原生支持MCP,您可以使用JSON文件对其进行配置。
步骤1——创建配置文件
{
"mcpServers": {
"petstore": {
"command": "uv",
"args": [
"run",
"--project", "/absolute/path/to/ai-dev-openapi-mcp-server",
"openapi-mcp",
"serve",
"--spec", "https://petstore3.swagger.io/api/v3/openapi.json"
]
}
}
}替换 /absolute/path/to/openapi-mcp-server 使用解压缩项目的实际路径。
步骤2--重新启动Cursor
Cursor在启动时读取配置。重新启动后,转到 光标设置→ 工具和MCP 你应该看看 petstore 用绿点列出。
步骤3--在Cursor聊天中使用它
打开光标聊天面板(Cmd/Ctrl+L),确保您已进入 代理 模式(不询问或编辑),只需自然地与API对话:
find pet with id 1
list all available pets
create a new pet named Bruno到底发生了什么
光标生成您的 openapi-mcp serve 进程启动时作为子进程,通过stdio连接到它(就像Claude Desktop一样),其余部分是相同的: list_tools 启动时,然后 call_tool 每当代理决定使用一个。
小心
这 --llm ollama 你传递去发球的旗帜是 未使用 在 serve mode,进行推理的LLM是Cursor本身(它是MCP客户端)。这 --llm 选项仅在聊天模式下重要,在这种模式下,我们的服务器也扮演着代理的角色。在 serve mode,你的服务器只是一个愚蠢的工具执行器: Cursor思考,你的服务器行动。
光标读取 ~/.cursor/mcp.json 并在服务器进程启动时自动生成该进程。你从不跑 uv run openapi-mcp serve 你自己。 Cursor为您完成此操作。
你什么时候运行每个命令?
简单地总结一下规则:
| 旗帜 | 发球 | 聊天 |
|---|---|---|
--spec | 必填 | 必填 |
--llm | 忽略 | 必填 |
--ollama-model | 忽略 | 如果是必需的 --llm ollama |
--gemini-key | 忽略 | 如果是必需的 --llm gemini |
uv run openapi-mcp chat 是一个完全独立的、独立的命令,当您想要在根本不涉及Cursor的情况下直接与API对话时,您可以在终端中运行该命令。 这两种模式彼此无关。
