Guides

The MCP Server

Gostly ships a Model Context Protocol server so an AI agent — Claude Desktop, Cursor, or any MCP client — can inspect and configure a deterministic mock environment. The current catalog covers services and mocks, coverage, traffic evidence, drift, fidelity, faults, isolated episodes, training, evaluation, and scenario-pack preflight. tools/list returns only the tools allowed for the caller and enabled deployment features. MCP is a licensed, Team-tier capability in the self-hosted product.

What it is

The MCP server is a thin, tenant-scoped control surface served by the control-plane API on the same port as the rest of the REST API. It supports the stable 2025-11-25 revision and retains 2025-03-26 compatibility:

POST http://localhost:8000/mcp
X-API-Key: <your-api-key>
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2025-11-25

It implements the stable lifecycle (initialize, then notifications/initialized) plus ping, tools/list, and tools/call. It holds no server-side MCP session store, so any request can be served by any instance. Subsequent requests carry the negotiated revision in MCP-Protocol-Version; a missing header follows the stable specification's explicit 2025-03-26 compatibility assumption. There is no separate process or port. Each call passes the control plane's existing session-or-key authentication and tenant scope. The same license snapshot and authorization policy filter both tools/list and tools/call.

Gostly has no server-to-client MCP message stream, so an authenticated GET /mcp returns 405 with Allow: POST. Browser callers must exactly match MCP_ALLOWED_ORIGINS; normal server clients omit Origin. Raw POST bodies are capped by MCP_MAX_REQUEST_BODY_BYTES (1 MiB by default) before UTF-8 decoding or JSON parsing.

Team tier

The /mcp endpoint is gated behind the mcp feature. Unlicensed or lower-tier deployments receive a license-shaped 403. Training and evaluation tools additionally require the inference feature, fault tools require chaos, and episode calls require an agent started with GOSTLY_EPISODES=1. Unauthorized or unavailable tools are omitted from discovery.

Connecting a client

For an inspection-only client, generate a user API key in Settings; the full key is shown only once. User keys are deliberately read-only because they do not carry a user role or per-key scopes. A mutation-capable key client must use the system-managed service key. Signed-in dashboard sessions can read at viewer and mutate at member or above. If a request sends both a valid session cookie and a key, the session takes precedence.

Point the client at the endpoint with the chosen key in X-API-Key. For Claude Desktop, add the server to claude_desktop_config.json and restart:

{
  "mcpServers": {
    "gostly": {
      "url": "http://localhost:8000/mcp",
      "headers": {
        "X-API-Key": "<user-or-service-key>"
      }
    }
  }
}

Swap localhost:8000 for the host your control plane is reachable on if the client runs elsewhere. The discovered catalog will reflect that credential's access level and the deployment's enabled features.

The tools

The backend keeps one closed definition, handler, authorization, and public-projection registry. The catalog below mirrors that registry, while runtime discovery remains the authority for what a particular client may call. Read tools inspect state; mutate tools change control-plane or boot-local agent state.

Discover and inspect

Read the recorded world and find the weakest or missing coverage.

list_servicesRead

cursor?

List configured upstream services with cursor pagination.

list_mocksRead

method?, service_ids?, limit?, cursor?

Browse recorded mocks, optionally filtered by method or service.

get_coverageRead

(no arguments)

Summarize recordings, unique endpoints, and per-endpoint hit counts.

get_unmatchedRead

(no arguments)

List requests that reached MOCK mode without a recorded match.

get_wide_eventsRead

service_id?, workload_class?, since?, limit?

Read recent request events, with filters and a response-field glossary.

get_fidelityRead

service_id

Read materialized route and service fidelity scores, weakest route first.

get_driftRead

service_id?, unacknowledged_only?

Inspect schema and status drift, either per service or as a tenant rollup.

Build and serve

Register dependencies, record them, and prepare deterministic replay.

create_serviceMutate

name, upstream_url, routing_type?, routing_value?, description?

Register an upstream service and return its service ID.

transition_to_mockMutate

service_id

Queue the LEARN-to-MOCK job that builds and reloads a mock library.

create_mockMutate

request_method, request_uri, response_status, request_body?, response_body?, response_headers?, operation_key?

Persist a mock; the receipt reports persistence separately from serving application.

set_modeMutate

mode, operation_key?

