mockworld
A synthetic internet for agents
Run fake services — a fake Stripe, a fake Gmail, a fake exchange, a fake CRM — as local MCP servers, so you can build and test agents without touching production, leaking data, or paying for real API calls.
pip install mockworld-mcp
mockworld run mock:payments # a stateful fake Stripe as an MCP server
Status: released —
mockworld-mcpon PyPI. Deterministic engine, 6 built-in mocks, MCP stdio + HTTP, fault injection, control plane, registry, world composition, record-mode, snapshots, and a stampedeTarget. Companion to stampede.
Contents
- Why
- Install
- Quickstart
- Use it in your tests
- Built-in mocks
- Author & share mocks
- Compose, record, and simulate
- Project structure
- Documentation
- Contributing
- License
- Part of the Swarm Proof toolkit
Why
Agents need to do things — charge a card, send an email, place a trade, update a record — but you can't point a half-finished, non-deterministic agent at real Stripe/Gmail/an exchange during development. So teams hand-build throwaway mocks for every project, or test against nothing and find failures in production.
Recent agent sandboxes (Veris Sandbox, AWS ToolSimulator) put an LLM in the response path, so the mock does not behave the same way twice. That rules out a CI run that is green for the same reason twice, a byte-identical bug repro, and offline or air-gapped testing.
mockworld is deterministic, MCP-native, and open:
- Deterministic & LLM-free. A seed determines state, IDs, timing, and every injected fault.
reset --seed 42produces the same decline across 50 parallel CI workers. No LLM in the response path. - MCP-native. Services are MCP servers with tool descriptions, stateful behavior, and business-logic fault semantics (declines, insufficient funds, rate limits, disputes). Postman and WireMock target human-driven HTTP testing; they don't speak MCP and don't model business state.
- Open & self-hostable.
pip install, runs locally, offline, Apache-2.0 — not a hosted SaaS.
Install
pip install mockworld-mcp
Requires Python 3.11+. The distribution is named mockworld-mcp; the import package and CLI are simply mockworld.
Quickstart
mockworld list # the built-in mocks
mockworld run mock:payments # a stateful fake Stripe over stdio (MCP)
mockworld run mock:payments --transport http --port 8931 # Streamable HTTP + control plane
mockworld run mock:payments --seed 42 --faults hostile # deterministic + adversarial
mockworld inspect mock:crm # tools, faults, and state shape without running
mockworld demo mock:payments # prove determinism: same seed → identical transcript
Point any MCP client (or a stampede swarm) at it. mockworld reset --seed 42 returns a running server to a byte-identical world, every time.
Use it in your tests
Installing mockworld gives every pytest run a mockworld fixture — a deterministic fake Stripe in two lines:
def test_agent_handles_a_decline(mockworld):
pay = mockworld.start("mock:payments", seed=7, faults="hostile")
cust = pay.call("create_customer", {"name": "Ada", "balance": 10_000}).data
result = my_agent.charge(pay, cust["id"], 2_500) # your agent, against a fake Stripe
assert result.retried_sanely
Seeded and in-memory: each test is deterministic and isolated, and 50 parallel workers don't collide.
Built-in mocks
| Mock | Shape | What it exercises |
|---|---|---|
mock:payments |
Stripe | charges, refunds, idempotency; refund ≤ captured, balance conservation |
mock:crm |
Records | the delete-vs-archive misuse map; audit log; optimistic locking |
mock:exchange |
CEX | balances, orders, fills, slippage; balance conservation |
mock:email |
Gmail/SMTP | send/read/search; sticky bounces; threading; rate limits |
mock:files |
S3 | read-after-write consistency; versioning; slow-download latency |
mock:hello |
— | the smallest complete example, for learning the schema |
Each enforces stateful invariants and injects seeded, business-shaped faults. A declarative mock.yaml plus an optional Python handler defines a mock.
Author & share mocks
mockworld new mystripe # scaffold a runnable, clean-linting mock to grow from
mockworld validate ./mystripe # schema, handler ABI, determinism smells, description quality
mockworld pack ./mystripe # print a registry entry (checksum + metadata) to publish
mockworld search weather # the public registry
mockworld add mock:weather # install a community mock — checksum-verified + safety-gated
The registry (swarmproof/mockworld-registry) is an index-as-repo: contribute a mock by opening a PR with a folder and an index entry. See docs/AUTHORING.md and mock:hello.
Compose, record, and simulate
# Compose several mocks into one world with a shared customer namespace:
mockworld run world:examples/worlds/ecommerce.yaml --seed 42
# → payments + crm + email share the same 50 customers: charge → update CRM → email, consistently.
# Scaffold a runnable mock from an OpenAPI spec — or from captured traffic (HAR):
mockworld record --openapi ./petstore.yaml --out ./petstore_mock
mockworld record --har ./session.har --name orders --out ./orders_mock
# Run a scripted-persona swarm → an Agent Readiness Report (the misuse map):
mockworld swarm mock:crm --agents 200 --goal hide --seed 42
# ⚠ 32.5% of agents destroyed data they meant to hide (delete vs archive) — reproducible.
mockworld swarm mock:crm --agents 200 --seed 42 --descriptions ambiguous
# ⚠ 45.5% — same swarm, vaguer tool descriptions.
# Save a dirtied world as a portable artifact; reload it anywhere to reproduce a bug:
mockworld snapshot save mock:payments bug123.mw.json --seed 7
# Govern fidelity drift against a real provider's OpenAPI contract:
mockworld verify mock:payments --against ./stripe-openapi.yaml
# Export target-side traces (OTel GenAI profile) to any OTLP collector:
mockworld run mock:payments --otlp http://localhost:4318
The joint chaos demo — a transport interruption and a business decline at once, with the side-effect firing exactly once — runs standalone:
python examples/demos/exactly_once_under_chaos.py
Project structure
mockworld/
├── src/mockworld/
│ ├── determinism.py # the seeded entropy funnel (clock/ids/rng/fault-dice)
│ ├── state.py # copy-on-write state store (memory / sqlite)
│ ├── session.py # per-session isolation
│ ├── schema.py # the mock.yaml pydantic models
│ ├── faults.py # business-logic fault injector
│ ├── dispatch.py # declarative CRUD + Python handler ABI
│ ├── engine.py # the transport-free call path (start here)
│ ├── server.py # MCP exposure: stdio + Streamable HTTP + resources
│ ├── control.py # control plane + stampede Target protocol
│ ├── trace.py # OTel-GenAI-profile spans + NDJSON + OTLP export
│ ├── registry.py # add / search / pack (index-as-repo)
│ ├── world.py # compose mocks with a shared identity namespace
│ ├── record.py # scaffold a mock from OpenAPI / HAR
│ ├── snapshot.py # portable scenario snapshots (+ migration)
│ ├── swarm.py # persona swarm → Agent Readiness Report
│ ├── verify.py # contract-drift check vs OpenAPI
│ ├── cli.py # the mockworld command
│ └── mocks/ # payments · crm · exchange · email · files · hello
├── tests/ # 86 tests mapping to the TEST-PLAN gates
├── docs/ # ARCHITECTURE · PRD · AUTHORING · RELEASING · TEST-PLAN · …
├── examples/ # worlds/ · demos/ · registry/
└── .github/workflows/ # ci.yml · release.yml
The engine has no MCP dependency; server.py, control.py, and cli.py are adapters over it. This keeps the determinism and isolation tests dependency-free.
Documentation
| Doc | What it covers |
|---|---|
docs/AUTHORING.md |
Write a mock: schema, handler ABI, faults, publishing |
docs/ARCHITECTURE.md |
Engine design, session isolation, the stampede contract, ADRs |
docs/PRD.md |
Requirements (the REQ-IDs referenced across the docs) |
docs/TEST-PLAN.md |
Test strategy, E2E scenarios, and CI gates |
docs/RELEASING.md |
How releases are cut and published to PyPI |
CHANGELOG.md |
Release history |
SPEC.md · ROADMAP.md |
The original spec and roadmap |
Contributing
Contributions welcome — bug reports, new mocks, and features. See CONTRIBUTING.md. Three rules: determinism is required (all entropy comes from the seeded ctx; the validator enforces it), faults are business-logic only, and every mock ships a fidelity.md.
git clone https://github.com/swarmproof/mockworld && cd mockworld
uv venv && uv pip install -e ".[dev]"
python -m pytest -q
License
Apache-2.0. Citable via CITATION.cff.
Part of the Swarm Proof toolkit
mockworld is one of the Swarm Proof projects for building and testing reliable agents:
| Project | What it does |
|---|---|
| stampede | Point a herd of realistic agents at your system before real ones arrive |
| mockworld ← you are here | A synthetic internet for agents — fake Stripe, Gmail, exchange, instantly |
| mcp-probe | The CI quality suite for MCP servers — lint, contract-test, benchmark, load |
| costbomb | Denial-of-wallet fuzzing — find the inputs that make your agent spend $500 |
| exactly-once | Idempotency middleware so agent side-effects fire once |
| agent-postmortems | A structured incident database + post-mortem standard for agent failures |
| awesome-agent-reliability | The curated map of the field |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mockworld_mcp-0.3.1.tar.gz.
File metadata
- Download URL: mockworld_mcp-0.3.1.tar.gz
- Upload date:
- Size: 146.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d3358cd1fc38bb17d1c3d485c4c29757ac2bdf018a8cf4caa2bdb6228b36bae
|
|
| MD5 |
189e47e980053145b83f5da636c773a4
|
|
| BLAKE2b-256 |
c37e82c679dd589ec49d3cac7e5ce56bf0c8a54b6bc3ba0c0e6999d46f749349
|
Provenance
The following attestation bundles were made for mockworld_mcp-0.3.1.tar.gz:
Publisher:
release.yml on swarmproof/mockworld
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mockworld_mcp-0.3.1.tar.gz -
Subject digest:
2d3358cd1fc38bb17d1c3d485c4c29757ac2bdf018a8cf4caa2bdb6228b36bae - Sigstore transparency entry: 2710212930
- Sigstore integration time:
-
Permalink:
swarmproof/mockworld@727e8bf7fd16cd819baa802675c37228201969e5 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/swarmproof
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727e8bf7fd16cd819baa802675c37228201969e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mockworld_mcp-0.3.1-py3-none-any.whl.
File metadata
- Download URL: mockworld_mcp-0.3.1-py3-none-any.whl
- Upload date:
- Size: 102.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0fdedeb904403dd471520fde2aa4c9284f48cc53a83eb4435773798621edcc1
|
|
| MD5 |
c5161dd36bc56ac15d68969a52672357
|
|
| BLAKE2b-256 |
eaedc659f91c1de58e3acc59d528ca04b5382270348d8c3b5b8e94bf83f3a528
|
Provenance
The following attestation bundles were made for mockworld_mcp-0.3.1-py3-none-any.whl:
Publisher:
release.yml on swarmproof/mockworld
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mockworld_mcp-0.3.1-py3-none-any.whl -
Subject digest:
b0fdedeb904403dd471520fde2aa4c9284f48cc53a83eb4435773798621edcc1 - Sigstore transparency entry: 2710213165
- Sigstore integration time:
-
Permalink:
swarmproof/mockworld@727e8bf7fd16cd819baa802675c37228201969e5 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/swarmproof
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@727e8bf7fd16cd819baa802675c37228201969e5 -
Trigger Event:
push
-
Statement type: