mcp-api-bridge
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-api-bridgeList the 5 most recent posts by user 3"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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 resourceNo prompt engineering needed. The AI assistant discovers the tools, validates inputs via Pydantic schemas, and gets structured responses.
Related MCP server: OpenAPI MCP Server
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/ -vAdd 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 |
| GET /posts | List posts with filtering + pagination | Query params, in-memory pagination, dual format output |
| GET /posts/{id} | Fetch a post with optional comments | Resource lookup, related data joining |
| POST /posts | Create a new post | Write operations, input validation |
| 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 -vThe 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
FastMCP — MCP Python SDK
httpx — async HTTP client
Pydantic v2 — input validation
JSONPlaceholder — demo REST API
pytest + pytest-httpx — testing
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.
Site: brycewatson.com
GitHub: github.com/BryceEWatson
Need an MCP server built for your API? Get in touch.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/BryceEWatson/mcp-api-bridge'
If you have feedback or need assistance with the MCP directory API, please join our Discord server