Set LEARN, MOCK, or PASSTHROUGH and report desired versus applied serving state.

Train and evaluate

Manage service adapters and run held-out fidelity evaluation.

list_training_sessionsReadInference feature

cursor?

List fine-tuning sessions and their current lifecycle state.

start_trainingMutateInference feature

service_id

Build a training prompt from recorded traffic and start fine-tuning.

run_evalMutateInference feature

service_id, holdout_fraction?

Run and persist a synchronous holdout-fidelity evaluation.

activate_adapterMutateInference feature

session_id

Activate a ready adapter after serving and agent-boot acknowledgement succeeds.

Faults and episodes

Inject repeatable failures and operate isolated, boot-local rollouts.

get_chaos_presetsReadChaos feature

(no arguments)

List built-in fault-injection configurations for use with set_chaos.

set_chaosMutateChaos feature

service_id, config

Configure or clear per-service latency and error injection.

snapshot_episodeMutateAgent episodes enabled

name, operation_key?, agent_instance_id?, agent_boot_id?

Capture resource state and chaos RNG position on the current agent boot.

fork_episodeMutateAgent episodes enabled

episode, from_snapshot, operation_key?, agent_instance_id?, agent_boot_id?

Create an isolated rollout from a snapshot on the pinned agent boot.

reset_episodeMutateAgent episodes enabled

episode, from_snapshot?, mode?, operation_key?, agent_instance_id?, agent_boot_id?

Restore an isolated episode from a snapshot or wipe its boot-local state.

Scenario-pack preflight

Validate candidates without persisting a pack or admitting it to the agent.

author_scenario_packRead

pack

Return a canonical validated draft and recorded-world reference report.

validate_scenario_packRead

pack

Run advisory API-side checks and report what only the agent loader can decide.

One policy for discovery and execution

Viewer sessions may discover read tools; member, admin, and owner sessions may also use mutate tools. User-generated gsk_* keys are read-only. The system-managed service key can use read and mutate tools. Required license features are checked in addition to credential access, and a forged unavailable tool call fails as unknown or unauthorized.

A typical agent loop

A client should begin with tools/list and compose its workflow from the returned subset. A mutation-capable environment workflow will typically:

Discover

List services and mocks, then read coverage to establish the recorded world.

Inspect

Use unmatched requests, wide events, fidelity, and drift to find missing or stale behavior.

Build

Register a service, record in LEARN, transition recordings to mocks, or author a specific mock directly.

Stress

Apply an available chaos preset. When episodes are enabled, snapshot a baseline and fork isolated rollouts before resetting or wiping them.

Verify

Run an inference-gated holdout evaluation, or preflight a scenario-pack candidate without persisting or admitting it.

Discovery and execution use the same authorization decision. Tool results also pass a tool-specific public projection before they are returned. A read-only tools/call looks like this:

curl -X POST http://localhost:8000/mcp \
  -H "X-API-Key: $GHOST_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_drift",
      "arguments": { "unacknowledged_only": true }
    }
  }'

MCP controls the same environment; it does not introduce a separate request-matching path. See How It Works for the full cascade.

Boundaries and safety

The MCP server inherits the product's structural guarantees — it is a control surface, not a back door:

  • Authenticated and tenant-scoped. Calls use an existing login session, system service key, or user-generated key and operate within the resolved tenant. Session role or key type determines read versus mutate access.
  • Closed tool surface. At startup, definitions, handlers, access policies, and public projectors must name the same tools. An incomplete registration fails closed, and discovery and execution share one policy decision.
  • Projected public results. Tool responses pass explicit allowlists, scrubbing, and size bounds. Unsafe or oversized results fail instead of returning the handler's raw value.
  • Mutations are explicit. The current surface can change services, mocks, modes, adapters, fault settings, evaluations, and isolated episode state. reset_episode can wipe an explicit boot-local episode; scenario-pack tools only preflight candidates and never admit them to the agent.
  • Self-hosted boundary. The MCP endpoint runs in your Docker stack. Data returned to an MCP client follows that client's own deployment and trust boundary, so configure remote clients accordingly.

Licensed product vs. OSS proxy

The MCP server is part of the licensed self-hosted product (distributed as docker-compose + container images, no host CLI). The separate open-source proxy is a standalone product with its own command-line interface and does not ship this control-plane MCP surface.

Next steps