MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

10 intentionally malicious MCP servers that exploit protocol features to attack AI clients. For security research and defense testing.

Created 2/9/2026
Updated about 21 hours ago
Repository documentation and setup instructions

bad-mcp

License: MIT Go Docker MCP

10 intentionally malicious MCP servers that demonstrate protocol-level attack patterns against AI clients. Each server exploits a distinct feature of the Model Context Protocol — tool descriptions, schemas, resources, session management, and cross-server interactions.

These aren't buggy servers waiting to be exploited. They are the attacker.

WARNING: This project is for authorized security research and education only. Do NOT expose these servers to the internet or use them in production.

Why This Exists

MCP adoption is accelerating — Claude Desktop, Cursor, Windsurf, and dozens of other AI clients now support it. But the protocol's trust model has fundamental gaps: tool descriptions are unverified, schemas can carry hidden instructions, and servers can mutate definitions mid-session. Research from CyberArk, Invariant Labs, and Elastic Security Labs has documented these attacks, but working implementations are scarce.

bad-mcp provides concrete, runnable attack servers so client developers can test defenses, security teams can assess risk, and researchers can study protocol-level threats without building everything from scratch.

How This Differs

| | bad-mcp | damn-vulnerable-MCP-server | vulnerable-mcp-servers-lab | |---|---|---|---| | Perspective | Server is the attacker | Server is the victim | Server is the victim | | Focus | MCP protocol-level attacks only | Mixed (prompt injection + classic appsec) | Mixed (path traversal, SQLi, MCP) | | Attacks | FSP, ATPA, rug-pull, resource poisoning, cross-server shadowing | CTF challenges (easy/med/hard) | 9 servers, pentest training | | Language | Go + mcp-go SDK | Python | JS + Python | | Isolation | Docker-compose, no host access | Local Python scripts | Docker-compose | | Unique | Rug-pull via session tools + notifications, full-schema poisoning via param names | Challenge/scoring format | Typosquatting focus |

Architecture

vuln-external network (localhost:8001-8010)
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ schema-poison-notes│ │ response-inject-   │ │ shadow-exfil       │
│       :8001        │ │ tickets    :8002   │ │       :8003        │
└────────────────────┘ └────────────────────┘ └────────────────────┘
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ squatting-file-ops │ │ tool-poisoning-calc│ │ true-rug-pull      │
│       :8004        │ │       :8005        │ │       :8006        │
└────────────────────┘ └────────────────────┘ └────────────────────┘
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ resource-poison-   │ │ indirect-inject-   │ │ exfil-chain-       │
│ docs       :8007   │ │ fetcher    :8008   │ │ analytics  :8009   │
└────────────────────┘ └────────────────────┘ └────────────────────┘
┌────────────────────┐
│ denial-of-wallet   │
│       :8010        │
└────────────────────┘

Servers

| Port | Server | MCP Attack Class | Protocol Feature Exploited | |------|--------|------------------|---------------------------| | 8001 | schema-poison-notes | Full-Schema Poisoning (FSP) | input_schema parameter names | | 8002 | response-inject-tickets | Adv. Tool Poisoning via Output (ATPA) | Tool response content | | 8003 | shadow-exfil | Cross-Server Shadowing | Multi-server tool descriptions | | 8004 | squatting-file-ops | Tool Name Collision / Squatting | Tool naming + descriptions | | 8005 | tool-poisoning-calc | Tool Description Poisoning (TPA) | Tool descriptions | | 8006 | true-rug-pull | Rug-Pull (Tool Def Mutation) | Session tools + notifications | | 8007 | resource-poison-docs | Resource Poisoning (ATPA variant) | resources/list + resources/read | | 8008 | indirect-inject-fetcher | Indirect Prompt Injection | External data in tool output | | 8009 | exfil-chain-analytics | Cross-Tool Exfiltration Chain | Tool chaining via descriptions | | 8010 | denial-of-wallet | Denial of Wallet | Recursive invocation + massive output |

