chokepoint-finder-mcp
This server provides an MCP-based toolset to identify, rank, plan, and execute chokepoint remediation actions across a fleet, with emphasis on safety and verification.
Setup & Configuration: Guide first-run setup, test connectivity to data sources (Tenable, AWS, demo), without asking for secrets.
Ingest Findings: Load vulnerabilities, assets, and attack paths from Tenable, AWS Security Hub, or a synthetic demo dataset.
Rank Chokepoints: Greedy weighted max-coverage algorithm to find the smallest set of actions eliminating the most risk, with marginal coverage and attack-path disruption reported separately.
Pre-flight Safety Gates: Check EDR silence, change freezes, and blast radius from supplied evidence; returns PROCEED, REQUIRES_STAGING, HOLD_PARTIAL, or HOLD; fail-closed on missing/stale evidence.
Generate Remediation Payloads: Produce ticket-ready change requests with summary, justification, plan, and rollback notes.
Plan Execution: Build typed, ordered workflows with per-step approvals, canary-first waves, and CTI handoff, outputting a canonical v3 JSON manifest.
Supply Evidence: Relay EDR or change-freeze evidence from other MCP servers with provenance tracking and strict trust rules.
Mark Executed: Record execution of plan steps with confirmation matching plan hash, wave, and rescan digest.
Verify Deltas: Re-query sources and diff against baseline; fails closed, returning UNKNOWN/ERROR on any issue; only final-wave VERIFIED closes a change record.
Run Demo: Execute a full, deterministic walkthrough on synthetic data, demonstrating the entire loop including pre-flight refusals and wave-by-wave verification, clearly labeled as SIMULATED.
Allows relayed security evidence from Splunk (e.g., EDR silence, change freezes, blast radius) to be supplied to Chokepoint Finder's pre-flight gates with provenance and coverage tracking, informing HOLD/PROCEED decisions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@chokepoint-finder-mcpFind the highest-impact remediation actions for my security findings"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Chokepoint Finder MCP Server
The engine behind the Chokepoint Finder method: a FastMCP server with ten tools that turn thousands of findings into the smallest set of remediation actions that eliminates the largest share of risk, with fail-closed pre-flight safety gates, typed execution plans, and verification that refuses to report clean when it could not actually look.
Part of the Chokepoint Finder family: chokepoint-finder (the agent) · chokepoint-finder-skill (the portable method) · chokepoint-finder-playbook (the cross-vendor chain).
Quickstart (zero credentials)
uv sync
uv run python -m chokepoint_finder.demo # the full loop in the terminal
uv run python -m chokepoint_finder.report # a board-ready HTML report
uv sync --extra dev && uv run pytest # 167 testsThe demo estate is deterministic (seeded): every run shows the same collapse — 3,734 findings across 783 assets reduced to 7 actions covering 74% of weighted finding risk (1,700 findings) and severing all 22 known attack paths — plus a pre-flight refusal and a wave-by-wave simulated delta. Synthetic data, reproducible numbers, labelled SIMULATED in every report it produces. The demo can prove the mechanics but can never authorize a real change-record close.
Related MCP server: MCP SSDLC Security Toolkit
The ten tools
chokepoint_setup (guided plumbing, never asks for a secret in conversation,
defaults to the offline source so it cannot hang on a captive portal),
chokepoint_ingest (demo | tenable | aws | all), chokepoint_rank (greedy weighted
max-coverage, marginal ranking), chokepoint_supply_evidence (relay EDR or
change-freeze evidence in from another connected MCP server; coverage that could
clear a gate requires explicit human confirmation),
chokepoint_preflight (EDR silence, change freezes, blast radius → PROCEED /
REQUIRES_STAGING / HOLD_PARTIAL / HOLD), chokepoint_payload (CAB-ready change
request), chokepoint_plan (typed execution workflow routed to your MCP fleet,
per-step approvals, canary-first waves, CTI out-of-band handoff; pass
json_output=true for the complete canonical v3 manifest),
chokepoint_mark_executed (requires a matching plan hash, explicit confirmation,
the exact wave, a targeted-rescan digest, and a recent one-time approval receipt),
chokepoint_verify (fail-closed, plan/wave-bound delta; pass json_output=true for
the structured proof receipt),
chokepoint_demo (the whole wave-aware loop at once).
Five tools update only this process's session state: ingest, rank, evidence relay, execution accounting, and verification. None holds credentials for, or calls, an external write API. Planning, payload generation, setup, and the complete demo remain read-only at the MCP annotation boundary.
{
"mcpServers": {
"chokepoint-finder": {
"command": "uv",
"args": ["run", "--directory", "/path/to/chokepoint-finder-mcp", "chokepoint-mcp"]
}
}
}The safety model
Three properties, each enforced in code and asserted by tests in
tests/test_failclosed.py rather than promised in prose.
Evidence that is missing is not evidence of safety. Every gate reads typed
Evidence carrying its source, collection time and completeness. Evidence that is
unconfigured, failed, partial, truncated or stale reads as UNKNOWN, and UNKNOWN
produces HOLD. Forgetting to wire up a feed can only ever make the agent less
willing to act. An empty result from a healthy feed is a different thing —
ABSENT — and does clear the gate.
Evidence composes, the same way execution does. Chokepoint Finder holds no EDR,
SIEM or ITSM credentials and never will. It sees that telemetry anyway: your agent
queries whatever server provides it — CrowdStrike, SentinelOne, Splunk, Sentinel,
ServiceNow, a CTI platform — and relays the answer through
chokepoint_supply_evidence with its provenance intact. The trust rules do not
soften for relayed data: stale, partial or truncated input still reads UNKNOWN and
still holds, a future collection timestamp is rejected outright, and every verdict
built on relayed evidence prints [RELAYED by the operator's agent] next to its
source. Evidence that travelled through an agent is one link weaker than a direct
pull, and a human reading a HOLD deserves to know which one they are looking at.
The failure mode that matters — an agent queries an EDR, gets an error, and relays
nothing — leaves the channel UNKNOWN, so giving up produces a refusal rather than
a silent proceed.
Relayed evidence also carries an exact covered_asset_ids set. Free-text scope is
audit context only; if any proposed target is absent from that set, the gate holds.
The confirmation rule is asymmetric: adding detections or freezes inside coverage the
gate already has needs no confirmation because it can only make the decision more
cautious. Establishing, refreshing, replacing, or extending coverage can turn a HOLD
into PROCEED. The first call therefore refuses with a SHA-256 preview digest. The
agent must present the exact evidence and digest to a human, then retry with
confirm=true, that digest, a recent confirmer identity/time, and a one-time receipt
ID; it may not self-attest. Changing the payload changes the digest, and replaying the
receipt is refused.
Honest relay limitation. The same agent is still the transport. A human who
confirms a relay is attesting to the evidence the agent handed them, not to a direct
read of the EDR, SIEM, or ITSM console. confirm=true does not make the relay an
authoritative pull. What it buys is a deliberate control boundary: fabrication that
could widen action now requires active human affirmation instead of happening silently
inside one tool call.
Verification re-queries the authoritative source and fails closed.
chokepoint_verify runs a fresh collection and grades it: VERIFIED, PARTIAL,
NOT_FIXED, UNKNOWN or ERROR. Auth failure, timeout, malformed payload,
truncation, partial collection and stale evidence all resolve to UNKNOWN/ERROR,
and only a non-simulated, final-wave VERIFIED result permits closing a change
record. Verification also requires the re-query to match the baseline tenant/account,
credential principal, query and region scope. An empty result set against a
non-empty baseline is treated as a broken query unless the approved action was expected
to retire the entire baseline and the collector independently proves complete, exact
asset coverage. This prevents an outage from masquerading as a fix without making a
genuine all-clear impossible. In demo mode the re-query is a simulation, says so in its
status line, and can never authorize closure.
Every external mutation requires approval bound to the exact plan. Steps carry
a structural mutates_external_state flag, and the Step constructor refuses to
build one that mutates without requiring approval. "External" is drawn deliberately
wide: opening a change ticket, notifying a SOC, and launching a scan all count, not
just touching infrastructure. Approval binds to ExecutionPlan.plan_hash; change
the source scope, complete finding IDs, complete targets, exact mutation args, ordered
waves, or held assets and the full SHA-256 hash changes, voiding the earlier approval.
Each wave must be recorded and verified before the next becomes eligible. The server
holds no write credentials and calls no write API — execution
happens through the operator's own MCP servers, as a separate human-invoked phase.
The human Markdown is intentionally bounded and omits bulk identifier arrays; the full
v3 JSON manifest carries exact identifiers, mutation arguments, and ordered steps. For
a three-wave plan, target mutation, targeted rescan, execution receipt, and proof are
physically interleaved for wave 1 before any wave-2 target is touched. Proof binds to
the approved plan hash, exact wave, authoritative scope, and rescan receipt.
Attack-path credit is also evidence-bound. A fix severs a path only when the source explicitly maps that remediation target to the path; mere overlap between a target asset and a path node is not counted as disruption.
How this is tested
167 tests, of which the load-bearing ones are in tests/test_failclosed.py:
they are written to fail if a safety claim stops being true, which is the only
reason a safety claim is worth making.
Each control was verified by reverting it and confirming the test catches it — a regression test that passes against the broken code proves nothing. That exercise found real gaps twice: an injection test that only checked the sanitiser rather than the call sites, and an AWS fixture whose STS branch was never reached.
What the suite covers: every way a re-query can fail (auth, timeout, malformed payload, truncation, staleness, wrong scope) resolving to UNKNOWN or ERROR and never to clean; unconfigured, stale or under-scoped evidence holding a gate; approval bound to a plan hash and refused when the plan changes; wave ordering that cannot skip ahead; coverage arithmetic that cannot exceed 100%; finding identity stable under reordering; and prompt-injection payloads driven through the real MCP tools — not the sanitiser in isolation — asserting no rendered line can become a model instruction.
The attack-path collector was additionally verified against a live Tenable One tenant: 2,285 vectors, 24 distinct remediations, with partial coverage and unbound vectors counted and surfaced rather than silently dropped.
The ranking, and what is actually guaranteed
The library default (ranking_mode="risk", with both early stops disabled) is greedy
on marginal objective gain under
a cardinality constraint. The objective — covered finding risk plus a bonus per
newly severed attack path — is monotone and submodular, so the classical
(1 − 1/e) ≈ 63% approximation bound applies (Nemhauser, Wolsey & Fisher 1978), and
no polynomial algorithm does better unless P = NP (Feige 1998).
The MCP shortlist intentionally uses an early target-share stop and prints that the
classical guarantee does not apply to that run. More generally, the early stops
(target_share, min_marginal_share) trade that k-cardinality bound for a shorter
list, and the bound is over the objective, not over any single reported percentage.
ranking_mode="effort_weighted" divides marginal gain by effort^exponent. It is
useful and it carries no approximation guarantee — ratio-greedy under a
cardinality constraint can be arbitrarily bad. It is opt-in and named honestly
rather than sold under a theorem it does not satisfy.
Coverage is reported as two numbers, never blended. Finding-risk coverage has total finding risk as its denominator; attack-path disruption has the path count. Mixing them is how a tool reports more than 100% of something, so the code keeps the path bonus out of every human-facing percentage.
Live sources
Tenable Vulnerability Management via the export APIs
(uv pip install ".[tenable]", TENABLE_ACCESS_KEY / TENABLE_SECRET_KEY), and
AWS via Security Hub + IAM + EC2 security groups (uv pip install ".[aws]",
standard credentials, read-only, SecurityAudit suffices). Copy .env.example to
.env, or use the environment. Run chokepoint_setup first: it reports
READY / TO DO / FAILED per source with the exact next step.
Finding identity is derived from source-natural keys — (asset uuid, plugin id, port/protocol) for Tenable, and the Security Hub finding ID plus every sorted resource
and vulnerability identity for AWS — never from
enumeration order, so a re-query that returns rows in a different order still
compares correctly against the baseline.
Limitations
These are the things this tool does not do. They are listed because a security tool that hides its edges is worse than one that has them.
The demo estate is synthetic. Its numbers are illustrative, not benchmarks.
No bundled EDR/SIEM/ITSM collector, by design. Evidence comes from the MCP servers you already have connected, relayed in through
chokepoint_supply_evidence(see above). This tool holds no credentials for CrowdStrike, Splunk or ServiceNow and is not trying to. The consequence to be aware of: if nobody relays a channel, it staysUNKNOWNand the gates hold. Refusing is the safe direction, but an unattended run against live data will refuse a lot until the evidence path is wired up.Attack paths need Tenable One APA. The Tenable collector reads APA vectors -- what Tenable calls attack paths -- paginating to the tenant's reported total, and binds each to the plugin APA says severs it. Deliberately not the findings endpoint: a finding is a technique that can occur in many paths (one observed finding sat on 39 vectors), so counting findings as paths yields a denominator that is neither the path count nor a stable quantity. A path is credited only when APA names the remediation that breaks it; node overlap earns nothing. Without an APA licence -- and on the AWS collector, which has no equivalent surface -- zero paths are collected and the reason is recorded, rather than reported as "this estate has no attack paths". Unbound vectors, vectors referencing assets outside the ingest, and any short read are counted and surfaced, so partial coverage is never presented as complete.
Collectors are read-only and not load-tested against very large tenants; exports are capped, and hitting the cap marks the collection truncated, which blocks verification rather than degrading it silently.
Ranking quality tracks metadata quality. Findings with no fix-sharing key cannot converge into a chokepoint. Garbage in, defensible out — every ranking cites the evidence behind it, so a wrong answer is visible rather than opaque.
HTTP is loopback-only development transport. It has no authentication or session isolation and uses one process-global state, so the CLI refuses non-loopback binds. Use stdio for real operator/tenant boundaries and a separate process per session.
Finding text is untrusted input. Titles and remediation strings are normalized into bounded labels or escaped
<untrusted-scanner-data>JSON, never interpreted as instructions; prompt-injection tests exercise the model-facing rendering boundary.
Authors: Zane K (@zkilling), Tarek H (@tarhou), AJ (@Ethosmos). MIT license.
Available Tools
10 toolschokepoint_demoRun the full demoBRead-only
The four-beat walkthrough on the deterministic simulated estate: the wall, the collapse, the refusal, and wave-by-wave proof.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already signals a safe read operation, so the description does not need to restate safety. It adds some context by outlining the four-beat structure, but it does not explain what these beats actually entail or what side effects (if any) occur, such as whether state changes or outputs are produced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, compact sentence that front-loads the core idea ('four-beat walkthrough') and then lists the beats. It is concise, but the cryptic beat names add color rather than clarity, and the sentence could be more straightforward without losing brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, a read-only hint, and an output schema, the description is nearly sufficient. However, it does not connect the demo to the surrounding workflow (e.g., whether it should be run after setup or before verify), and the abstract language leaves the tool's actual behavior under-specified for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, and the baseline for 0-parameter tools is 4. The description does not need to explain parameters because there are none, and the 100% schema coverage leaves no ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the tool as a 'four-beat walkthrough' on a 'deterministic simulated estate', which clearly distinguishes it from sibling tools like setup, ingest, or verify. The title 'Run the full demo' reinforces the action, but the metaphorical phrasing ('the wall, the collapse, the refusal') is less direct than an explicit statement like 'runs the complete demo'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given on when to use this tool versus the available siblings. The description implies it is for running a full demo walkthrough, but it does not state conditions, prerequisites, or alternatives, leaving the agent to infer usage from the name and title alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_ingestIngest findingsA
Load findings, assets and attack paths from a source and build the engine.
| Name | Required | Description | Default |
|---|---|---|---|
| source | No | Data source: demo | tenable | aws | all | demo |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds context about the types of data loaded (findings, assets, attack paths) and indicates the tool constructs an engine. Annotations already signal a write operation (readOnlyHint=false) and non-destructive behavior (destructiveHint=false), so the description does not contradict them, but it does not disclose deeper side effects like idempotency or data replacement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the action and resources, with no redundant or filler words. It is concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, output schema present), the description covers the core function adequately. It does not mention prerequisites like running setup first, but the pipeline context and sibling tools make this a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter 'source' is fully documented in the schema with allowed values and a default. The description's phrase 'from a source' aligns with the schema but adds no additional semantic detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Load') and identifies the resources (findings, assets, attack paths) and the goal ('build the engine'). It clearly distinguishes the tool from siblings like chokepoint_setup or chokepoint_rank, which serve different pipeline stages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is the ingestion step in the chokepoint pipeline (loading data to build the engine). However, it does not explicitly state when to use this tool versus alternatives, nor does it mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_mark_executedMark a chokepoint executedA
Record that the plan's steps were executed (through other MCP servers, by the operator's agent), arming verification with expected retirements.
This tool mutates nothing outside the finder's own accounting. It refuses without explicit confirmation, refuses a plan hash that does not match the current plan, refuses a HOLD verdict outright, and excludes assets held by pre-flight.
| Name | Required | Description | Default |
|---|---|---|---|
| rank | Yes | Chokepoint rank from chokepoint_rank | |
| wave | No | Exact rollout wave being recorded. Required for a staged plan. | |
| confirm | No | Human approval flag. Must be true. | |
| plan_hash | No | Plan hash from chokepoint_plan. Binds this approval to the exact plan reviewed. | |
| approval_id | No | Unique one-time operator approval ID. | |
| approved_at | No | UTC ISO 8601 approval time. | |
| approved_by | No | Identity of the approving operator. | |
| rescan_evidence_digest | No | Digest of the completed targeted-rescan receipt for this wave. | |
| approval_evidence_digest | No | Digest of plan_hash, wave, and rescan receipt shown to the human. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint=false and destructiveHint=false. The description adds substantial behavioral detail: it mutates nothing outside internal accounting, requires explicit confirmation, rejects non-matching plan hashes and HOLD verdicts, and excludes pre-flight-held assets. This goes well beyond the annotations and gives the agent clear expectations for side effects and refusal conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded. The first sentence states the action, and the second paragraph lists constraints in a scannable list-like sentence. No filler words; every clause contributes meaningful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter state-changing tool, the description covers purpose, side-effect boundaries, all refusal conditions, and relationship to other servers/tools. Output schema exists, so return-value details are not the description's burden. It is complete enough for an agent to invoke safely and correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the meaning of key parameters: confirm must be true, plan_hash must match the current plan, and HOLD verdicts/pre-flight assets are excluded — which clarifies rank, wave, and approval fields. This lifts it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Record') with a clear resource ('that the plan's steps were executed') and states the downstream effect ('arming verification with expected retirements'). This distinguishes it from sibling tools like chokepoint_verify and chokepoint_plan.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool: after plan steps have been executed through other MCP servers, and before verification. It also states important preconditions (explicit confirmation, matching plan hash, no HOLD verdict). It does not explicitly name alternative tools, but the context is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_payloadGenerate remediation payloadARead-only
Ticket-ready remediation payload for a chokepoint: summary, justification, change plan, rollback note. Paste into Jira/ServiceNow or hand to a ticketing MCP. Generates text only; it opens nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| rank | Yes | Chokepoint rank from chokepoint_rank |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include readOnlyHint=true, and the description reinforces this by stating 'Generates text only; it opens nothing.' This adds behavioral clarity beyond the annotation, confirming no side effects. No contradictions or missing relevant behavioral details for a simple generation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loaded with the tool's purpose and contents, followed by usage context and side-effect clarification. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter, 100% schema coverage, an output schema, and simple read-only behavior, the description fully covers what the tool does, what it produces, and how to use the result. It is complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the only parameter 'rank' is described as 'Chokepoint rank from chokepoint_rank'. The description does not add extra parameter semantics, but the schema fully defines the parameter, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Generates text only') with a specific resource ('remediation payload for a chokepoint') and lists contents (summary, justification, change plan, rollback note). It distinguishes from siblings by emphasizing ticket-readiness and that it 'opens nothing.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use when a ticket-ready remediation payload is needed, to paste into Jira/ServiceNow or hand to a ticketing MCP. It does not explicitly name alternatives or exclusions, but the focus on text generation and 'opens nothing' helps disambiguate from action-oriented siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_planBuild the execution planARead-only
Typed, ordered workflow for executing a chokepoint through the operator's connected MCP servers.
Chokepoint Finder holds no write credentials by design and executes nothing itself. Each step names a capability (aws-ec2, ssm-patch, ci-cd, tenable, ticketing); route it to whatever connected MCP server provides it. Steps marked MUTATES change state outside this process and need an explicit operator go quoting the plan hash. A HOLD pre-flight yields no plan, only the evidence. Held assets are excluded from every step.
| Name | Required | Description | Default |
|---|---|---|---|
| rank | Yes | Chokepoint rank from chokepoint_rank | |
| json_output | No | Return the full canonical manifest JSON for a runner. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant context beyond the readOnlyHint annotation, stating the tool 'holds no write credentials by design and executes nothing itself.' It also discloses key behaviors such as requiring 'an explicit operator go quoting the plan hash' for MUTATES steps and that 'Held assets are excluded from every step,' which are not captured by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is composed of four focused sentences, each covering distinct aspects: what the plan is, design constraints, step routing, mutation approval, and HOLD behavior. There is no filler or redundancy, and the structure front-loads the main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and readOnlyHint annotation, the description covers essential behavioral rules, including HOLD outcomes, asset exclusion, and mutation approval. It does not describe the plan's exact JSON structure, but that is handled by the output schema, making this sufficiently complete for a planning tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides complete descriptions for both parameters, including the rank source and json_output behavior. The description does not add parameter semantics beyond confirming the plan is typed and ordered, so it meets the baseline for 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the tool as producing a 'Typed, ordered workflow for executing a chokepoint' and clarifies that it builds a plan rather than executing it, saying 'executes nothing itself.' This distinguishes it from sibling tools like preflight and verify, though the verb 'build' comes mainly from the title rather than the description itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use after a pre-flight: 'A HOLD pre-flight yields no plan, only the evidence,' and explains that MUTATES steps require operator go. However, it does not explicitly name alternative tools or state when to choose plan over payload or other siblings, so usage guidance is more implied than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_preflightPre-flight a chokepointARead-only
Evidence gates before acting: EDR silence, change freeze, blast radius.
Verdicts: PROCEED, REQUIRES_STAGING (sound, but too wide for one window -- canary-first waves are supplied), HOLD_PARTIAL (act on clean assets, hold the rest), HOLD. Evidence that is missing, stale, partial or failed reads as UNKNOWN and produces HOLD: this gate never clears what it cannot see.
| Name | Required | Description | Default |
|---|---|---|---|
| rank | Yes | Chokepoint rank from chokepoint_rank |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses key behaviors: missing/stale/failed evidence reads as UNKNOWN and produces HOLD, and the gate never clears what it cannot see. This adds meaningful context about how evidence is evaluated and verdicts are derived.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: the first states the purpose, the second lists verdicts with a useful clarification, and the third explains the edge-case behavior. It is front-loaded and free of fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter and presence of an output schema, the description covers the essential behavioral details: gates checked, verdicts, and evidence handling. It fully explains the tool's decision logic without needing to document return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single 'rank' parameter, and the schema already states 'Chokepoint rank from chokepoint_rank'. The tool description adds no further parameter meaning, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool evaluates evidence gates before acting, listing specific gates (EDR silence, change freeze, blast radius) and producing concrete verdicts. This distinguishes it from siblings like chokepoint_ingest or chokepoint_plan.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool: before acting, as a gating step. Verdicts like REQUIRES_STAGING and HOLD_PARTIAL clarify subsequent actions. However, it does not explicitly contrast with alternatives or state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_rankRank chokepointsA
Greedy weighted max-coverage over synthesized actions. Returns the shortlist.
Each chokepoint's value is marginal: what it eliminates GIVEN everything ranked above it is done. Finding-risk coverage and attack-path disruption are reported as two separate numbers, never blended.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many chokepoints to select |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state non-destructive and non-read-only, adding little. The description goes beyond this by explaining the key behavioral trait: chokepoint value is marginal (what it eliminates given higher-ranked items are done) and that finding-risk and attack-path disruption are reported separately, not blended. This is valuable context for interpreting results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the tool's core action and result. The second sentence adds essential algorithmic nuance without extraneous detail. Every word contributes useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only one optional parameter, an output schema, and annotations, the description provides a coherent conceptual model: greedy ranking with marginal values and separate metrics. It does not mention prerequisites such as prior ingestion or planning steps, but the sibling tool list and the phrase 'over synthesized actions' offer some context. Slightly incomplete on workflow placement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single optional 'top' parameter, whose description 'How many chokepoints to select' is clear. The tool description does not add extra parameter semantics, but it is not needed given the schema already fully documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The title 'Rank chokepoints' combined with 'Returns the shortlist' and the mention of chokepoints being 'ranked above it' clearly indicate the tool produces an ordered selection of chokepoints. The algorithm name 'Greedy weighted max-coverage' is specific but somewhat opaque, slightly reducing clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given about when to use this tool versus siblings like chokepoint_plan, chokepoint_payload, or chokepoint_mark_executed. The phrase 'over synthesized actions' implies it should be used after action synthesis, but the description does not state this prerequisite or any alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_setupGuided setupARead-only
First-run hand-holding. Checks what is configured, tests connections, and gives the exact next step for anything missing, including where in the Tenable and AWS UIs the credentials live.
Defaults to demo, which makes no network calls. Pass tenable, aws or
all to test live connectivity -- those probe remote endpoints and can be
slow on a captive-portal network.
Never asks for a secret in conversation: keys go in the environment or a .env file next to the server. Safe to run repeatedly; run it again after each fix until everything you need says READY.
| Name | Required | Description | Default |
|---|---|---|---|
| source | No | Which source to check: demo | tenable | aws | all | demo |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behaviors beyond the annotations: it explains the demo mode makes no network calls, while live modes 'probe remote endpoints and can be slow on a captive-portal network.' It also reveals security handling ('Never asks for a secret in conversation') and idempotency ('Safe to run repeatedly'). These are valuable details not covered by readOnlyHint or openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently organized into three short paragraphs: what it does, behavioral modes, and safety/repeatability. Every sentence adds value, and the opening 'First-run hand-holding' immediately conveys the purpose. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all necessary aspects for a setup tool: purpose, usage modes, network behavior, security, and repeatability. With a schema, annotations, and output schema present, there are no significant gaps. It even explains where credentials live in the Tenable and AWS UIs, which is highly contextual and aids the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes `source` as 'Which source to check: demo | tenable | aws | all,' but the description adds significant meaning by explaining the behavioral implications of each value (e.g., 'demo' makes no network calls, 'tenable'/'aws'/'all' test live connectivity and may be slow). This goes well beyond the schema's minimal description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'First-run hand-holding. Checks what is configured, tests connections, and gives the exact next step for anything missing.' It also differentiates itself from siblings by focusing on setup guidance and credential locations, making it distinct from tools like chokepoint_preflight or chokepoint_verify.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context: 'First-run hand-holding' implies use during initial setup, and 'run it again after each fix until everything you need says READY' specifies when to re-run. However, it does not explicitly name alternatives or state when not to use the tool, so it lacks the explicit 'vs alternatives' guidance seen in top-tier examples.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_supply_evidenceSupply evidence from another MCP serverA
Feed a pre-flight gate from an MCP server you already have connected.
Chokepoint Finder holds no EDR, SIEM or ITSM credentials and never will. This is how it sees that telemetry anyway: your agent queries whatever server provides it -- CrowdStrike, SentinelOne, Splunk, Sentinel, ServiceNow, a CTI platform -- and relays the answer here with its provenance. The same composition the execution path uses, applied to evidence intake.
The trust rules do not soften for relayed data. Stale, partial or truncated input still reads UNKNOWN and still holds the gate, and every verdict built on it prints the source, the collection time and the fact that it was relayed rather than pulled directly.
Calls that establish, refresh, replace, or extend coverage require
confirm=true after the agent presents the evidence to a human. The only
unconfirmed update accepted is an additive detection or freeze inside
already-covered scope; that path preserves the established coverage and
freshness, so it can only make a decision more cautious. Never self-attest.
Send an empty items list ONLY when the source genuinely returned nothing.
If the query failed, say so by omitting this call entirely: an unsupplied
channel reads UNKNOWN and holds, which is the safe answer. Reporting a
failed query as "nothing found" is the one input that could widen what the
agent is willing to do.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | EDR: [{asset_id, severity, rule, age_hours}]. change_freeze: [{asset_id, reason}]. An empty list means the source was queried and found nothing -- do not send [] if the query failed. | |
| scope | Yes | What was actually queried, e.g. 'all Windows servers, last 24h'. Under-scoped evidence is worse than none, so be specific. | |
| source | Yes | The MCP server or system the data came from, e.g. 'crowdstrike-mcp', 'splunk-mcp', 'servicenow-mcp'. Recorded verbatim. | |
| channel | Yes | Which gate to feed: edr | change_freeze | |
| confirm | No | Human confirmation that the relayed evidence may establish, refresh, replace, or extend gate coverage. Not needed for caution-only detections/freezes added inside existing coverage. | |
| complete | Yes | False if the query was partial, paged out or capped. A partial answer holds the gate. | |
| collected_at | Yes | When the SOURCE collected this, ISO 8601 UTC, e.g. 2026-08-05T09:00:00Z. Not the time you are calling this tool. | |
| confirmed_at | No | UTC time of the human confirmation, ISO 8601. | |
| confirmed_by | No | Operator identity recorded on the approval receipt. | |
| confirmation_id | No | Unique human approval receipt ID; one-time use. | |
| evidence_digest | No | Exact SHA-256 digest printed by the refused preview call. | |
| covered_asset_ids | Yes | Exact asset IDs the source query covered. Scope prose is audit context only and cannot widen this set. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint false, destructiveHint false), the description discloses important behavioral traits: Chokepoint Finder holds no EDR/SIEM/ITSM credentials; stale/partial/truncated input reads UNKNOWN and holds the gate; every verdict prints source, collection time, and relayed status; calls that establish/refresh/replace/extend coverage require confirm=true; never self-attest. This is rich, safety-critical context that the annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long (four paragraphs) but well-structured: it starts with the core purpose, then explains trust rules, confirmation requirements, and empty-items semantics. Every paragraph earns its place given the safety-critical nature of the tool. It is not as concise as a two-sentence description, but the length is justified by the complexity, and the front-loaded opening sentence immediately clarifies the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (12 parameters, 7 required, safety implications), the description is exceptionally complete. It covers the tool's role, the provenance model, trust rules, confirmation workflow, and edge cases like failed queries and empty results. An output schema exists, so return values need no explanation. The description leaves no significant gaps for an agent to misuse the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 12 parameters with detailed descriptions (e.g., items, scope, confirm, complete). The tool description adds some nuance on the items parameter ('Send an empty items list ONLY when the source genuinely returned nothing' and the failed-query rule), but most parameter semantics are already in the schema. The description provides marginal added value beyond the schema, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Feed a pre-flight gate from an MCP server you already have connected.' It clearly distinguishes this tool from siblings like chokepoint_ingest by explaining it relays evidence from external MCP servers (CrowdStrike, Splunk, etc.) rather than pulling directly or holding its own credentials. The purpose is unmistakable and differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance. It states the tool is for relaying evidence from other MCP servers, and explicitly says 'If the query failed, say so by omitting this call entirely' while also explaining that an empty items list should only be sent when the source genuinely returned nothing. It also details the confirm=true requirement for coverage changes and permits unconfirmed additive detections/freezes, giving clear operational rules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chokepoint_verifyVerify the deltaA
Re-query the authoritative source and diff against the baseline.
Fails closed. A re-query that errors, times out, comes back truncated, partial or stale returns UNKNOWN or ERROR and explicitly refuses to conclude anything about remediation -- it never reports clean. Only a non-simulated, final-wave VERIFIED result permits closing a change record. In demo mode the re-query is a labelled simulation, stated in the status and closure-decision lines.
| Name | Required | Description | Default |
|---|---|---|---|
| wave | Yes | Pending wave number; required by the canonical playbook. | |
| plan_hash | Yes | Approved plan hash; required by the canonical playbook. | |
| json_output | No | Return a structured, digest-bound verification receipt. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses critical behavior not present in annotations: fail-closed semantics, error/timeout/truncated/stale handling that returns UNKNOWN or ERROR, and explicit refusal to report clean. It also explains demo-mode simulation and the requirement for a non-simulated final-wave VERIFIED result. This far exceeds what the readOnlyHint/destructiveHint annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core action, then systematically covers failure behavior and demo mode. Each sentence contributes distinct value without filler, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and annotations, the description is strong on failure modes and demo behavior. It doesn't explicitly identify the authoritative source or pipeline prerequisites, but the canonical playbook references in the schema fill most gaps. It is complete enough for safe use in most scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all three parameters with descriptions (plan_hash, wave, json_output), so the baseline is 3. The description adds 'final-wave' context that relates to the wave parameter and mentions demo mode, but it doesn't add new syntax or value formats beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool re-queries the authoritative source and diffs against the baseline, which is a specific verb+resource. It does not explicitly name sibling alternatives, so it stops short of full differentiation, but the verification intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: this is used to verify a delta before closing a change record, with important caveats like 'fails closed' and 'only a non-simulated, final-wave VERIFIED result permits closing.' It does not explicitly say when not to use it or name alternative tools, but the when-to-use is evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.0- First observed
chokepoint_demo - First observed
chokepoint_ingest - First observed
chokepoint_mark_executed - First observed
chokepoint_payload - First observed
chokepoint_plan - First observed
chokepoint_preflight - First observed
chokepoint_rank - First observed
chokepoint_setup - First observed
chokepoint_supply_evidence - First observed
chokepoint_verify
TDQS
Scored across 10 tools
Most tools have clearly distinct roles in the workflow, but some pairs like chokepoint_payload and chokepoint_plan (both produce outputs for a chokepoint) could be confused. Similarly, chokepoint_supply_evidence and chokepoint_preflight are closely related input/evaluation steps.
All tools share the consistent 'chokepoint_' prefix, but the second part mixes verbs (ingest, setup, rank, verify) with nouns (payload, plan) and verb phrases (mark_executed, supply_evidence). This is readable but not perfectly uniform.
10 tools is well within the ideal 3-15 range. Each tool maps to a distinct phase in the chokepoint-finding and remediation workflow, and none feel redundant or unnecessary.
The tool set covers the full lifecycle from setup and ingest to ranking, evidence gating, plan/payload generation, execution marking, and verification. The design intentionally leaves out direct execution, which is documented and consistent with the server's zero-trust posture.
Maintenance
Related MCP Connectors
Threat modeling, code/cloud/pipeline scanning, shadow-AI discovery, compliance checks and fixes.
Production-safety audits for AI-generated code, with a fix for every finding.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Fail-closed policy guardrails for AI agents running kubectl, terraform, helm, and argocd.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables security auditing, penetration testing, and compliance validation with tools like Semgrep, Trivy, Gitleaks, and OWASP ZAP. Features strict project boundary enforcement and supports OWASP, CIS, and NIST compliance frameworks.7-
- AlicenseNot gradedqualityCmaintenanceAutomates 85-95% of the Secure Software Development Lifecycle (SSDLC) planning phase through multi-role AI orchestration, enabling business analysis, threat modeling, test strategy design, and security code review.MIT

Rigour MCPofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to self-govern by scanning code for hardcoded secrets, structural violations, and AI drift in real-time, providing fix packets for automatic remediation.27MIT- AlicenseBqualityCmaintenanceAn authorization-first MCP-governed control plane for executing security-tool workflows in explicitly approved, sandboxed environments with auditable campaigns and AI collaboration boundaries.61MIT