SimuLoom MCP
Contract-driven service virtualization and synthetic test-data management server that enables simulating APIs from OpenAPI contracts through MCP tools.
README
SimuLoom MCP
SimuLoom is an open-source control plane for contract-driven service virtualization and synthetic test-data management. An approved OpenAPI contract remains the source of truth; the same deterministic application services are available through REST and MCP.
Status: early MVP (
v0.7.0). All example records are fictional and synthetic.
What works in this milestone
- Analyze an OpenAPI 3.x contract and calculate a stable fingerprint.
- Create a versioned local simulation workspace.
- Generate reproducible synthetic requests from arbitrary OpenAPI JSON schemas.
- Populate path, query, header, cookie, and JSON request-body inputs.
- Compile successful OpenAPI responses into WireMock mappings.
- Preview validation cases before deployment and cover every contract operation.
- Inspect generated datasets through REST or MCP resources.
- Turn synthetic member records into exact, correlated request/response mappings.
- Return a deterministic 404 response for unknown synthetic member IDs.
- Activate normal, slow, unavailable, and deterministic intermittent profiles.
- Simulate a contract-backed
SUBMITTED → PROCESSING → COMPLETEDjourney. - Execute live validation cases against WireMock and validate 2xx response schemas.
- Calculate operation/scenario coverage and capture unmatched WireMock traffic.
- Publish machine-readable JSON and human-readable HTML evidence.
- Export reproducible, Git-friendly
simulation.yamlbundles. - Safely import portable bundles and regenerate mappings from approved source artifacts.
- Authenticate REST and MCP clients with role-scoped API keys.
- Record request outcomes in a tamper-evident JSONL audit chain.
- Deploy mappings through the WireMock Admin API.
- Invoke the workflow through REST or MCP Streamable HTTP.
Architecture
flowchart TD
A[REST clients] --> C[Shared application services]
B[MCP clients] --> C
C --> D[Contract compiler]
C --> E[Synthetic data engine]
C --> F[WireMock adapter]
F --> G[WireMock runtime]
Run with Docker
docker compose up --build
- REST and Swagger UI:
http://localhost:8000/docs - MCP Streamable HTTP:
http://localhost:8000/mcp - WireMock runtime:
http://localhost:8080
Run locally
uv sync --extra dev
uv run uvicorn simuloom.main:app --reload
Run WireMock separately or override WIREMOCK_URL to point to an existing instance.
Authentication and roles
Authentication is disabled by default for local evaluation. Enable it with environment
variables or copy .env.example to a private .env file and replace every example secret:
export SIMULOOM_AUTH_ENABLED=true
export SIMULOOM_API_KEYS='{
"replace-viewer-key": {"subject": "reviewer", "role": "viewer"},
"replace-operator-key": {"subject": "qa-engineer", "role": "operator"},
"replace-admin-key": {"subject": "platform-owner", "role": "admin"}
}'
export SIMULOOM_AUDIT_SIGNING_KEY='replace-with-a-long-random-secret'
When authentication is enabled, SimuLoom refuses to start without at least one valid key.
Clients can send either Authorization: Bearer <key> or X-API-Key: <key>. The same headers
protect /mcp.
| Role | Access |
|---|---|
viewer |
Analyze contracts and read simulations, datasets, plans, manifests, exports, and reports |
operator |
Viewer access plus create, generate, compile, profile, deploy, validate, and import |
admin |
Operator access plus reset all WireMock mappings and inspect audit evidence |
curl -H "Authorization: Bearer $SIMULOOM_KEY" \
http://localhost:8000/api/v1/simulations/example-id/manifest
Terminate TLS in front of SimuLoom outside local development. Keep API keys and the audit signing key in a secret manager; never commit them to Git.
REST quick start
Convert the YAML example to JSON or use the Swagger UI to submit it as the contract
field in these calls:
POST /api/v1/contracts/analyze
POST /api/v1/simulations
POST /api/v1/simulations/{id}/data
GET /api/v1/simulations/{id}/data
POST /api/v1/simulations/{id}/compile
PUT /api/v1/simulations/{id}/profiles/{profile}
POST /api/v1/simulations/{id}/validation/plan
POST /api/v1/simulations/{id}/deploy
POST /api/v1/simulations/{id}/validate
GET /api/v1/simulations/{id}/reports/latest
GET /api/v1/simulations/{id}/reports/latest/html
POST /api/v1/simulations/{id}/export
GET /api/v1/simulations/{id}/manifest
GET /api/v1/simulations/{id}/export/bundle
POST /api/v1/simulations/import
GET /api/v1/audit/events
GET /api/v1/audit/verify
The simulation creation request shape is:
{
"name": "Eligibility Demo",
"contract": {
"openapi": "3.1.0",
"info": {"title": "Example", "version": "1.0.0"},
"paths": {
"/ping": {
"get": {
"operationId": "ping",
"responses": {"200": {"description": "OK"}}
}
}
}
}
}
Use either complete example from examples/catalog-orders/openapi.yaml or
examples/benefits-eligibility/openapi.yaml; the shortened object above only illustrates
the envelope.
Generic OpenAPI workflow
For contracts outside the eligibility example, POST /simulations/{id}/data generates
deterministic contract-cases. SimuLoom cycles through contract operations and derives
fictional inputs from parameter and request-body schemas. Common JSON Schema features include
objects, arrays, local $ref, allOf, oneOf, anyOf, enums, constants, defaults, examples,
numeric bounds, string lengths, and common formats such as date, UUID, email, and URI.
POST /api/v1/simulations/{id}/data
{"records": 6, "seed": 1207}
GET /api/v1/simulations/{id}/data
POST /api/v1/simulations/{id}/validation/plan
{"max_dataset_cases": 6}
Each generated case records its operation, resolved path and query, required headers, JSON body, expected success status, and schema-derived response. Exact case mappings receive a higher WireMock priority while contract-level mappings remain available as fallbacks. If the stored dataset does not cover every operation, the validation planner adds deterministic baseline cases so operation coverage remains complete.
The current generic engine targets JSON request/response operations with local OpenAPI references. External references, callbacks, webhooks, multipart bodies, and authentication token generation remain future extensions.
Eligibility accelerator
After generating data and compiling, each generated member can be called directly:
GET http://localhost:8080/eligibility/SYN-1207-000001
The response uses the correlated status, plan, and effective date from that member's
synthetic dataset record. Any other member ID returns 404 MEMBER_NOT_FOUND.
Behavior profiles
Activate a profile before deployment:
PUT /api/v1/simulations/{id}/profiles/slow
{"fixed_delay_ms": 2500, "failure_status": 503}
| Profile | Compiled behavior |
|---|---|
normal |
Contract and dataset responses without injected disruption |
slow |
Adds a fixed response delay to every compiled mapping |
unavailable |
Returns the configured 5xx status with a controlled error body |
intermittent |
Deterministically alternates normal and 5xx responses |
The intermittent profile is deterministic so the same test sequence can be reproduced. Contract-backed business journeys retain their own state machine.
Stateful journey
The approved example contract contains asynchronous eligibility operations:
POST /eligibility/requests
→ 202 {"requestId":"REQ-SYN-001","status":"SUBMITTED"}
GET /eligibility/requests/REQ-SYN-001
→ 200 {"status":"PROCESSING"}
GET /eligibility/requests/REQ-SYN-001
→ 200 {"status":"COMPLETED"}
Validation evidence
Deploy the current compiled bundle before running live validation:
POST /api/v1/simulations/{id}/deploy
{"reset_existing": false}
POST /api/v1/simulations/{id}/validate
{"max_dataset_cases": 3, "reset_runtime_state": true}
The evidence engine:
- Resets WireMock request and scenario state when requested.
- Executes generic contract cases or the specialized eligibility scenarios.
- Compares actual and expected HTTP statuses.
- Validates successful JSON responses against the approved OpenAPI schemas.
- Calculates operation and scenario-category coverage.
- Reads the WireMock request journal and counts unmatched requests.
- Saves
reports/latest.jsonandreports/latest.html.
The HTML report provides a compact dashboard and a case-by-case evidence table. A failed schema assertion, unexpected status, execution error, or unmatched request makes the overall report fail.
Portable simulations
Exporting a simulation produces a deterministic ZIP archive containing a versioned
simulation.yaml, its approved OpenAPI contract, the active behavior profile, and any
synthetic dataset. The manifest records contract and dataset fingerprints, making changes
reviewable in Git and integrity-checkable during import.
apiVersion: simuloom.io/v1alpha1
kind: Simulation
metadata:
name: Eligibility Demo
spec:
contract:
path: contract.json
fingerprint: 725faa5388ca1bc1
behavior:
profile:
name: normal
fixedDelayMs: 2000
failureStatus: 503
Download a bundle with GET /api/v1/simulations/{id}/export/bundle. Import one as a
multipart file named bundle with POST /api/v1/simulations/import.
Imports reject unknown or duplicate artifacts, unsafe paths, oversized archives, fingerprint mismatches, non-synthetic records, and behavior-profile drift. Bundled mappings are never trusted: SimuLoom recompiles them from the validated contract, dataset, and profile.
MCP tools
analyze_contractcreate_simulationgenerate_test_dataplan_validationcompile_wiremock_bundleactivate_profiledeploy_simulationrun_validationexport_simulationimport_simulation_bundle
Read-only simulation metadata is available as
simulation://{simulation_id}/manifest.
The portable YAML is available as
simulation://{simulation_id}/portable-manifest.
The current synthetic dataset is available as
dataset://{simulation_id}/current.
The latest evidence is available as evidence://{simulation_id}/latest.
Deployment preserves existing WireMock mappings by default. Set reset_existing explicitly
only when SimuLoom owns the entire target WireMock instance. This reset requires admin.
Audit evidence
Every authenticated REST or MCP request records its subject, role, non-secret key identifier,
method, path, response status, outcome, request ID, and duration in audit/events.jsonl under
the configured workspace. API-key values and request/response bodies are never recorded.
Each event includes the previous event hash. When SIMULOOM_AUDIT_SIGNING_KEY is set, the
chain uses HMAC-SHA256; otherwise it uses an unkeyed SHA-256 chain suitable for local demos.
Admins can retrieve recent events from /api/v1/audit/events and verify the complete chain at
/api/v1/audit/verify. SimuLoom also verifies the existing chain during startup and refuses to
append to a corrupted log.
Guardrails
- SimuLoom does not generate or alter API contracts using an LLM.
- Only approved OpenAPI input is compiled.
- Generated example datasets are marked
synthetic: true. - Never copy client endpoints, schemas, payloads, credentials, or production data into a public simulation.
- Review
SECURITY.mdbefore exposing SimuLoom outside a local development environment.
Next milestones
- Pluggable data generators and runtime adapters beyond WireMock.
- Schema-derived negative, boundary, and pairwise validation cases.
- External identity-provider integration and short-lived credentials.
License
MIT. WireMock is a separate Apache-2.0-licensed project and is consumed as an external runtime container.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.