The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Secretguard MCP listing page.
An MCP (Model Context Protocol) server that scans a code string for
hardcoded secrets — AWS keys, Stripe keys, GitHub tokens, Google API keys and
OAuth client secrets, Slack tokens and incoming webhook URLs, Shopify access
tokens, Telegram bot tokens, DigitalOcean tokens, Hugging Face tokens,
Notion API tokens, Mailchimp API keys, Postman API tokens, Linear API keys,
Readme API keys, Clojars API tokens, Pulumi API tokens, OpenAI keys, Anthropic keys, npm access tokens, SendGrid keys, Twilio API keys, Azure
Storage account keys, database connection strings with embedded passwords,
private key blocks, JWTs, and generic high-entropy credentials — so an AI coding
agent (Claude Code, Cursor, Windsurf, ...) can catch a
secret before it writes the file or makes the commit, instead of finding
out at CI/PR-review time. It exposes exactly one tool, scan_for_secrets,
runs entirely locally over stdio, needs no API key, and never returns a raw
secret value — every finding comes back redacted.
secret-scan-action
already catches these secrets in CI, on every PR. That's necessary but late
— by the time it runs, the secret has already been written, committed, and
pushed. This project reuses that same detection engine (same rules, same
entropy check, same redaction) but puts it in front of the agent as a tool
call, so the check can happen at generation time, before the secret ever
touches disk or history.
On a scan_for_secrets call:
code string into lines.secret-scan-action uses:
AKIA...) and
contextual secret keys, Stripe live keys (sk_live_, rk_live_),
GitHub tokens (ghp_, gho_, github_pat_, ...), Google API keys
(AIza...), Google OAuth client secrets (GOCSPX-...), Slack tokens
(xox[baprs]-...), Slack incoming webhook URLs
(hooks.slack.com/services/...), Shopify access tokens (shpat_...,
shpca_..., shpss_..., shppa_..., shpua_...), Telegram bot tokens
(<bot_id>:A..., 35-char secret), DigitalOcean tokens (dop_v1_...,
doo_v1_..., dor_v1_..., 64-char hex), Hugging Face tokens (hf_...,
api_org_..., 34-char alpha), Notion API tokens (ntn_..., 11 digits +
35 alphanumeric), OpenAI keys (sk-..., sk-proj-...,
sk-svcacct-...), Anthropic keys (sk-ant-...), npm access tokens
(npm_...), SendGrid keys (SG....), Twilio API keys (SK...), Azure
Storage account keys (contextual AccountKey=...), private key blocks
(-----BEGIN ... PRIVATE KEY-----), and JWTs. One pattern rule —
database connection strings with an embedded password
(postgres://, mysql://, mongodb(+srv)://, redis(s)://,
amqp(s)://) — is deliberately not near-certain even after excluding
known placeholder passwords (user, password, changeit, ...) and
${...}-style env-var references, since a real value there could still
be a low-stakes tutorial example rather than a live credential; it's
returned at generic confidence, same as the entropy rule below. Another
pattern rule — Mailchimp API keys (a 32-char hex value followed by a
-usNN datacenter suffix) — is also generic confidence: it only fires
when a mailchimp-prefixed variable/key name immediately precedes the
value, but that keyword gate still doesn't rule out an unrelated hex
value that happens to end in the same suffix shape. Postman API tokens
(PMAK-..., 24-char hex + - + 34-char hex), Linear API keys
(lin_api_..., 40-char alphanumeric), Readme API keys
(rdme_..., 70-char lowercase alphanumeric), Clojars API tokens
(CLOJARS_..., case-insensitive, 60-char alphanumeric), and Pulumi API
tokens (pul-..., 40-char lowercase hex) are high confidence — a fixed
prefix and exact length, same as the other provider-token rules.secret, token, password/credential, or a *key compound
commonly used for real secret material (apiKey, sessionKey,
signingKey, clientKey, webhookKey, ...) whose value also has high
Shannon entropy (looks random, not like a placeholder or an env-var
reference). Deliberately does not match a bare *Key — that would
also catch partitionKey, cacheKey, queryKey, and similar
non-secret identifiers common in ordinary code.filename, line, ruleId, description,
confidence ("high" | "generic"), and a redacted line — the raw
secret value never leaves the process. If nothing is found, it returns a
plain "No secrets detected." result.Calling scan_for_secrets with:
returns:
(The AWS key above is AWS's own public documentation placeholder, not a live
credential.) A clean scan — e.g. { "code": "const greeting = \"hello world\";" } — returns { "findings": [], "summary": "No secrets detected." }.
Not yet published to the npm registry — install directly from GitHub via
npx. npm install from a git source runs this package's prepare script
automatically, which builds dist/ on the fly, so no separate build step is
needed.
Add to your project's .mcp.json (or run claude mcp add):
Add to claude_desktop_config.json:
No API key, no account, no config options — restart Claude Code / Claude
Desktop and scan_for_secrets is available. The tool description tells the
agent to call it before writing code that could contain a credential, and
again before a commit or PR — most of the time you won't need to ask for it
explicitly.
Both read the same command/args shape from their own MCP settings UI or
config file — point them at npx -y github:vladimirbakalov/secretguard-mcp
the same way.
Once this package is published to npm, the args above can drop to
["-y", "secretguard-mcp"] instead — that's a follow-up, not a blocker.
A prebuilt MCP Bundle is
attached to the
v0.1.4-mcpb release —
download secretguard-mcp-0.1.4.mcpb and open it in Claude Desktop (or any
other MCPB-compatible client) for a one-click local install, no npx/Node
setup required on the client side. Rebuild it yourself with
npm run package:mcpb (see scripts/build-mcpb.sh).
This same .mcpb release asset is what server.json at the repo root points
at for the official MCP Registry —
secretguard-mcp is published and listed there as
io.github.vladimirbakalov/secretguard-mcp,
so MCP clients that browse the official registry can discover and install it
directly, in addition to the npx/.mcpb paths above. Publishing runs
unattended in CI (.github/workflows/publish-mcp.yml) via mcp-publisher login github-oidc on every v*-mcpb tag push — no interactive login step.
scan_for_secrets call and is redacted
(redactLine/redactSecret) before the tool result is built — it never
appears in the returned content, structuredContent, or any log line.confidence: "generic" as "worth a second look," not "confirmed."dist/ is not committed — it's built from src/ via the prepare script,
which runs both on a git-based npx/npm install and before any future
npm publish.
One tool, one job: scan a code string, return redacted findings. No allowlist file, no AI triage step, no config options, no persistent state. If this needs any of that later, it'll get added once real usage shows it's needed — not before.
secretguard-mcp and
secret-scan-action
share the same detection engine (rules.ts, redact.ts, and the core of
scan.ts) but are independent, separately distributed packages: one is a
GitHub Action that scans PR diffs in CI, the other is an MCP server that
scans arbitrary code strings locally, before a commit exists. Fixing a
false positive/negative in the ruleset means updating both.
MIT.