mcp-api-bridge

mcp-api-bridge

Enables AI assistants like Claude to interact with any REST API through typed, validated MCP tools. Provides a pattern to wrap REST APIs as MCP servers.

Category
访问服务器

README

REST API → MCP Server Bridge

Turn any REST API into an MCP server so Claude, Cursor, and other AI assistants can use it directly.

This is a production-quality starter kit that wraps JSONPlaceholder (a free REST API) as 4 MCP tools. The real value is the pattern — swap the API client to point at your own API and you have a working MCP server.


<p align="center"> <img src="docs/demo.svg" alt="Demo: Claude Desktop using MCP API Bridge tools" width="800"> </p>

What This Does

You give Claude (or any MCP-compatible AI assistant) access to a REST API through typed, validated tools:

You: "List the 5 most recent posts by user 3"

Claude calls: api_list_posts(user_id=3, limit=5)
→ Fetches GET /posts?userId=3
→ Returns formatted, paginated results

You: "Create a post about MCP servers"

Claude calls: api_create_post(title="Why MCP Servers Matter", body="...", user_id=1)
→ Sends POST /posts with validated payload
→ Returns the created resource

No prompt engineering needed. The AI assistant discovers the tools, validates inputs via Pydantic schemas, and gets structured responses.

Quick Start

Prerequisites: Python 3.10+, uv (recommended) or pip

# Clone and install
git clone https://github.com/BryceEWatson/mcp-api-bridge.git
cd mcp-api-bridge
uv pip install -e ".[dev]"

# Run the server (stdio transport)
python -m api_bridge_mcp.server

# Or run tests
pytest tests/ -v

Add to Claude Desktop — copy this into your claude_desktop_config.json:

{
  "mcpServers": {
    "api-bridge": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/mcp-api-bridge", "api-bridge"]
    }
  }
}

Restart Claude Desktop. The 4 tools appear automatically.

The Tools

Tool Method What It Does Key Patterns
api_list_posts GET /posts List posts with filtering + pagination Query params, in-memory pagination, dual format output
api_get_post GET /posts/{id} Fetch a post with optional comments Resource lookup, related data joining
api_create_post POST /posts Create a new post Write operations, input validation
api_update_post PATCH /posts/{id} Update post fields Partial updates, existence checks

Every tool supports response_format: "markdown" (human-readable) or "json" (machine-readable). All inputs are validated with Pydantic v2 models with field constraints. Every tool has MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) set correctly.

Adapting This For Your API

The whole point of this project is to show a repeatable pattern. Here's how to make it work with any REST API:

Step 1: Replace the API client

Edit src/api_bridge_mcp/api_client.py. Change the base URL and add your auth:

class APIClient:
    def __init__(self, base_url: str = "https://api.your-service.com/v1", timeout: int = 30):
        self.base_url = base_url
        self.timeout = httpx.Timeout(timeout)
        self.headers = {"Authorization": f"Bearer {os.environ['YOUR_API_KEY']}"}

The rest of the client (get/post/put/patch, error handling) works unchanged.

Step 2: Define your Pydantic input models

Replace the post-related models in server.py with your domain:

class SearchOrdersInput(BaseModel):
    model_config = ConfigDict(str_strip_whitespace=True, extra="forbid")

    customer_id: Optional[str] = Field(None, description="Filter by customer")
    status: Optional[str] = Field(None, description="Filter by status: pending, shipped, delivered")
    limit: int = Field(20, ge=1, le=100, description="Results per page")

Step 3: Register your tools

Same @mcp.tool decorator pattern — pass a Pydantic model as the single parameter:

@mcp.tool(
    name="orders_search",
    description="Search orders by customer and status.",
    annotations={"readOnlyHint": True, "idempotentHint": True}
)
async def orders_search(params: SearchOrdersInput) -> str:
    async with APIClient() as client:
        query = {}
        if params.customer_id:
            query["customer_id"] = params.customer_id
        if params.status:
            query["status"] = params.status
        orders = await client.get("/orders", params=query)
        return format_orders(orders[:params.limit])

Step 4: Update the Claude Desktop config

Point the config at your new server. That's it.

Project Structure

mcp-api-bridge/
├── README.md                          ← You are here
├── PLAN.md                            ← Design decisions and research
├── pyproject.toml                     ← PEP 621 packaging
├── claude_desktop_config.json         ← Example Claude Desktop config
├── src/
│   └── api_bridge_mcp/
│       ├── __init__.py
│       ├── api_client.py              ← HTTP client (swap this for your API)
│       └── server.py                  ← MCP tools (4 tools, ~530 lines)
└── tests/
    ├── conftest.py                    ← Shared fixtures and mock data
    ├── test_client.py                 ← API client tests (14 tests)
    └── test_tools.py                  ← Tool tests (32 tests)

The architecture separates the API layer (api_client.py) from the MCP layer (server.py). When adapting for a new API, you primarily modify api_client.py and the Pydantic models — the MCP wiring stays the same.

Design Decisions

These are documented in detail in PLAN.md. The short version:

JSONPlaceholder as the demo API — zero friction (no auth, no signup, no rate limits), full CRUD, and obviously a stand-in so the pattern is the focus, not the domain.

Python + FastMCP — the MCP Python SDK's high-level framework. Handles tool registration, input schema generation, and transport automatically. Fewer lines, fewer bugs.

stdio transport — the right default for local-first MCP servers. Add mcp.run(transport="streamable_http", port=8000) for remote deployment.

Pydantic v2 for validation — every tool input is a typed model with constraints. The AI assistant sees the schema and knows exactly what to send.

Dual response formats — markdown for when a human is reading Claude's output, JSON for when another system is consuming it.

Running Tests

# All tests
pytest tests/ -v

# Just the API client tests
pytest tests/test_client.py -v

# Just the tool tests
pytest tests/test_tools.py -v

The unit and tool tests use pytest-httpx to mock HTTP responses — fast and deterministic. The end-to-end tests hit the live JSONPlaceholder API over the real MCP protocol. 74 tests covering input validation, output formatting, pagination, error handling, and full MCP protocol flows.

Built With

About

Built by Bryce Watson — senior engineer (10+ years, ex-eBay) specializing in AI engineering, MCP servers, and production AI systems. Contributor to Anthropic's Python SDK.

Need an MCP server built for your API? Get in touch.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选