terramend-mcp
v0.1.1
Published
Model Context Protocol server for Terramend Cloud — read a repo's Terraform findings, health score, compliance evidence and crosswalk from Claude Code, Cursor or Windsurf.
Maintainers
Readme
@terramend/mcp-server
A Model Context Protocol server that gives an AI coding agent (Claude Code, Cursor, Windsurf, …) read-only access to a repository's Terramend Cloud posture — its open Terraform findings, public health score, and signed compliance evidence — without ever writing to the repo or holding a cloud credential.
This is the Cloud MCP server: it reads posture Terramend already recorded in your account. It is complementary to the engine's local
terramend mcpcommand, which runs the Terraform scanners on your working tree. Use this one to ask "what did Terramend find, and is it compliant?"; useterramend mcpto scan/validate/plan right now.
Tools
| Tool | Auth | What it does |
| --- | --- | --- |
| terramend_health_score | none | Public Terraform Health Score (0–100) + posture for a public repo. |
| terramend_verify_evidence | none (offline) | Recompute a bundle's hash and check its Ed25519 signature — no network. |
| terramend_run_context | org token | Is the repo Cloud-managed? Its plan + org-required compliance controls. |
| terramend_findings | org token | Open findings: severity, scanner, rule id, file:line, remediation state. |
| terramend_evidence_export | org token (evidence:read) | Immutable, signed compliance evidence bundle for a framework. |
| terramend_crosswalk | org token | The maintained finding→framework-control crosswalk (CE / ISO 27001 / NCSC CAF). |
All tools are read-only. The two token-free tools work the moment the server starts; the rest need a token.
Requirements
- Node.js ≥ 20.10
- A Terramend Cloud org token (
tmnd_…) for the authenticated tools — mint one in Dashboard → Settings → Tokens.terramend_evidence_exportadditionally needs theevidence:readscope.
Configuration
Set via environment variables (see .env.example):
| Variable | Default | Notes |
| --- | --- | --- |
| TERRAMEND_API_URL | https://terramend.dev | Your Cloud base URL, no trailing slash (API served under /api). |
| TERRAMEND_API_TOKEN | — | The tmnd_… org token. Optional at boot; required per-call for authenticated tools. |
| TERRAMEND_API_TIMEOUT_MS | 30000 | Per-request timeout (covers body read). |
| TERRAMEND_EVIDENCE_FINGERPRINTS | (none) | Published signing-key fingerprint(s) to confirm evidence provenance. |
| PORT | 3010 | HTTP transport only. |
| TERRAMEND_MCP_ALLOWED_HOSTS | 127.0.0.1,localhost | HTTP transport DNS-rebinding Host allow-list. |
| TERRAMEND_MCP_ALLOWED_ORIGINS | (off) | HTTP transport CORS origin allow-list (browser clients). |
| TERRAMEND_MCP_MAX_SESSIONS | 256 | HTTP transport concurrent-session cap. |
Install & build
npm install
npm run buildUse it in an MCP client (stdio)
Claude Code:
claude mcp add terramend \
-e TERRAMEND_API_TOKEN=tmnd_your_token \
-- npx -y @terramend/mcp-serverCursor / Windsurf / any mcp.json — see examples/mcp.json:
{
"mcpServers": {
"terramend": {
"command": "npx",
"args": ["-y", "@terramend/mcp-server"],
"env": { "TERRAMEND_API_TOKEN": "tmnd_your_token" }
}
}
}Then ask your agent things like:
- "What's the Terraform health score for
hashicorp/terraform?" →terramend_health_score - "List the critical and high findings for
acme/platform-core." →terramend_findings - "Export the Cyber Essentials evidence and verify it offline." →
terramend_evidence_export→terramend_verify_evidence
Authenticity vs. integrity.
terramend_verify_evidencerecomputes the hash and checks the Ed25519 signature, but a valid signature only proves the bundle was signed by whatever key it embeds. To prove it is genuinely Terramend's, pass Terramend's published fingerprint asexpectedFingerprint(or setTERRAMEND_EVIDENCE_FINGERPRINTS) — only then does the tool reportprovenanceConfirmed: true. Without a pin it returnsprovenanceConfirmed: nulland flags the gap.
Run the hosted HTTP transport
For remote or browser-based clients, run the Streamable HTTP transport:
npm run start:http # listens on http://localhost:3010/mcpIt is stateful (one session per Mcp-Session-Id), ships with DNS-rebinding protection on by default, and keeps CORS off until you set TERRAMEND_MCP_ALLOWED_ORIGINS. A Dockerfile is included for hosting.
Develop & test
npm run dev # stdio server via tsx (no build step)
npm run dev:http # HTTP server via tsx
npm test # unit tests (node:test via tsx)
npm run typecheck # tsc --noEmit
npm run inspector # open the MCP Inspector against the stdio serverMCP Inspector
npx -y @modelcontextprotocol/inspector npx -y @terramend/mcp-serverSet TERRAMEND_API_TOKEN in the Inspector's environment panel, then call any tool with an owner/repo.
Troubleshooting
- "No TERRAMEND_API_TOKEN configured" — the token-free tools still work; set the token for the rest.
- 401 Unauthorized — token is missing/expired/revoked. Mint a fresh one.
- 402 Payment required — a private repo (or a non-starter compliance framework) needs a paid plan.
- 404 Not found — the repo isn't connected to this org yet, or hasn't reported a run.
- "no public report" from
terramend_health_score— the repo is private, unconnected, or unscanned; the public badge never discloses private posture. - Nothing shows in the client — check the client's MCP server logs (this server logs to stderr; stdout is reserved for JSON-RPC).
Releasing
Releases are automated with release-please, driven by Conventional Commits:
feat: …→ minor bump ·fix: …→ patch bump ·feat!:/BREAKING CHANGE:→ (pre-1.0) minor bump.chore:/test:are hidden from the changelog.- On each push to
main, therelease-pleaseworkflow maintains a release PR that bumps the version and updatesCHANGELOG.md. - Merging that PR cuts a GitHub release + git tag, which triggers the guarded
publish job (
npm publish --provenance --access public).
Publishing requires an NPM_TOKEN repository secret and a public repo (npm
provenance uses the workflow's OIDC identity via id-token: write).
Security model
- Read-only. There is no code path here that writes to a repo, opens a PR, comments, or mints a token.
- The token is sent only as a
Bearerheader toTERRAMEND_API_URL. Secrets the Cloud may return (apiToken, module credentials) are stripped before a tool result is built. terramend_verify_evidenceruns entirely offline and separates integrity (verified) from authenticity (provenanceConfirmed) — a self-signed bundle can never read as authentic without a pinned fingerprint.- The HTTP transport defends localhost with a Host allow-list (DNS-rebinding protection), caps concurrent sessions, and defaults CORS closed.
License
Copyright © 2026 Gabriel Ignat.
Licensed under the GNU Affero General Public License v3.0 or later
(AGPL-3.0-or-later). This is network-copyleft: if you run a modified version of
this server as a network service, you must offer its source to that service's
users. See LICENSE for the full text.
