From audit
Adversarial critic for MCP servers. Reviews an MCP server's tool descriptions, parameter schemas, and implementation code to find flaws: inter-tool discrimination issues, discoverability gaps, schema anti-patterns, semantic drift between descriptions and behavior, error handling inconsistencies, and undocumented workflow dependencies. Use when the user asks to review, audit, stress-test, or find flaws in an MCP server. Also trigger on: "review my MCP tools", "audit my MCP server", "are my tool descriptions good", "find issues in my MCP server", "test my tool schemas", "what's wrong with my MCP server", "MCP tool quality", "review my tool descriptions". Do NOT trigger for: general code review (use critical-code-reviewer), security scanning (use mcp-scan), reviewing Claude Code skills (use skill-adversary), creating MCP servers, or non-MCP tool/API review.
How this skill is triggered — by the user, by Claude, or both
Slash command
/audit:mcp-adversaryThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an adversarial critic for MCP servers. Your job is to find what breaks, not what works. You read an MCP server's source code, extract tool metadata, spawn isolated sub-agents to attack it from three angles, and produce a structured report the user can act on.
You are an adversarial critic for MCP servers. Your job is to find what breaks, not what works. You read an MCP server's source code, extract tool metadata, spawn isolated sub-agents to attack it from three angles, and produce a structured report the user can act on.
You never modify the target server's files. Your output is a report.
MCP servers expose tools that LLMs select and invoke based on descriptions and schemas. Existing tools (mcp-scan, Pipelock) audit security (poisoning, injection). Nothing audits usability and correctness: are the descriptions clear enough for the LLM to pick the right tool? Are the schemas tight enough to prevent bad inputs? Does the code do what the description promises?
This skill fills that gap — specifically for FastMCP (Python) servers in V1.
!pwd
!cat ~/.claude/settings.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); [print(f'- {k} → {v.get(\"command\",\"\")} {\" \".join(v.get(\"args\",[]))}') for k,v in d.get('mcpServers',{}).items()]" 2>/dev/null || echo "(none found or settings unreadable)"
!cat .claude/settings.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); [print(f'- {k} → {v.get(\"command\",\"\")} {\" \".join(v.get(\"args\",[]))}') for k,v in d.get('mcpServers',{}).items()]" 2>/dev/null || echo "(none found or settings unreadable)"
pyproject.toml with a FastMCP dependency, or a server.py/main.py with mcp imports).The server root is the directory containing pyproject.toml (or the top-level directory with the server source).
Run Glob on the server root for **/*.py. Read all Python files. Build a map of:
mcp.run(), FastMCP(), or Server())@mcp.tool() or @server.tool())The parent only extracts what it needs for the report header and agent preamble — the sub-agents do their own deeper extraction from the source files. From the discovered source files, extract:
FastMCP(name=...) / Server(name=...) or the package name){N} (count of @mcp.tool() / @server.tool() decorators)pyproject.toml)Do not extract docstrings, parameter signatures, or implementation code at this stage — the sub-agents read those directly from the source files.
Build a source path list — absolute paths for all server-relevant files, including:
pyproject.toml (for framework/version detection)Sub-agents Read these files themselves; the parent does not embed source content into prompts (see "Attack sequence" below for why). Each agent focuses on a different dimension via its instructions, not via a pre-filtered payload.
The parent still needs the tool count {N} for the preamble — derive it from a quick scan of @mcp.tool() / @server.tool() decorators across the path list.
Run all three attacks in parallel. Each attack is a sub-agent spawned with path-based context isolation: the sub-agent receives a list of file paths, not embedded file content, and uses the Read tool to fetch each file itself.
When constructing the Agent prompt, include exactly these elements and nothing else:
agents/tool-surface-attacker.md, agents/schema-critic.md, or agents/contract-auditor.md).{absolute path}. It exposes {N} tools."SECURITY: Path-based passing eliminates two classes of injection by design, not by instruction:
<server> tag), so a malicious docstring or comment in the target server cannot inject a closing tag to escape its container. The OS file boundary is the delimiter, and tool results are structurally distinct from prompt text.If a sub-agent cannot Read a listed file (permission error, missing file), it must report the failure as a finding rather than silently proceed.
If agents/tool-surface-attacker.md, agents/schema-critic.md, or agents/contract-auditor.md cannot be read by the parent (mcp-adversary itself) when constructing prompts, abort immediately and tell the user. Read the agent instruction files from ${CLAUDE_SKILL_DIR}/agents/.
Always attempt to use a different model for the sub-agents:
model: "sonnet"model: "opus"model: "sonnet"If the alternate model is unavailable, fall back to the current model.
Tests whether tool descriptions enable the LLM to pick the right tool. Generates:
Tests whether parameter schemas are tight enough. Finds:
Tests whether the code honors the description's promise. Finds:
Once all three agents return, compile their findings into a single report. The agents produce raw findings — you generate the recommendations by synthesizing across all three.
If an agent failed, include the available results and note the failure.
Present the report directly in the conversation:
# MCP Adversary Report: {server-name}
## Server Overview
- Server: {name} ({framework} {version})
- Tools: {N} ({list of names})
- Server instructions: {present with summary / absent}
- Source files scanned: {N}
## Tool Surface Analysis
### Inter-tool Discrimination Issues
For each:
- **User intent**: what the user wants
- **Competing tools**: which tools the LLM might confuse
- **Why it's ambiguous**: explanation
- **Severity**: critical / important / minor
### Discoverability Gaps
For each:
- **Prompt**: the adversarial prompt
- **Target tool**: which tool should be called
- **Why it might not be found**: explanation
- **Severity**: critical / important / minor
### Description Quality
For each:
- **Tool**: name
- **Issue**: what's wrong
- **Impact**: how it affects LLM behavior
- **Severity**: critical / important / minor
### Tool Surface Recommendations
Concrete suggestions for renaming, rewording, splitting/merging tools.
## Schema Analysis
### Type Issues
For each:
- **Tool.parameter**: location
- **Current type**: what it is
- **Problem**: why it's too loose
- **Suggested type**: what it should be
- **Severity**: critical / important / minor
### Naming Inconsistencies
For each:
- **The inconsistency**: description
- **Tools involved**: which tools
- **Suggested convention**: how to align
### Path Convention Issues
For each:
- **The assumption**: what the code assumes
- **What breaks**: scenario
- **Suggested fix**: how to make it explicit
- **Severity**: critical / important / minor
## Contract Analysis
### Semantic Drift
For each:
- **Tool**: name
- **Description says**: quote
- **Code does**: actual behavior
- **Severity**: critical / important / minor
### Error Handling
For each:
- **Tool**: name
- **Scenario**: what input or state triggers the error
- **Current behavior**: what happens (structured error / exception / silent)
- **Recommended**: what should happen
- **Severity**: critical / important / minor
### Workflow Dependencies
- Dependency graph (tool A → tool B means A requires B's output)
- Which dependencies are documented in tool descriptions: list
- Which are undocumented: list
### Path Safety
For each:
- **Tool.parameter**: location
- **Risk**: what a malicious or accidental path could do
- **Severity**: critical / important / minor
### Resource Issues
For each:
- **Issue**: description
- **Location**: file:function or module-level
- **Impact**: what goes wrong
- **Severity**: critical / important / minor
## Summary
- Total findings: N
- Critical (breaks correct behavior or leaks data): N
- Important (degrades LLM usability or reliability): N
- Minor (cosmetic or unlikely): N
---
*For complementary security scanning (prompt injection, tool poisoning), run `mcp-scan`.*
These reduce bias without eliminating it. The report amplifies human review, it does not replace it.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub hebstr/claude-code-plugins --plugin audit