blastcheck-mcp
An MCP server that gives coding agents (Claude Code, Claude Desktop, Cursor, and any other MCP client) the ability to assess Terraform plans with blastcheck: produce an Impact Manifest - a machine-readable change-safety assertion - and explain it in plain language.
Read-only and propose-only. No tool applies Terraform, mutates a cloud resource, or accepts a credential. This release performs no network I/O at all: everything runs offline against the plan file.
Quickstart
Requires Python 3.10+ and uv. No install step; the first run resolves everything:
uvx blastcheck-mcp
Claude Code
claude mcp add blastcheck -- uvx blastcheck-mcp
Claude Desktop
Add to claude_desktop_config.json (Settings > Developer > Edit
Config):
{
"mcpServers": {
"blastcheck": {
"command": "uvx",
"args": ["blastcheck-mcp"]
}
}
}
Cursor
Add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"blastcheck": {
"command": "uvx",
"args": ["blastcheck-mcp"]
}
}
}
Using it
Ask your agent to check a plan:
terraform plan -out plan.tfplan
terraform show -json plan.tfplan > plan.json
Then: "run blastcheck on plan.json and explain what could go wrong." The agent will call impact_emit, get a manifest handle plus a verdict summary, and follow up with impact_explain for the full picture. (impact_emit also accepts the saved .tfplan directly and converts it.)
Tools
impact_emit
Runs blastcheck's plan-only analysis on a terraform show -json file
(or a saved .tfplan) and returns:
manifest_handle- a short reference to the full Impact Manifest, written to a private temp file (0600, per-user 0700 directory, kept at most 24h). Pass it to impact_explain instead of shuttling the large document through model context.summary- the verdict, per-severity counts, which changes drove it, and the plan-only note.
A plan-only run can never emit safe - it never verified live state,
and blastcheck says so rather than guessing. That is the point of the
format.
impact_explain
Turns a manifest into markdown a human can act on: the verdict and why, each change's noteworthy findings with their rationales, a "safe if ..." checklist of unmet preconditions, and exactly what could not be verified. Deterministic local code; accepts a manifest_handle, a manifest_path, or the manifest inline (exactly one).
Output is capped by a hard budget (BLASTCHECK_MCP_EXPLAIN_BUDGET env, default 32000 characters, about 8K tokens) so the tool can never consume a session's context in one call. Small plans render in full. Large plans get a compact view: dimensions identical across every change are stated once, changes with identical assessments are grouped with numeric indexes compressed to ranges (app[0..11]) - for_each string keys are never wildcarded, so which tenants or keys are affected stays visible - and blocking changes always keep their complete address list, dropping only per-change repetition. Whenever anything is grouped or cut, an explicit partial-view notice says so and shows the exact follow-up calls; all lists are lexically sorted before any cut, so the same plan always shows the same subset. Never a silent drop.
Drill-down filters (optional, combined with AND):
severity- e.g.["blocking"]or["blocking", "caution"]module_prefix- address prefix, e.g."module.tenants[\"contoso-prod\"]"resource_type- exact type, e.g."azurerm_managed_disk"addresses- exact addresses, always rendered in full detail; the guaranteed path to any specific change
Compatibility
Verified against real clients and across MCP protocol eras (v0.1.0-rc1, mcp SDK 2.x, macOS, Python 3.13):
| Check | Result |
|---|---|
| Protocol 2024-11-05 (oldest era) | negotiated, tools list + calls work |
| Protocol 2025-03-26 | negotiated, tools list + calls work |
| Protocol 2025-06-18 | negotiated, tools list + calls work |
| Unknown version offered | server answers with its latest, per spec |
| Claude Code 2.0.76 (stdio) | connects; both tools exercised end to end in three separate headless runs. Investigated note: when driving headless claude -p sessions from INSIDE another Claude Code session (a nested test rig), intermittent multi-minute client startup stalls were observed; process inspection showed they occur before the MCP server process is even spawned, and the identical command succeeds on retry with no changes, so they are attributed to the nested test environment rather than this server. An ordinary interactive session has not yet been driven by a human; recommended as a final confirmation. |
| Claude Desktop | config block above is the documented uvx form; not yet exercised on this machine |
| Cursor | config block above is the documented uvx form; not yet exercised (Cursor not installed on the test machine) |
| Large-plan compression | verified against a synthetic 288-change fixture ONLY (nested modules, for_each string keys, count indexes; 372KB full render compressed to a 12.5KB overview). NOT yet verified against a large real-world plan - if real changes fingerprint less uniformly, overviews will be larger; the hard output budget still caps them and the partial-view notice still applies. |
Errors
Failures come back as CODE: one clear sentence - for example
FILE_NOT_FOUND: no such file: plan.json or
MANIFEST_UNSUPPORTED_VERSION: ... - never a stack trace.
Data boundary
This release sends nothing anywhere: no telemetry, no API calls, no network I/O. Raw plan JSON never leaves the machine.
A future release adds an optional CloudRift tier (live cost, dependency
and tenant enrichment; see docs/remote-tier.md). Its boundary is
already implemented and tested in this codebase, before any network
code exists: if a manifest is ever scored remotely, what leaves the
machine is an identity-only projection - per change: address, resource
type, name, Terraform provider address, and actions; plus the
manifest's schema_version, generated_at, producer name/version, and
source type. Evidence, rationales, verdicts, attribute values (ports,
CIDRs, sizes), and the plan itself are stripped by an explicit
allowlist, so a future manifest field is excluded by default rather
than leaked by default. That tier will require an explicit
CLOUDRIFT_API_TOKEN; without one, the server registers the local tools
only.
Environment variables
| Variable | Effect |
|---|---|
| BLASTCHECK_MCP_EXPLAIN_BUDGET | Hard cap, in characters, on impact_explain output (default 32000, floor 4000). Over the cap, a compact grouped view with an explicit partial-view notice is returned instead - never a silent cut. |
| CLOUDRIFT_API_TOKEN | Reserved for the future remote tier. If set today, the server notes on stderr that the remote tier is not in this release and runs the local tools only. Credentials are NEVER accepted as tool arguments. |
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[test]"
.venv/bin/pytest
The suite is fully offline. tests/test_project.py holds the
data-boundary tests; treat a failure there as a stop-ship.
Relationship to blastcheck and the spec
blastcheck-mcp is a thin MCP layer over the
blastcheck library
(pinned >=0.7,<0.8) and implements a consumer of the
Impact Manifest specification
(schema major version 0). The manifest schema is read from blastcheck's
own vendored copy, so there is no second copy to drift.
License
Apache-2.0. See LICENSE.
Release files for blastcheck-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| blastcheck_mcp-0.1.0.tar.gz | 26.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| blastcheck_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.4 kB
Release files / blastcheck_mcp-0.1.0.tar.gz
| Download URL | blastcheck_mcp-0.1.0.tar.gz |
|---|---|
| Size | 26.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
54c7348e0a91d910f335c9d23acc6899a5ee91244490a7f05c8418d83728b191
|
|
BLAKE2b-256 checksum How to use checksums |
b9c60c67fc06c106018a4a493c0cf94dee9aaa4c084c4f8ed6f623c8a4cc5766
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.2
|
Release files / blastcheck_mcp-0.1.0-py3-none-any.whl
| Download URL | blastcheck_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a58366cd2800003dcccf8f8c8f22745bf0a6825a34d9d23c98a614824aa4f4ce
|
|
BLAKE2b-256 checksum How to use checksums |
72e26766dd4e71efb0c82b85990c5d764d07cc65bd2753f65006fe2804bdc266
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.2
|