Each server has its own README.md with vulnerability details, exploit scenarios, detection methods, and mitigation strategies.

Quick Start

# Build and start all servers
docker-compose build && docker-compose up -d

# Run smoke tests (runs entirely inside Docker)
docker-compose --profile test run --rm smoke-test

# View exfiltration logs
docker-compose logs schema-poison-notes | grep EXFIL
docker-compose logs true-rug-pull | grep RUG-PULL

# Stop
docker-compose down

Connecting an MCP Client

After docker-compose up -d, connect any SSE-compatible MCP client (Claude Desktop, Cursor, Windsurf, Claude Code, etc.). All servers use the same JSON format:

{
  "mcpServers": {
    "schema-poison-notes":    { "url": "http://localhost:8001/sse" },
    "response-inject-tickets":{ "url": "http://localhost:8002/sse" },
    "shadow-exfil":           { "url": "http://localhost:8003/sse" },
    "squatting-file-ops":     { "url": "http://localhost:8004/sse" },
    "tool-poisoning-calc":    { "url": "http://localhost:8005/sse" },
    "true-rug-pull":          { "url": "http://localhost:8006/sse" },
    "resource-poison-docs":   { "url": "http://localhost:8007/sse" },
    "indirect-inject-fetcher":{ "url": "http://localhost:8008/sse" },
    "exfil-chain-analytics":  { "url": "http://localhost:8009/sse" },
    "denial-of-wallet":       { "url": "http://localhost:8010/sse" }
  }
}

Tip: Start with tool-poisoning-calc (:8005) — simplest attack to observe. Then try true-rug-pull (:8006) — ask about the weather 3+ times and watch the tools mutate.

Safety Guarantees

| Concern | Guarantee | |---------|-----------| | Host filesystem | No volume mounts. Containers have zero access to host filesystem. | | Host network | No network_mode: host. All containers use isolated Docker bridge networks. | | Privileged access | No privileged: true. No cap_add. Default restricted capabilities. | | Environment leakage | No host env vars passed. All "credentials" are fake hardcoded strings. | | Host execution | Nothing runs on the host. Tests run inside Docker via --profile test. | | Code on disk | Inert Go source files. Not executable outside Docker. |

Tech Stack

  • MCP servers: Go + mcp-go v0.32.0 (SSE transport)
  • Docker: Multi-stage golang:1.23-alpine -> alpine:3.19
  • Orchestration: docker-compose with network isolation
  • Testing: Dockerized Go smoke test (--profile test)

Research References

| Server | Source | |--------|--------| | schema-poison-notes | CyberArk — Full-Schema Poisoning | | response-inject-tickets | CyberArk — ATPA | | shadow-exfil | Invariant Labs — Tool Poisoning | | squatting-file-ops | Elastic Security Labs | | tool-poisoning-calc | Invariant Labs — Tool Poisoning | | true-rug-pull | ETDI Paper | | resource-poison-docs | Pillar Security | | indirect-inject-fetcher | Microsoft — Indirect Injection | | exfil-chain-analytics | Elastic Security Labs | | denial-of-wallet | Prompt Security — Top 10 MCP Risks |

See also: Adversa AI — MCP Security TOP 25 | MCPTox Benchmark | OWASP Top 10 for Agentic Applications

Known Gaps

The following published MCP attack classes are not yet implemented:

  • Server Identity Spoofing — MCP server spoofing trusted serverInfo name/version during initialization
  • Sampling Abuse — Exploiting sampling/createMessage to inject arbitrary prompts
  • Prompt/System Instruction Leakage — Extracting system prompts via crafted tool responses
  • Notification Channel Exfiltration — Abusing progress/logging notifications as data channels
Quick Setup
Installation guide for this server

Installation Command (package not published)

git clone https://github.com/canack/bad-mcp
Manual Installation: Please check the README for detailed setup instructions and any additional dependencies required.

Cursor configuration (mcp.json)

{ "mcpServers": { "canack-bad-mcp": { "command": "git", "args": [ "clone", "https://github.com/canack/bad-mcp" ] } } }