An MCP mock-API server: let your coding agent spin up the backend

Coding agents keep hitting the same wall humans do: the frontend they're writing needs an API that doesn't exist yet. The usual agent workarounds are all bad β€” hardcode JSONPlaceholder (fixed schema, fake writes), generate an MSW handler file (more code to maintain, only exists inside the test process), or scaffold an Express server (now your "mock" has a package.json, a port, and a lifecycle).

Mockbird is a hosted mock REST API service, and it ships a hosted MCP server. Add one URL to your MCP client config and your agent gets eighteen tools that create and drive real, live mock backends: seeded multi-resource projects, OpenAPI/db.json/Postman/CSV import, record CRUD, custom routes, snapshots. No signup, no API key, no OAuth dance β€” the connection just works.

Connect your editor or agent

# Claude Code
claude mcp add --transport http mockbird https://mockbird.mockbird.workers.dev/mcp

# Cursor / Windsurf / any client that reads mcp.json
{ "mcpServers": { "mockbird": { "url": "https://mockbird.mockbird.workers.dev/mcp" } } }

# VS Code
code --add-mcp '{"name":"mockbird","type":"http","url":"https://mockbird.mockbird.workers.dev/mcp"}'

The transport is stateless Streamable HTTP (spec 2025-06-18; older 2025-03-26 and 2024-11-05 clients work too). No session juggling, no SSE requirement, no server to install β€” it's the same Cloudflare Worker that serves the mocks. Mockbird is also listed in the official MCP Registry as dev.workers.mockbird.mockbird/mockbird.

The eighteen tools

