What Is aimock? We Tested CopilotKit's Mock Server for Your Entire AI Stack
aimock is an open-source mock server from CopilotKit that lets you test AI applications without calling real APIs: it mocks LLM providers, MCP servers, A2A agents, AG-UI streams, vector databases and multimedia endpoints from a single npm package on a single local port. It's MIT licensed, written in TypeScript with zero runtime dependencies, and it exists to solve a problem every AI team hits eventually: test suites that are slow, flaky and expensive because they talk to live model APIs.
We installed it and ran it before writing this, first on version 1.38.0 in August 2026. We rechecked the gotchas below on 1.45.1 (published October 12, 2026). As of October 29, 2026 the latest release on npm is 1.47.0, published October 27. Here's what worked, what surprised us, and the three gotchas that cost us real debugging time. Testing for this article was run in a sandboxed Linux environment with Claude as part of our editorial workflow, and every command and output below is reproducible.
Why does testing AI apps need a special mock server?
A single agent request can touch several services before it returns: the LLM, an MCP tool server, a vector database for RAG, a web search API, a reranker, a moderation layer, maybe a sub-agent over A2A. Most teams mock one of those and leave the rest live, which means CI burns tokens on every run and fails randomly when a provider hiccups.
aimock's answer is to mock the whole chain deterministically. You define fixtures, which are match criteria plus a canned response, and the mock serves them over real HTTP on a real port. That last detail matters: unlike interceptor-based tools such as MSW, it works across processes, so your app under test doesn't need any special test harness. It just points its base URL at localhost.
The project started as LLMock, CopilotKit's LLM-only mock, and was renamed to aimock at version 1.7.0 of the package when coverage expanded to the rest of the agentic stack. The project's README points to one public user: the AG-UI protocol runs its end-to-end test suite on aimock.
What happened when we installed it?
The install is genuinely as small as advertised. npm install @copilotkit/aimock finished in about 5 seconds, added exactly one package to node_modules, and took 8.4 MB on disk. The zero-dependencies claim is literally true: everything is built on Node.js builtins. Those timings are from version 1.38.0. The package still lists no dependencies in 1.45.1, though it has grown as features landed, so expect a bigger download today.
Getting a mocked LLM response took four lines and one environment variable. This is the actual code we ran, using the real OpenAI SDK, not a fake client:
import { LLMock } from "@copilotkit/aimock";
const mock = new LLMock({ port: 0 });
mock.onMessage("hello", { content: "Hi there! I'm a mock." });
await mock.start();
process.env.OPENAI_API_KEY = "fake-key-123";
process.env.OPENAI_BASE_URL = mock.url + "/v1";
// ...your normal OpenAI client code works unchangedOn 1.38.0, the first response came back in 63 milliseconds, in correct OpenAI wire format, with a fake API key. Tool-call fixtures also came back properly shaped, with generated call_... IDs the SDK parsed without complaint. For a class exercise or a CI pipeline, that's the whole point: no keys, no network, no cost, no flakiness.
Does aimock really mock MCP servers?
Yes, and this is the part most coverage of aimock skips, so we went deepest here. MCPMock runs a local MCP server speaking full JSON-RPC 2.0 with session management. You register tools with addTool(), attach behavior with onToolCall(), and any MCP client can run the complete handshake against it: initialize, session ID negotiation, tools/list, tools/call, with correct MCP error codes for unknown tools.
What surprised us is how strict it is, in a good way. When our hand-rolled test client skipped the notifications/initialized notification after initialize, every subsequent call failed with -32002 Session not initialized. That's the correct behavior per the MCP spec, and it means aimock will catch sloppy MCP clients that happen to work against more forgiving servers. If you're learning to build MCP clients or agents, that strictness is free protocol tutoring.
One more detail we haven't seen mentioned anywhere: the npm package ships its own agent skill file at skills/write-fixtures/SKILL.md, a document written for AI coding agents that teaches them the fixture syntax, match fields and common patterns. If you use Claude Code or a similar agent to write your tests, it can read that file and generate correct fixtures on the first try. A testing library shipping documentation for machines as a first-class artifact tells you a lot about where dev tooling is heading.
What gotchas did we hit?
Three. We hit all of them on version 1.38.0, and all three still reproduce on 1.45.1. Each one is cheap to avoid once you know it:
MCPMock.start()returns the URL; there is nomcp.urlproperty.LLMockexposesmock.urlafter starting (so do the A2A and AG-UI mocks), so we assumedMCPMockdid too. It doesn't,mcp.urlisundefinedand our first client crashed withFailed to parse URL. Capture the return value:const url = await mcp.start().- Tool handlers go in
onToolCall(), not inaddTool(). We passed ahandlerfunction inside theaddTool()definition. The tool registered fine, listed fine, and returned empty content on every call, silently, with no error. The schema belongs inaddTool(); the behavior belongs in a separateonToolCall(name, handler)call. - Fixtures can't be passed as a constructor array.
new LLMock({ fixtures: [...] })doesn't error, it just serves 404s for everything. Usemock.addFixtures([...])after construction, or load them from a directory with the CLI's-fflag.
We also verified the chaos testing works as documented. A fixture with chaos: { dropRate: 1.0 } made the OpenAI SDK throw a real InternalServerError with status 500, and disconnectRate: 1.0 on a streaming fixture killed the stream with an APIConnectionError. If your agent claims to handle provider outages gracefully, this is how you prove it in CI instead of hoping.
What's new since 1.38.0?
aimock ships often. Four changes are worth knowing if you read an older tutorial:
- Record a real MCP server, replay it offline (1.45.0). Point aimock at a live MCP server with
--mcp-recordon the command line, or callMCPMock.enableRecording()in code. It saves the session into fake files you can replay in CI with no network. Recordings never store headers and redact known secrets, and aimock refuses to write a file while a secret remains in it. - Model misbehavior on demand (1.45.0). Real models sometimes return broken tool arguments, call tools that don't exist, stop mid answer, or refuse. aimock can now fake those failures so you can test how your agent copes. It's off by default: turn it on with
enableMisbehavior: true. The README warns that older versions silently ignore a fixture's misbehavior settings. - OpenAI Vector Stores mock (1.44.0). Vector stores are where OpenAI keeps your files for search. aimock now mocks creating them, attaching files and running searches, with results that come back the same every time.
- A newer pytest helper.
aimock-pytest, the package that controls aimock from Python tests, is at 0.7.0 on PyPI (October 10, 2026) and supports the new misbehavior and fake report options.
How does aimock compare to WireMock and MSW?
| Aspect | aimock | WireMock | MSW |
|---|---|---|---|
| Primary focus | AI/agentic stack | General HTTP APIs | Browser/Node HTTP interception |
| LLM providers | 11 providers across 22 API surfaces, per the README | Manual setup | Manual setup |
| MCP / A2A / AG-UI | Native, including MCP record and replay | No | No |
| Vector DBs, search, rerank | Built-in (Pinecone, Qdrant, ChromaDB, Tavily, Cohere) | No | No |
| Record & replay | Yes, tuned for AI streaming | Yes | Limited |
| Drift detection vs real APIs | Daily CI against live providers | No | No |
| Runtime | Node.js, zero dependencies | Java | Node.js |
| Works across processes | Yes, real HTTP server | Yes | No, in-process interceptor |
The honest recommendation: these aren't competitors. aimock covers the AI layer; WireMock or MSW still make sense for your ordinary backend APIs. Many teams will run both.
Drift detection is aimock's most unusual feature. LLM providers change response formats without warning, which silently rots mocks. aimock's own CI runs drift tests against the real APIs every day and compares the answers with what the mock produces, so format changes get caught and fixed. No general-purpose mock tool does anything like this, because no general-purpose API changes as often as LLM APIs do.
Should you use aimock?
If you're building or learning to build AI agents in TypeScript or JavaScript, yes, and the cost of trying it is one npm install. It turned our test loop from "needs API keys and patience" into deterministic sub-100ms responses, and the MCP mock alone is worth it if you're developing MCP clients or teaching agent architecture. The strict protocol enforcement will catch bugs your real server forgives.
The limits are real too. The core library is Node.js only. Python teams get the official aimock-pytest helper for controlling the server from pytest, plus a Docker image at ghcr.io/copilotkit/aimock, but you're still running a Node process. And deterministic fixtures test how your code handles responses, not how good the responses are. Judging real model output is a different discipline with different tools.
Go deeper
- What an MCP server is, if the MCP part of this article was new to you
- What is Stagehand, a browser SDK for agents that you'd test the same way
- Our hub of tested AI tools, ranked by the job you need done
Mocking, fixtures and failure injection are the unglamorous engineering that separates a demo agent from one you can trust. If you already call AI APIs and want a guided path to building agents like these, see how AI Flex works. It's self paced, with an AI tutor and mentors.
