MCP config + implementation security audit — config secrets/auth, unpinned versions, remote vs local, OAuth, env exposure; implementation command injection, SSRF, unsafe args, tool poisoning. Static, evidence-cited.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add ulises-jeremias/agent-toolkit --skill mcp-audit --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mcp Audit?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ulises-jeremias-mcp-audit)More formats (shields.io, HTML) on the badges page.
---
name: mcp-audit
description: MCP config + implementation security audit — config secrets/auth, unpinned versions, remote vs local, OAuth, env exposure; implementation command injection, SSRF, unsafe args, tool poisoning. Static, evidence-cited.
origin:
type: first-party
---
# MCP Audit — Config + Implementation Security
Audit **MCP servers** before adopting — static inspection only, never execute remote servers. Use when reviewing `mcp/registry/*.yaml`, `mcp/templates/*/config.template.json`, skill/plugin MCP declarations, or when a static surface scan flags MCP references.
**Single skill, two modes** — decision per #379 review: config and implementation scopes meaningfully overlap (both inspect `mcp/registry/*.yaml` + templates), but checklists differ enough to keep separate gates. One skill with two modes avoids duplicating registry parsing while keeping `config` (secret hygiene, version pinning) distinct from `implementation` (command injection, SSRF, tool poisoning).
> **Static only:** Do not start or call remote MCP servers during audit. Inspect YAML/JSON, package provenance, tool descriptions, and env handling.
## Modes
| Mode | What it checks | Evidence |
|------|----------------|----------|
| **Config audit** | `mcp/registry/*.yaml` auth, package provenance, version pinning, remote vs local, OAuth, env/secret exposure, permissions | Registry YAML, template JSON, env var names, `docs/MCP.md` |
| **Implementation audit** | Command injection, shell execution, SSRF, unsafe args, tool description poisoning, secret env leakage, dangerous permissions, transport security | Skill SKILL.md + static surface patterns (shell/network/mcp/hooks), tool definitions, args validation, network_hosts |
Run the relevant mode per request; for full adoption review, run both and emit a single `mcp-audit-report.md`.
## Config audit — checklist
### Auth & secrets
- [ ] `auth.env` lists only env var **names**, never values (scan registry YAML for `ghp_`, `xoxb`, hardcoded tokens)
- [ ] Template `config.template.json` uses `${ENV_VAR}` placeholders (no real credentials)
- [ ] Remote MCP (`streamable_http` URL like `https://mcp.figma.com/mcp`) documents auth as `bearer-env` with region var, not query param
- [ ] Local MCP (`stdio` via `npx`/`docker`/`uvx`) does not embed secrets in `args` — secrets only in `env`
- [ ] No `default-branch push` or `filesystemWrites` beyond declared `security.network_hosts`
### Version pinning & provenance
- [ ] `implementation.package` is machine-verifiable: npm `chrome-devtools-mcp@latest` / docker `ghcr.io/...` / URL `https://mcp.figma.com/mcp` — not bare `latest` without policy
- [ ] `implementation.version_policy` declared (`npx-latest`, `pin image digest`, `pin to minor`) and matches template `args` (`-y chrome-devtools-mcp@latest` vs `@notionhq/notion-mcp-server`)
- [ ] `implementation.provenance` = `official` with `repository` URL + `license` verifiable via `gh api` (e.g., ChromeDevTools/chrome-devtools-mcp Apache-2.0, github/github-mcp-server MIT)
- [ ] Remote vs local decision documented: remote (Figma) for designer-hosted, local (GitHub/Slack/Notion) for on-host execution — no mixed remote + local for same provider without rationale
### Permissions & env exposure
- [ ] `security.network_hosts` enumerates expected hosts (no `*`, no private `.local` / `192.168.`)
- [ ] `security.secret_storage` = `environment variable` with `secret_storage` notes
- [ ] `platforms` matrix declares support per target (native/bridged/manual) — no assumed universal
- [ ] `approval.default` matches risk: `read-only` for Figma/GitHub vs `read-write` for Chrome DevTools (can modify page) — justified
### Per-template gate
- [ ] Template `command` ∈ `npx|docker|uvx` and `args[:2] == ["-y", provider.package]` for `npx` (verified by `tests/test_mcp_templates.py`)
## Implementation audit — checklist
### Command injection & shell
- [ ] `args` contain no shell interpolation (`$(`, `` ` ``, `;`, `&&`, `|`). MCP `command` is single binary, not `sh -c`.
- [ ] `command` is not `sh`/`bash`/`python -c` with concatenated args — use direct `npx`/`docker` entrypoint.
### SSRF & network
- [ ] URL args (`--browser-url`, `https://mcp.linear.app/mcp`) are not user-controlled without allowlist; `navigate_page` tool validates hosts.
- [ ] `network_hosts` does not include internal metadata endpoints (`169.254.169.254`, `metadata.google.internal`).
### Tool poisoning & unsafe args
- [ ] Tool descriptions in registry `tools.read/write` do not contain prompt injections (e.g., `ignore previous instructions`, `send secrets to`).
- [ ] Tool `write`/`destructive` sets are minimal — no `delete_file` where read-only suffices (GitHub `destructive` correctly lists `delete_file` only there).
- [ ] Args that become file paths (`FIGMA_OAUTH_TOKEN`) are env var refs, not string interpolation.
### Secret leakage & OAuth
- [ ] No `env` value contains PII — only `${VAR}` placeholders in templates; registry lists `env` names with `CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS` style opt-outs.
- [ ] OAuth flows (Linear) documented as browser OAuth, not token paste.
## Workflow
1. **Load registry:** `agent_toolkit.compiler.mcp_registry.load_registry(mcp/registry)` — record `providers, errors` (evidence: registry count).
2. **Pick mode:** `config` (default for adoption) or `implementation` (for command/SSRF/poisoning) or both.
3. **Run checks:** For each `provider` in `providers`, apply the relevant checklist above; for `implementation`, Grep the registry/templates for shell/network/hooks patterns and capture findings with `file:line` evidence. (Repo checkout/CI may also run `./scripts/audit-capability.vsh mcp/registry/<provider>.yaml --json` — that script is **not** on the host install.)
4. **Score:** `ALLOW` (no Blocking), `CAUTION` (Major, e.g., unpinned version, remote without TLS), `BLOCK` (Blocking: hardcoded secret, command injection, SSRF to metadata endpoint, provenance unknown).
5. **Report:** Emit `mcp-audit-report.md` (see `references/mcp-audit-template.md`) with per-provider table: `provider | config verdict | impl verdict | package/license | version_policy | provenance | evidence`.
### Example report row
| Provider | Config | Impl | Package | License | Version policy | Verdict | Evidence |
|----------|--------|------|---------|---------|----------------|---------|----------|
| chrome-devtools | ✅ auth none, package chrome-devtools-mcp@latest, npx-latest, no secrets | ✅ no shell, no SSRF, read-write justified | npm chrome-devtools-mcp@latest | Apache-2.0 | npx-latest | ALLOW | registry chrome-devtools.yaml + template config.template.json |
## Relation to `mcp` skill
- `mcp` (integrations/mcp) — **how to setup** (`agent-toolkit mcp setup`, `mcp list`, `doctor`) — orchestration.
- `mcp-audit` (this skill) — **whether to trust** — security gate before setup. Call this skill before `mcp setup` for unreviewed providers; delegate `supply-chain-audit` for full skill/plugin surface.
## Delegation table
| Need | Skill |
|------|-------|
| Setup MCP after audit | `integrations/mcp` |
| Full skill/plugin supply-chain | `agentic-security/supply-chain-audit` |
| OWASP agentic review (prompt injection, tool poisoning, identity) | `agentic-security/owasp-agentic-review` (next issue) |
| Output gate | `output-handshake` |
## Security & compatibility
- Never execute MCP servers during audit; static YAML/JSON only.
- Portable: `gh api` for provenance license check, `yaml` + `jsonschema` offline.
## References
- `references/mcp-audit-template.md` — report template (per-provider verdict)
- `mcp/registry/*.yaml` — canonical registry (7 providers after #375)
- `mcp/templates/*/config.template.json` — host wiring (placeholders)
- Static surface patterns in this skill’s checklists (shell/network/mcp/hooks); repo checkout/CI may use `scripts/audit-capability.vsh`
- MCP spec: https://modelcontextprotocol.io/ , ChromeDevTools MCP https://github.com/ChromeDevTools/chrome-devtools-mcp
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!