ToolWhat it doesNeeds adminKey?
create_projectNew mock API β€” blog / ecommerce / saas preset or blank. Returns {id, adminKey, baseUrl}.β€”
import_dataOpenAPI 3.x / Swagger 2.0, json-server db.json, Postman Collection v2.x, DevTools HAR, VCR cassette, bare JSON array, or CSV β†’ live seeded API. Auto-detected. OpenAPI non-CRUD paths (login, search, RPC verbs) round-trip as custom routes serving the spec's own examples.β€”
fork_projectCopy a whole project (records verbatim, custom routes, settings) into a fresh one with its own id + adminKey. Pass ttl for a self-expiring fork (60 s – 7 days) β€” crashed eval/CI runs can't leak sandboxes. withSnapshots:true carries the template's answer-key snapshots along. {"project":"demo"} works with no key.source's (not for demo)
add_resourceAdd a collection from a template (users, products, …) or explicit typed fields; seeds realistic fake records.yes
project_infoRoot index: resources, record counts, URLs, export links. Works on demo.no
query_recordsGET with the full query toolkit: filters, _gte-style operators, search, sort, pagination, select, relations, and failure simulation (mock_status, mock_delay, mock_chaos…).no
write_recordPOST / PUT / PATCH / DELETE β€” writes persist.no
generate_fake_dataInstant realistic fake data, stateless β€” ready-made shapes (persons, products, credit_cards…) or a custom {key: type} field map; pass seed for deterministic rows. No project needed.no
custom_routeDefine /health, /config/:key, catch-all /webhooks/* bins, templated bodies.yes
snapshotsSave / restore / list / delete full-dataset snapshots β€” deterministic fixtures for the tests your agent writes. action:"diff" grades a run: compare an expected snapshot against live data (or another snapshot) and assert .identical.yes
verdictThe whole eval grade in one call: state check (snapshot diff vs live) + trajectory constraints on the request log → {pass, checks[]}. E.g. {"snapshot":"expected","trajectory":[{"method":"DELETE","count":0}]} β€” assert .pass.yes
inspect_requestsRead the request inspector: what your app / tests / webhook sender actually sent (method, path, headers, body snippet). Public on demo.yes*
share_projectMint / rotate / revoke a read-only share link β€” a browser URL your human reviewer opens to browse the sandbox’s data, endpoints, snapshots and live request traffic. No writes, adminKey never exposed.yes
delete_projectDelete a project and all its data β€” clean up short-lived test projects when the session is done.yes
check_api_statusLive health of the ~37 public mock/testing APIs on the status tracker (httpbin, JSONPlaceholder, ReqRes…): summary of everything failing, or per-service detail with 24h/7d uptime and recent checks. Down services link the migration guide.no
uptime_monitorFree downtime alerts for any public URL β€” checked every 30 minutes from Cloudflare's network; your webhook gets one message on down, one on recovery (debounced, so blips never fire). Includes a public status page + badge + Atom feed.no (returns its own secret)
heartbeatDead man's switch for cron jobs and recurring agent runs: the job pings Mockbird (a returned URL or the tool's ping action); a missed ping fires the alert webhook. Arm one for your own scheduled runs so a human hears when you stop running.no (returns its own secret)
watch_service_statusSubscribe a webhook to down / recovered events for any API tracked by check_api_status β€” or "*" for all of them.no (returns its own secret)

Every tool dispatches through the same code paths as the public HTTP API, so the request inspector, daily caps, and anonymous per-IP limits apply identically. The adminKey returned by create_project is shown once β€” well-behaved agents save it into the project's .env.

Five slash commands (MCP prompts)

The server also publishes MCP prompts β€” ready-made workflows your client surfaces as slash commands (in Claude Code they appear in the / picker as /mockbird:<name> (MCP)):

PromptArgumentWhat it does
mock_an_apia plain-English descriptioncreates the project, adds matching resources with realistic field types, verifies with real reads, hands you baseUrl + dashboard + a working curl
mock_from_specan OpenAPI spec, db.json, Postman collection, HAR, CSV β€” or a URL to oneimports it as a live mock, reports warnings, verifies records survived
simulate_failuresoptional scenario ("retries on 503", "rate limiting"…)builds the exact mock_status/mock_chaos/mock_seq/mock_ratelimit URLs for your test and demonstrates each failing response for real
monitor_uptimea URL (or a cron-job description) + a webhookpicks uptime_monitor or heartbeat, arms it, stores the credentials, and hands you the status page + badge + (for cron jobs) the ping line to append
is_it_downa public API name ("httpbin", "reqres.in"…)reads the live status tracker, and if the service is failing, stands up a drop-in replacement and tells you what to change

They're plain prompts/list + prompts/get under the hood β€” no client lock-in, any MCP client that supports prompts gets them.

What a session looks like

Prompt your agent with something like:

"Create an ecommerce mock API with Mockbird and point this app's
 .env at it. Then write a Playwright test that checks the empty-cart
 state using a snapshot."

A capable agent will: call create_project with preset: "ecommerce" (one call β€” products, orders, customers, reviews, all seeded), write VITE_API_URL=<baseUrl> into .env, call snapshots with action: "save" after emptying the fixture data it needs, and pin that scenario in tests via mock_snapshot=<name> in query_records params β€” the same snapshot pinning humans use, no restore races between parallel workers.

The important part: the mock itself stays plain HTTP. The code your agent writes ships with a working URL β€” you can curl it, open it in a browser, hand it to a teammate, or run CI against it after the agent session ends. The mock isn't trapped inside the agent's tool sandbox.

No MCP client? It's just JSON-RPC over POST

You can drive the whole thing from curl β€” useful for debugging what your agent sees:

# list the tools
curl -s -X POST https://mockbird.mockbird.workers.dev/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# call one: the shared demo project's index
curl -s -X POST https://mockbird.mockbird.workers.dev/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
        "name":"project_info","arguments":{"project":"demo"}}}'

# query with projection + pagination
curl -s -X POST https://mockbird.mockbird.workers.dev/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
        "name":"query_records","arguments":{"project":"demo",
        "resource":"products","params":{"_limit":2,"select":"name,price"}}}}'

All three run against the live server right now β€” the last one returns two products with just id, name, price.

Why MCP and not just… curl?

Honest answer: agents can already use Mockbird with plain HTTP β€” that's why /llms.txt exists, and agent traffic does arrive that way. MCP adds three things: discovery (the agent finds typed tools with descriptions instead of reading docs into context), fewer tokens (tool results are trimmed and capped at 50 KB, with a hint to use select/_limit when truncated), and fewer mistakes (input schemas encode the gotchas β€” field types, which calls need the adminKey β€” so the agent doesn't learn them by 400ing). If your agent runs fine on raw HTTP, nothing forces the switch.

Limits, honestly: tool calls share the project's 10,000 requests/day cap and anonymous project creation is limited to 30/IP/day (the MCP server forwards your real client IP for caps β€” one shared egress IP for a big agent fleet will hit it). Responses are JSON only, no streaming. The server is stateless, so clients that require session-id handshakes fall back to sessionless mode per spec. And the data is mock-grade: this is for building against an API shape, not for storing anything you care about. Full reference in the docs.

More guides: using the sandbox for agent evals (snapshot episodes, inspector ground truth, chaos drills) Β· deterministic test data Β· mock server from an OpenAPI spec Β· testing loading & error states Β· free mock API tools compared. Create your API β†’

⚑ Skip the terminal: this link creates a live, seeded e-commerce backend (products, orders, customers, reviews) in the dashboard β€” real URL, data browser already open, no signup. Or import your own OpenAPI spec, db.json, CSV, Postman collection, or HAR and mock your exact shapes.