1. Conduid
  2. Developer Tools
  3. Bad MCP
MCP server · Developer Tools

Bad MCP

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

Unclaimed MIT last commit 8 months ago mcpmcp-servermcp-serversmcp-tools
64Good

Scored 8 days ago · breakdown

About Bad MCP

Bad MCP is an MCP server published by canack in the Developer Tools category: 10 intentionally malicious MCP servers that exploit protocol features to attack AI clients. For security research and defense testing.

The repository has 9 stars and 1 forks, with the last commit 8 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.

Install

From source
git clone https://github.com/canack/bad-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Bad MCP

Powered by Claude · Grounded in docs

I know everything about Bad MCP. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository yesterday. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

README

bad-mcp

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

README fetched from the repository yesterday. The original is authoritative.

Questions

About Bad MCP

How do I install Bad MCP?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Bad MCP safe to use with an AI agent?

Its trust score is 64 out of 100 (good). It passes 5 of the 6 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Bad MCP still maintained?

The last commit was 8 months ago. That's long enough that you should check whether the maintainer is responding to issues before depending on it.