Atlas / MCP servers / copilotkit / aimock

aimockBLOCK

mcp/copilotkit/aimock

Mock everything your AI app talks to — LLM APIs, MCP, A2A, AG-UI, vector DBs, search. One package, one port, zero dependencies.

Verdict
BLOCK
Grade
F
Trust score
51 /100
Exposed tools
64 57r · 5w · 2d
Transport
streamable-http
License
MIT
Stars
971
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Mock infrastructure for AI application testing — point your SDK at one local port and every provider, protocol, and service answers deterministically.

Quick start · The suite · **Record & replay** · **Docs**

[](https://www.npmjs.com/package/@copilotkit/aimock) [](https://github.com/CopilotKit/aimock/actions/workflows/test-unit.yml) [](https://github.com/CopilotKit/aimock/actions/workflows/test-drift.yml) [](./LICENSE)

https://github.com/user-attachments/assets/76815122-574a-48e1-b275-edae0a014667

One package, one port, zero dependencies. LLM APIs, image generation and editing, text-to-speech, transcription, audio translation and generation, video generation, embeddings, MCP tools, A2A agents, AG-UI event streams, vector databases, search, rerank, and moderation — no keys, no network, no surprise bills.

Quick Start

npm install @copilotkit/aimock
// The class is still named `LLMock` for back-compat after the v1.7.0 package
// rename from `@copilotkit/llmock` to `@copilotkit/aimock`.
import { LLMock } from "@copilotkit/aimock";

const mock = new LLMock({ port: 0 });
mock.onMessage("hello", { content: "Hi there!" });
await mock.start();

// Set env BEFORE importing/constructing the OpenAI (or other provider) client.
// Many SDKs cache the base URL at construction time — if the client is built
// before these are set, it will talk to the real API (surprise bills) instead
// of aimock.
process.env.OPE
Read from source at commit 8e7afd4aa812OBSERVED · 2026-10-12
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add aimock --env AIMOCK_DUMMY_KEY_MARKER=${AIMOCK_DUMMY_KEY_MARKER} --env AIMOCK_MCP_UPSTREAM_AUTH=${AIMOCK_MCP_UPSTREAM_AUTH} --env AIMOCK_RECORD_SECRET_VALUES=${AIMOCK_RECORD_SECRET_VALUES} --env AIMOCK_VERTEX_ACCESS_TOKEN=${AIMOCK_VERTEX_ACCESS_TOKEN} -- npx -y @copilotkit/[email protected]
claude-desktop
{
  "mcpServers": {
    "aimock": {
      "command": "npx",
      "args": [
        "-y",
        "@copilotkit/[email protected]"
      ],
      "env": {
        "AIMOCK_DUMMY_KEY_MARKER": "${AIMOCK_DUMMY_KEY_MARKER}",
        "AIMOCK_MCP_UPSTREAM_AUTH": "${AIMOCK_MCP_UPSTREAM_AUTH}",
        "AIMOCK_RECORD_SECRET_VALUES": "${AIMOCK_RECORD_SECRET_VALUES}",
        "AIMOCK_VERTEX_ACCESS_TOKEN": "${AIMOCK_VERTEX_ACCESS_TOKEN}"
      }
    }
  }
}
03

Exposed tools (64)

57 read · 5 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
areadd
afterreadKnown entry ID to page after; mutually exclusive with before
ag1readtest
apply_patchwriteApply a patch in the *** Begin Patch / *** End Patch format.
archivereadArchive a list of city names
beforereadKnown entry ID to page before; mutually exclusive with after
calcreadCalculator
conc-agentreadconcurrent
config-agentreadfrom config
config-toolreadfrom config
describedreadLook up a city
echoreade
emptyread
freadf
filterreadFilter by file ingestion status before pagination
get_weatherreadGet weather for a city
greetingreadA greeting prompt
helperreadhelper agent
includewriteSet to
journal-agentreadtest
late-agentwriteadded after start
limitreadMaximum entries per page
lookupreadconfig tool
mcp__githubreadGitHub MCP
mcp__gitlabreadGitLab MCP
methodreadExact method filter (case-insensitive)
native_toolreadCohere native
no-result-promptreadA prompt without a result handler
offsetreadEntries to skip (integer >= 0)
openai_toolreadOpenAI style
orderwriteSort order by creation time
pathreadSubstring filter on the request path
plainreadscoped
purposereadFilter by purpose
raw_queryreadfree text
real_toolreada tool
record_numbersreadRecord the full comma-separated integer sequence.
record_payloadreadRecord a long payload
record_textreadRecord text
registered-onlyreadregistered
requestIdreadRequest-id filter
reset-agentdestructivetest
reset-tooldestructivewill be cleared
searchreadSearch things
search_toolreadSearch
servicereadExact service filter
skill-agentreadAn agent with skills
statusreadExact response status filter
stream-agentreadAn agent with streaming tasks
suite-agentreadAgent in suite
summarizereadSummarize text
treadd
t1readone
task-agentreadAn agent with tasks
test-agentreadA test agent
test-toolreadA test tool
testIdreadTest-id scope filter
translatereadTranslates text
wreadfrom A
weatherreadWeather lookup
weather_toolsreadWeather lookups
webreadsearch
with_metareadFake with metadata
write_reportwriteWrite a detailed weather report.
04

Trust audit

BLOCKgrade F · trust 51/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
none-observed
Shell
declared (6 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
scripts/drift-report-collector.ts:2688
stdout = exec(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.claude/commands/write-fixtures.md
.claude/commands/write-fixtures.md
Why it matters. link not followed
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
src/__tests__/record-sanitize.test.ts:333
["sk-ant-api03-abcdefghijklmnop", "Anthropic API key"],
MEDIUMHard-coded secrets · secret.aws · CWE-798, CWE-321
src/__tests__/record-sanitize.test.ts:337
["AKIAABCDEFGHIJKLMNOP", "AWS access key"],
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
examples/mcp-record-replay-agents/mastra-agent.test.ts:109
apiKey: "aimock-fixture-no-key",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
src/__tests__/live-record-replay.test.ts:227
const secret = "synthetic-owner-private-7f3d";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
src/__tests__/live-record-replay.test.ts:237
token: source === "selected" ? secret : "ordinary-test-credential",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
src/__tests__/live-record-replay.test.ts:313
const token = "synthetic-live-credential-7f3d";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
src/__tests__/live-record-replay.test.ts:336
token: "synthetic-live-credential-7f3d",
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/__tests__/record-sanitize.test.ts:334
["ghp_abcdefghijklmnopqrstuvwxyz0123456789", "GitHub token"],
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
src/__tests__/record-sanitize.test.ts:335
["github_pat_11ABCDEFG0123456789_abcdefghij", "GitHub token"],
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
src/__tests__/drift-collector.test.ts:161
it('-----BEGIN PRIVATE KEY-----fixture-private-canary-----END PRIVATE KEY-----', () => expect(true).toBe(true));
MEDIUMHard-coded secrets · secret.slack · CWE-798, CWE-321
src/__tests__/record-sanitize.test.ts:336
["xoxb-123456789012-abcdefghij", "Slack token"],
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
reset-agent, reset-tool
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/__tests__/mcp-record-cli.test.ts:465
const path = join(fx, "..", `cfg-${createHash("sha1").update(fx).digest("hex")}.json`);
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/__tests__/ws-upstream.test.ts:50
const accept = createHash("sha1")
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/ws-framing.ts:370
return createHash("sha1")
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/__tests__/adoption-wall.test.ts:71
} from "../../scripts/update-adoption-wall.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/__tests__/adoption-wall.test.ts:1236
const DOCS_PATH = fileURLToPath(new URL("../../docs/index.html", import.meta.url));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/__tests__/adoption-wall.test.ts:3030
const AW_REPO_ROOT = new URL("../../", import.meta.url);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/__tests__/aimock-cli.test.ts:20
const CLI_PATH = resolve(__dirname, "../../dist/aimock-cli.js");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/__tests__/aimock-cli.test.ts:939
const readme = readFileSync(resolve(__dirname, "../../README.md"), "utf8");
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
.github/workflows/test-drift.yml:552
# code can never exfiltrate the provider keys. The trade-off (a fork PR has
LOWNetwork egress · net.env_exfil · CWE-200, CWE-319
packages/aimock-pytest/tests/test_basic.py:93
os.environ.copy() ... requests.post
Why it matters. reads secrets in the same file that sends data out

Gates applied: no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha 8e7afd4aa812full audit observations/trust-audit/mcp-server/copilotkit__aimock.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-128e7afd4aa812BLOCKF51first audit
06

Questions

What is the @copilotkit/aimock MCP server?

Mock everything your AI app talks to — LLM APIs, MCP, A2A, AG-UI, vector DBs, search. One package, one port, zero dependencies.

What tools does @copilotkit/aimock expose?

64 in total: 57 read-only, 5 that write, and 2 that can delete or overwrite (reset-agent, reset-tool). Every one is listed on this page with its risk.

Is @copilotkit/aimock safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (51/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does @copilotkit/aimock need?

It reads AIMOCK_DUMMY_KEY_MARKER, AIMOCK_MCP_UPSTREAM_AUTH, AIMOCK_RECORD_SECRET_VALUES, AIMOCK_VERTEX_ACCESS_TOKEN, ANTHROPIC_API_KEY, ARK_API_KEY, COHERE_API_KEY, ELEVENLABS_API_KEY, FAL_KEY, FIXTURE_SECRET, GITHUB_TOKEN and GOOGLE_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does @copilotkit/aimock run?

It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as @copilotkit/aimock at 1.45.1.

How current is this page?

The grade is for one exact copy of the source (8e7afd4aa812), read on 2026-10-12. The repository is watched and re-audited when it changes.

Advertisement