ShakerScan MCP
Status: shipped and contract-tested as of 2026-08-29.
ShakerScan includes a fail-closed MCP stdio adapter over the REST Command Arsenal and canonical
Hunt V2. Arsenal tools remain read-only. Hunt tools wrap /hunts directly and inherit its exact
target binding, approval, budget, evidence, and proof enforcement; arbitrary shell is never exposed.
Start it from the source/runtime directory:
./scanner.sh mcp
The same adapter runs without the engine from the shakerscan client
(pipx install shakerscan, uv tool install shakerscan, or the Homebrew tap; see
client.md):
shakerscan mcp --url https://scanner.example.com --token-file ./token
The scanner API must already be available at http://127.0.0.1:8080. Override
the origin with SHAKERSCAN_API_URL. Non-loopback origins are rejected unless
SHAKERSCAN_MCP_ALLOW_REMOTE_API=true is explicitly set.
Behind an authenticating gateway (for example a self-hosted Enterprise deployment that fronts
the API with service tokens), set SHAKERSCAN_API_TOKEN as well: the adapter sends it as
Authorization: Bearer on every call. A token is only ever sent over https://; the adapter
refuses to start with a token and a plain-http origin, and it never prints the token. The
product CLI (./scanner.sh hunt ..., scripts/v2_cli.py) honours the same variable with the
same rule.
SHAKERSCAN_API_URL=https://scanner.example.com \
SHAKERSCAN_MCP_ALLOW_REMOTE_API=true \
SHAKERSCAN_API_TOKEN=<service token> ./scanner.sh mcp
Example client configuration:
{
"mcpServers": {
"shakerscan": {
"command": "/absolute/path/to/shakerscan/scanner.sh",
"args": ["mcp"]
}
}
}
The adapter exposes two deliberately different trust levels:
Read-only Arsenal inspection:
shakerscan_targetsshakerscan_asm_gapsshakerscan_findingsshakerscan_evidence_manifestshakerscan_timelineshakerscan_plansshakerscan_tool_status
Target-bound Hunt V2 (including state-changing and target-facing operations):
shakerscan_hunt_skillsfor catalog metadata andshakerscan_hunt_skillfor global detailshakerscan_hunt_skill_suggestions,shakerscan_hunt_skill_read,shakerscan_hunt_skill_bind,shakerscan_hunt_skill_unbind, andshakerscan_hunt_skill_usagefor progressive, audited methodology useshakerscan_hunt_start,shakerscan_hunt_get, andshakerscan_hunt_queryshakerscan_hunt_capabilityfor capabilities returned by that Hunt's manifestshakerscan_hunt_candidate,shakerscan_hunt_candidate_update, andshakerscan_hunt_candidate_deleteshakerscan_hunt_verify,shakerscan_hunt_finish, andshakerscan_hunt_cancel
Arsenal tools read GET /arsenal/commands, require the mapped command to remain read_only risk,
and dispatch through the audited Arsenal endpoint. Hunt discovery reads GET /hunts/contract and
generates the start schema from the live authority contract. The MCP boundary uses only the
canonical goal name and sends the complete V2 body: schema version, target kind, policy, budgets,
credential references, capability allowlist, request-collection references, and optional
skill_ids. A run normally starts without one. Adaptive suggestions return at most three compact
records and no bodies; the planner loads exactly one relevant method through the Hunt-specific read
tool before binding it. MCP never auto-binds a methodology or changes authority.
Before capability execution, the adapter reloads GET /hunts/{id}, requires an active or
awaiting-planner run, finds the capability in that Hunt's returned manifest, and validates input
against its published schema. The client may provide an idempotency_key; if omitted, the adapter
generates one and returns it as mcp_idempotency_key so a retry can reuse the exact action identity.
The runtime still revalidates target binding, approval, budgets, evidence, and proof contracts.
Catalog/contract drift, redirects, oversized responses, unavailable APIs, and unexpected dispatch
results fail closed.
Tool annotations reflect these boundaries: Arsenal inspection and Hunt get/query are read-only; capability and verification operations are conservatively marked destructive and open-world; start, candidate create/update/delete, finish, and cancel are state-changing. Candidate updates cannot change identity or proof-owned fields; deletion expires the candidate while retaining its immutable audit record. Raw secrets, target-address overrides, planner argv, and arbitrary shell commands are not representable. Input schemas enforce UUIDs, enums, required/nested fields, patterns, uniqueness, and numeric bounds before dispatch. The transport also caps request and response sizes and rejects redirects.