Workflow · Agents
Build an MCP Server from Your API
Wrap your REST or GraphQL API as an MCP server so Claude Desktop, Cursor, and any MCP client can call it — write once, use everywhere.
Problem
Your team has useful APIs — CRM, billing, inventory, support tickets — but every AI client needs a custom integration. You end up writing the same GitHub-Slack-DB glue for ChatGPT, Claude, Cursor, and your internal agent.
Final output
A local MCP server (stdio transport) that exposes 5–10 curated tools from your API — with typed inputs, clear descriptions, and read-only resources for common lookups. Works in Claude Desktop and Cursor via a one-line config entry.
Architecture
MCP client (Claude Desktop / Cursor / custom app)
→ stdio transport
→ Your MCP server process
→ Tool handlers (POST /orders, GET /customer/:id, …)
→ Resource providers (recent tickets, account summary)
→ Auth layer (API key / OAuth token from env)
→ Your existing REST / GraphQL APIStep-by-step
- 01
Pick the API surface
List the 5–10 operations an AI assistant actually needs — not every endpoint. Favor read + safe writes. Skip destructive ops until you have guardrails.
- 02
Scaffold with the official SDK
Use @modelcontextprotocol/sdk (TypeScript) or mcp (Python). Start from the quickstart template. Register tools with Zod / Pydantic schemas for inputs.
- 03
Implement tool handlers
Each tool maps to one API call (or a small orchestration). Return structured text or JSON. Handle 4xx/5xx with clear error messages the model can relay to the user.
- 04
Add resources for read-heavy data
Expose stable lookups as MCP resources — e.g. uri://customers/{id}, uri://docs/onboarding. Resources are cheaper than tool round-trips for context the model should skim.
- 05
Wire auth and config
Read API base URL and credentials from env vars. Never hardcode secrets. Document required env in a README the client operator can follow.
- 06
Register in Claude Desktop / Cursor
Add the server to claude_desktop_config.json or Cursor MCP settings. Restart the client. Smoke-test each tool from the chat surface.
What you'll build
An MCP server that wraps your existing API so any MCP-compatible client — Claude Desktop, Cursor, your internal agent — can call it without custom glue per client.
If you haven't read MCP Explained yet, start there. This workflow is the hands-on follow-up.
Why MCP for your API
Before MCP, integrating your billing API into three AI surfaces meant three separate plugins. MCP standardizes the wire format:
- Tools — actions (create ticket, refund order, search customers).
- Resources — read-only context (account summary, open incidents).
- Prompts — reusable templates your server ships to the client.
The client still uses the model's native tool-calling API. MCP just defines where those tools come from.
Step 1 — Curate the surface
Don't mirror your OpenAPI spec 1:1. Ask: what would a helpful coworker need in chat?
Good first tools:
| Tool | Why |
|---|---|
get_customer | Every support / sales question starts here |
search_customers | When the user has email, not ID |
list_open_tickets | Context before drafting a reply |
get_order | Billing and fulfillment questions |
Defer until v2: bulk exports, admin deletes, anything irreversible.
Step 2 — Scaffold the server
TypeScript (most common for MCP servers):
npm init -y
npm install @modelcontextprotocol/sdk zod
Python:
pip install mcp httpx
Register each tool with a schema the SDK validates before your handler runs. Tight schemas = fewer bad API calls.
Step 3 — Tool handlers
Each handler should:
- Validate input (SDK does this if schemas are correct).
- Call your API with the user's credentials from env.
- Return concise, structured text — not a 50 KB JSON dump unless asked.
- On failure, return an actionable error string.
Example response shape:
Customer: Acme Corp (id: cust_8f2a)
Plan: Pro ($299/mo) · 12 seats · renews 2026-07-01
Open tickets: 2 (billing, SSO setup)
Last login: 2026-06-04
The model can quote this directly in chat.
Step 4 — Resources for read-heavy lookups
Tools are for actions and lookups the model chooses. Resources are for data the client can prefetch.
Expose stable URIs:
customer://{id}— full account snapshotdocs://runbooks/billing— internal markdown your team maintains
Resources shine when the same context gets attached to many conversations.
Step 5 — Auth
Pattern that works:
API_BASE_URL=https://api.yourco.com
API_KEY=sk_live_...
For OAuth SaaS (Linear, Slack, GitHub): complete OAuth once, store refresh token locally, refresh in the server on startup. Never pass tokens through the model's context.
Step 6 — Connect the client
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"your-api": {
"command": "node",
"args": ["/path/to/server/dist/index.js"],
"env": {
"API_KEY": "..."
}
}
}
}
Cursor — same shape in MCP settings. Restart after changes.
Smoke-test: ask the client to "look up customer X" and verify the tool call in logs.
Production guardrails
- Read-only v1 — ship reads first, add writes with
dry_runor confirmation. - Rate limits — wrap your API client with backoff; the model will retry aggressively.
- Audit log — append-only local log of tool name + args hash + timestamp.
- Allowlist — if the API is powerful, restrict which tools appear per environment.
What to build next
Once the base server works:
- Composite tools —
prepare_support_context(customer_id)that fetches customer + tickets + recent orders in one call. - MCP prompts — ship "Investigate billing dispute" as a server prompt with embedded tool hints.
- HTTP transport — host for the team when local stdio doesn't scale.
The platform compounds. Your API becomes a first-class citizen in every AI surface your team uses.
Prompt examples
Copy any of these, replace the placeholders, run.
Tool description template
Tool name: get_customer
Description (for the model):
Fetch a customer record by ID. Returns name, plan tier, MRR, open ticket count, and last login. Use when the user asks about a specific account or before creating a support reply.
Input schema:
{
"customer_id": { "type": "string", "description": "UUID or external ID" }
}
Rules:
- Read-only. Never mutate data through this tool.
- If customer_id is missing, ask the user — do not guess.Error message shape
When an API call fails, return text the model can quote:
"API error 404: Customer 'abc-123' not found. Verify the ID or search by email with search_customers."
Avoid raw stack traces. Include the HTTP status, a human sentence, and a suggested next step.Cost estimate
| Line item | Approx. cost |
|---|---|
| MCP server hosting (local) | $0.00 |
| Your API calls (depends on usage) | marginal |
| Dev time (first server) | 2–4 hours |
| Maintenance per quarter | 1–2 hours |
| Total per run (approx.) | ~$3.00 |
Costs depend on model choice, content length, and how aggressively you cache.
Optimizations
- Start with read-only tools — ship faster, fewer incident classes.
- Cache GET responses in-memory with a 60s TTL for hot lookups.
- Use MCP prompts to ship vetted templates ("draft refund reply for customer X").
- Batch related reads into one composite tool when the model always chains them.
- Log tool invocations locally — essential for debugging and auditing.
Common mistakes
- Exposing every endpoint — the model gets confused and users get hurt.
- Vague tool descriptions — the model calls the wrong tool or hallucinates parameters.
- No input validation — bad args become 500s your API team has to triage.
- Putting write tools live without confirmation — add a dry_run flag or human-in-the-loop.
- Forgetting stdio buffering on Windows — flush stdout after each response.
Frequently asked questions
Related on AIKnowHub
Concept
MCP Explained
The Model Context Protocol is the USB-C of AI tooling. Here's what it is, why it matters, and how to think about it.
Concept
AI Agents Explained
Agents are LLMs that can take actions in a loop. Here's what that actually means, where they shine, and where they fall over.
Concept
Function Calling Explained
Function calling is how LLMs trigger your code. Here's how it actually works under the hood, and how to design tools that the model uses correctly.
Tool Guide
Claude Code Guide
The definitive guide to Anthropic's terminal-native AI coding agent — install, configure, MCP, hooks, skills, sub-agents, plan mode, cost, security, limitations.
Directory
Claude Code
Terminal-native agent that reads, writes, runs, and reviews your codebase.
Learning Path
AI Agent Builder Roadmap
The path from 'I built a chatbot' to 'I built an agent that runs unsupervised.' For builders, not lurkers.