# Mcp Secret Sentinel

> MCP server that scans code for exposed secrets - API keys, tokens, private keys and high-entropy strings - with placeholder-aware allowlisting and redacted reports

- **Type:** MCP server
- **Install:** `agentstack add mcp-alebrito124356-mcp-secret-sentinel`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [AleBrito124356](https://agentstack.voostack.com/s/alebrito124356)
- **Installs:** 0
- **Category:** [Security](https://agentstack.voostack.com/c/security)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [AleBrito124356](https://github.com/AleBrito124356)
- **Source:** https://github.com/AleBrito124356/mcp-secret-sentinel

## Install

```sh
agentstack add mcp-alebrito124356-mcp-secret-sentinel
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# mcp-secret-sentinel

**MCP server that scans code for exposed secrets â€” API keys, tokens, private keys and high-entropy strings â€” with placeholder-aware allowlisting and redacted reports.**

Secrets rarely leak through hackers; they leak through commits. An agent (or a human in a hurry) pastes a webhook URL into a config, stages it, pushes â€” and from that moment the credential is compromised, even if the next commit deletes it, because history keeps every added line. mcp-secret-sentinel gives an agent a pre-commit checkpoint: scan a snippet, a file, a whole tree, the staged diff, or recent history, and get back a severity-ranked, fully redacted report it can act on *before* anything leaves the machine. The full secret value never appears in the tool output, so it never enters the conversation transcript either.

## Tools

| Tool | Arguments | Returns |
|---|---|---|
| `scan_text` | `text`, `source_name="input"` | Findings for a raw snippet (code, config, diff, logs) |
| `scan_file` | `path` | Findings for one file; skips binaries (null-byte heuristic) and files over 5 MB |
| `scan_directory` | `path`, `max_files=500` | Recursive scan; skips `.git`, `node_modules`, virtualenvs, `__pycache__`, `dist`, `build`, minified JS, lockfiles, and honors simple `.gitignore` patterns |
| `scan_git_staged` | `repo_path` | Scans only the lines added in `git diff --cached` â€” the exact content the next commit would publish |
| `scan_git_history` | `repo_path`, `max_commits=50` | Scans lines added by the last N commits, tagging each finding with its commit hash |
| `list_patterns` | â€” | Active detectors with severity and remediation advice, plus the allowlist rules |

All scan tools return the same shape:

```json
{
  "clean": false,
  "findings": [
    {
      "file": "config/notify.yaml",
      "line": 14,
      "pattern": "Slack incoming webhook",
      "severity": "high",
      "redacted": "hookâ€¦(77 chars)",
      "advice": "Anyone with this URL can post messages to your workspace. Regenerate the webhook in your Slack app settings and load the URL from an environment variable."
    }
  ],
  "files_scanned": 6,
  "summary": "Found 1 potential secret(s) across 6 scanned file(s): 1 high. Do NOT commit or push until these are removed or rotated."
}
```

### What it detects

Nineteen regex detectors: GitHub tokens (classic and fine-grained), OpenAI / Anthropic / NVIDIA / Google / Stripe (live) / Twilio keys, AWS access key IDs and secret access keys, Slack tokens and incoming webhooks, Discord webhooks, JWTs, private key blocks (RSA / EC / OPENSSH / PGP), database and queue connection strings with embedded credentials (Postgres, MySQL, MongoDB, AMQP, Redis), plus generic `password` / `secret` / `token`-style assignments in quoted code and in dotenv-style `UPPER_CASE=value` lines.

On top of the regexes, a Shannon-entropy detector flags quoted strings of 20+ characters assigned to variables whose empirical entropy reaches **4.5 bits/char** â€” the signature of random credential material â€” but only when no specific pattern already claimed that span.

### What it deliberately ignores (allowlist)

Each candidate value is checked against these placeholder heuristics before being reported:

- **Too short** â€” values under 8 characters are too short to be real credentials.
- **Masked** â€” values that are mostly (â‰¥ 80%) `X`, `x`, `*`, or dots: already redacted by a human, including vendor prefixes followed by an `XXXXâ€¦` run.
- **`example`** â€” any value containing `example` (any case): covers `example.com` / `example.org` domains *and* vendor-documented sample keys, such as the AWS docs key ending in `EXAMPLE`.
- **`placeholder`**, **`changeme`** (also `change-me` / `change_me`) â€” conventional fill-me-in markers.
- **your-â€¦-here** â€” fill-in-the-blank markers.
- **``** â€” documentation-style placeholders.
- **`${TEMPLATE_VARIABLES}`** â€” the secret is injected elsewhere, not stored here.
- **Environment lookups** â€” values referencing `os.environ` or `process.env`: an environment lookup is the fix, not the leak.

### Redaction guarantee

Every finding shows only the first 4 characters plus the total length â€” e.g. `"hookâ€¦(77 chars)"`. The full value never appears in the output, the transcript, or the logs. This is enforced in code (a single `redact()` choke point) and in the test suite, which asserts the raw values are absent from serialized results.

## How it works

```mermaid
flowchart TD
    A[Agent calls a scan tool] --> B{Source}
    B -->|scan_text / scan_file| C[Split into lines]
    B -->|scan_directory| D[Walk tree, skip .git, node_modules,binaries, lockfiles, .gitignore matches] --> C
    B -->|scan_git_staged / scan_git_history| E[git diff / git log with zero context,keep added lines only] --> C
    C --> F[19 regex detectors,specific patterns claim spans first]
    C --> G[Shannon entropy >= 4.5 bits/charon assigned strings of 20+ chars]
    F --> H{Allowlist check:placeholders, masked values,example domains, env lookups}
    G --> H
    H -->|placeholder| I[Dropped, not reported]
    H -->|real candidate| J[Redact: first 4 chars + length]
    J --> K[Report: file, line, pattern,severity, redacted, advice]
```

## Quickstart

```bash
pip install -e .
```

**Claude Desktop** â€” add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "secret-sentinel": {
      "command": "python",
      "args": ["/absolute/path/to/mcp-secret-sentinel/server.py"]
    }
  }
}
```

**Claude Code**:

```bash
claude mcp add secret-sentinel -- python /absolute/path/to/mcp-secret-sentinel/server.py
```

## Example session

> **User:** I'm about to push acme-app â€” make sure I'm not leaking anything.
>
> **Claude** calls `scan_git_staged(repo_path="C:/dev/acme-app")`:
>
> ```json
> {
>   "clean": false,
>   "findings": [
>     {
>       "file": "config/notify.yaml",
>       "line": 14,
>       "pattern": "Slack incoming webhook",
>       "severity": "high",
>       "redacted": "hookâ€¦(77 chars)",
>       "advice": "Anyone with this URL can post messages to your workspace. Regenerate the webhook in your Slack app settings and load the URL from an environment variable."
>     }
>   ],
>   "files_scanned": 6,
>   "summary": "Found 1 potential secret(s) across 6 scanned file(s): 1 high. Do NOT commit or push until these are removed or rotated. Unstage the affected files and strip the secrets before committing."
> }
> ```
>
> **Claude:** Hold the push â€” `config/notify.yaml` line 14 contains a real Slack webhook URL in the staged diff. Three steps:
> 1. Replace the literal URL with an environment lookup, e.g. `SLACK_WEBHOOK_URL`.
> 2. Regenerate the webhook in your Slack app settings â€” treat the current one as compromised.
> 3. Re-stage the file and I'll verify.
>
> **User:** Done â€” check again.
>
> **Claude** calls `scan_git_staged(...)` â†’ `"clean": true, "summary": "Staged changes are clean â€” 6 file(s) with additions scanned, no secrets in the added lines."` â€” then `scan_git_history(repo_path="C:/dev/acme-app", max_commits=20)` â†’ `"clean": true`.
>
> **Claude:** Clean â€” the staged changes and the last 20 commits contain no detectable secrets. Safe to push.

## Limitations

- **`.gitignore` support is best-effort**: plain names, `*.ext` globs, `dir/` and `/anchored` patterns from the *root* `.gitignore` only. No `!` negations, no `**` globs, no nested ignore files.
- **Entropy needs diversity**: empirical per-string entropy maxes out at log2(distinct characters), so a candidate needs at least 23 distinct characters to clear 4.5 bits/char. Short random strings are covered by the regex detectors instead.
- **Unquoted generic assignments** are only detected in dotenv-style `UPPER_CASE=value` lines â€” a deliberate trade against false positives in ordinary code.
- **Not a CI replacement**: dedicated scanners (gitleaks, trufflehog) with hundreds of rules belong in your pipeline. This server is the fast local checkpoint an agent can run *before* the commit exists.

## Development

```bash
pip install -e ".[dev]"
python -m pytest
```

The test suite exercises every detector, the allowlist, entropy, redaction, directory walking, and real temporary git repositories â€” and never contains a realistic secret literal: every positive fixture is assembled at runtime by concatenation.

## License

MIT

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AleBrito124356](https://github.com/AleBrito124356)
- **Source:** [AleBrito124356/mcp-secret-sentinel](https://github.com/AleBrito124356/mcp-secret-sentinel)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-alebrito124356-mcp-secret-sentinel
- Seller: https://agentstack.voostack.com/s/alebrito124356
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
