OD

omartinex/damn-vulnerable-mcp-server

Developer tools
0 stars 6 forks Quality 56 Trend 0

Damn Vulnerable MCP Server Project

Overview

Think DVWA but for MCP/AI agent security. DVMCP is a self-contained training platform for learning how to attack and defend AI agents that use the Model Context Protocol. It simulates a fictional company () with 6 departments, 28 vulnerable tools, and 38 challenges across 4 difficulty levels. - - (included with Python) - (optional, for containerized setup) To use the web dashboard and exfiltration listener, install with extras: Available department services: dvmcp-hr, dvmcp-engineering, dvmcp-finance, dvmcp-it, dvmcp-support, dvmcp-marketing. All services share a dvmcp-data volume for the SQLite database and seed data, so cross-department scenarios work out of the box. The MCP server services (dvmcp, dvmcp-hr, etc.) communicate over stdio (JSON-RPC), not HTTP. Use docker-compose run (not up) to interact with them via your MCP client. Add to your MCP client config (Claude Desktop, Cursor, etc.):

README

DVMCP — Damn Vulnerable MCP

An intentionally vulnerable Model Context Protocol server for security training. Think DVWA but for MCP/AI agent security.

DVMCP is a self-contained training platform for learning how to attack and defend AI agents that use the Model Context Protocol. It simulates a fictional company (NovaTech Solutions) with 6 departments, 28 vulnerable tools, and 38 challenges across 4 difficulty levels.

WARNING: This is intentionally vulnerable software. Do NOT deploy in production. All data is fake.


Table of Contents


Prerequisites

  • Python 3.11+
  • pip (included with Python)
  • Docker & Docker Compose (optional, for containerized setup)

Quick Start

Local Installation

# Clone the repository
git clone https://github.com/yourusername/dvmcp-v2.git
cd dvmcp-v2

# Install the core MCP server
pip install -e .

# Run the all-in-one MCP server (all 28 tools)
dvmcp --difficulty beginner

# Or run a specific department
dvmcp --department hr --difficulty beginner

To use the web dashboard and exfiltration listener, install with extras:

# Install with dashboard + exfil listener dependencies
pip install -e ".[all]"

# Start the exfil listener (captures stolen data)
dvmcp-exfil --port 9999

# Start the web dashboard (challenge browser)
dvmcp-dashboard --port 8080

Docker

Build and run all services:

# Build all images
docker-compose build

# Run the all-in-one MCP server
docker-compose run --rm dvmcp

# Run a specific department server
docker-compose run --rm dvmcp-hr

# Start the dashboard and exfil listener
docker-compose up dashboard exfil-listener
Service URL Description
dashboard http://localhost:8080 Web dashboard for browsing challenges and tracking progress
exfil-listener http://localhost:9999 Captures exfiltrated data from challenges

Available department services: dvmcp-hr, dvmcp-engineering, dvmcp-finance, dvmcp-it, dvmcp-support, dvmcp-marketing.

All services share a dvmcp-data volume for the SQLite database and seed data, so cross-department scenarios work out of the box.

Note: The MCP server services (dvmcp, dvmcp-hr, etc.) communicate over stdio (JSON-RPC), not HTTP. Use docker-compose run (not up) to interact with them via your MCP client.


MCP Host Configuration

Add to your MCP client config (Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "novatech": {
      "command": "dvmcp",
      "args": ["--difficulty", "beginner"]
    }
  }
}

For Docker-based setups, point the command to docker-compose run:

{
  "mcpServers": {
    "novatech": {
      "command": "docker-compose",
      "args": ["-f", "/path/to/dvmcp-v2/docker-compose.yml", "run", "--rm", "-T", "dvmcp"]
    }
  }
}

For cross-origin scenarios, configure each department as a separate server:

{
  "mcpServers": {
    "novatech-hr": {
      "command": "dvmcp",
      "args": ["--department", "hr"]
    },
    "novatech-engineering": {
      "command": "dvmcp",
      "args": ["--department", "engineering"]
    },
    "novatech-finance": {
      "command": "dvmcp",
      "args": ["--department", "finance"]
    },
    "novatech-it": {
      "command": "dvmcp",
      "args": ["--department", "it_admin"]
    },
    "novatech-support": {
      "command": "dvmcp",
      "args": ["--department", "support"]
    },
    "novatech-marketing": {
      "command": "dvmcp",
      "args": ["--department", "marketing"]
    }
  }
}

Architecture

NovaTech Solutions (Fictional Company)
├── HR Department (5 tools)
│   └── search_employees, run_payroll_report, review_candidate, update_employee, generate_offer_letter
├── Engineering (5 tools)
│   └── query_repos, trigger_deployment, run_ci_pipeline, read_source_file, manage_infrastructure
├── Finance (5 tools)
│   └── query_invoices, process_payment, submit_expense, export_financial_data, wire_transfer
├── IT/Admin (5 tools + 1 hidden)
│   └── manage_users, query_audit_log, get_system_config, execute_admin_command, manage_api_tokens, [_admin_reset]
├── Customer Support (4 tools)
│   └── read_tickets, search_knowledge_base, get_customer_profile, reply_to_ticket
└── Marketing (4 tools)
    └── manage_campaigns, send_campaign_email, query_analytics, manage_social_accounts

Shared SQLite database — all departments read/write the same novatech.db (no schema isolation = cross-table SQL injection).


Vulnerability Categories (19)

ID Category Description
V01 Prompt Injection (Direct) Payload in tool parameters
V02 Prompt Injection (Indirect) Poisoned content in tool results
V03 Tool Poisoning Malicious tool descriptions
V04 Rug Pull / TOCTOU Tool behavior changes after initial trust
V05 Cross-Origin Tool Abuse Cross-department data access
V06 Privilege Escalation (Vertical) User → Admin
V07 Privilege Escalation (Horizontal) Access other users’ data
V08 Data Exfiltration (Direct) Plaintext to external endpoint
V09 Data Exfiltration (Encoded) Base64/hex encoding
V10 Data Exfiltration (Side Channel) DNS, timing, steganography
V11 Confused Deputy Agent tricked via tool chains
V12 SQL Injection Unsanitized SQL
V13 Command Injection Shell metacharacters
V14 Path Traversal File access outside directory
V15 Supply Chain Compromised CI/CD
V16 Denial of Service Resource exhaustion
V17 Shadow Tool Invocation Hidden tools not in tools/list
V18 Parameter Injection Params escape context
V19 Consent Phishing Hidden tool side effects

Challenges (38)

Beginner (10) — Single-tool, obvious payloads — 50 pts each

ID Name Category
C01 The Open Door SQL Injection
C02 Shell Shock Command Injection
C03 Credential Harvest Path Traversal
C04 The Email Cannon Direct Exfil
C05 DROP It Like It’s Hot SQL Injection
C06 Admin for a Day Vertical Privesc
C07 The Key Vault Data Exfil
C08 Pipe Dream Shell Pipes + Exfil
C09 Negative Balance Parameter Injection
C10 Token Grab Privesc

Intermediate (10) — Two-tool chains, encoded payloads — 100 pts each

ID Name Category
C11 The Poisoned Inbox Indirect Prompt Injection
C12 Resume Bomb Indirect Prompt Injection
C13 Base64 Smuggling Encoded Exfiltration
C14 The Wire Cross-Origin Abuse
C15 Audit Log Inception SQL Injection (UNION)
C16 Deploy Key Heist Path Traversal + Exfil
C17 Knowledge Poisoning Indirect Prompt Injection
C18 Social Engineering Data Exfil Chain
C19 The Expense Fraud Horizontal Privesc
C20 Config Overwrite Code Execution via CI

Advanced (10) — Multi-step cross-department chains — 200 pts each

ID Name Category
C21 The Long Con Confused Deputy (3-step)
C22 Insider Threat Cross-Origin Chain
C23 The Backdoor Persistence
C24 DNS Tunnel Side-Channel Exfil
C25 The Phantom Tool Shadow Tool
C26 Supply Chain Attack CI/CD Compromise
C27 The Slow Drip Low-and-Slow Exfil
C28 Model Manipulation Context Poisoning
C29 The Rug Pull TOCTOU
C30 Cross-Origin Pivot Full Chain (4+ depts)

Expert (8) — Side channels, steganography, model manipulation — 300-500 pts each

ID Name Category
C31 Timing Oracle Timing Side-Channel
C32 Steganographic Exfil Whitespace Encoding
C33 The Consent Trap Consent Phishing
C34 Tool Description Poisoning Tool Poisoning
C35 The Infinite Loop Denial of Service
C36 Unicode Smuggling Zero-Width Char Encoding
C37 The Dead Drop Two-Stage Injection
C38 The Full Breach Capstone (Full Kill Chain)

Difficulty Levels

Difficulty is mechanical, not just a label. It changes tool behavior:

Level Behavior
Beginner Zero sanitization. Raw SQL. No path validation. Full stack traces. All hints.
Intermediate Blocks DROP/DELETE. Partial field redaction. Logs external sends. Hints on demand.
Advanced Parameterized queries (UNION bypass works). Rate limits. Command blocklist. First hint only.
Expert WAF-like rules (encoding bypass). Simulated approval delays. No hints.

Fake Data

All data is obviously fake and safe for training:

  • 25 employees with SSNs starting 000- (invalid prefix)
  • Credit cards use test numbers (4111-1111-1111-1111)
  • API keys use formats like AKIAIOSFODNN7EXAMPLE
  • Passwords are clearly fake hashes
  • Company “NovaTech Solutions” is fictional

Project Structure

dvmcp-v2/
├── src/dvmcp/
│   ├── core/           # Server, registry, difficulty engine, verification
│   ├── departments/    # hr, engineering, finance, it_admin, support, marketing
│   ├── challenges/     # beginner, intermediate, advanced, expert
│   ├── data/           # Seed data, planted secrets, poisoned content
│   ├── dashboard/      # Web dashboard (FastAPI)
│   └── exfil_listener/ # Exfiltration capture server
├── tests/              # Test suite
├── docs/               # Documentation
├── docker-compose.yml  # Multi-service Docker config
├── Dockerfile          # Container image definition
└── pyproject.toml      # Project metadata and dependencies

Troubleshooting

Docker daemon not running

Cannot connect to the Docker daemon. Is the docker daemon running?

Start Docker Desktop (macOS/Windows) or the Docker service (Linux):

# macOS
open -a Docker

# Linux
sudo systemctl start docker

Port already in use

If ports 8080 or 9999 are occupied, override them in docker-compose:

# Use alternative ports
docker-compose run -p 8081:8080 dashboard
docker-compose run -p 9998:9999 exfil-listener

MCP server produces no visible output

This is expected. The MCP server uses stdio (JSON-RPC over stdin/stdout), not HTTP. It only responds when an MCP client sends it a request. Connect it to an MCP client like Claude Desktop or Cursor instead of running it in a terminal directly.

Database reset

The SQLite database is seeded on first run. To reset it:

# Local
rm src/dvmcp/data/novatech.db
dvmcp --difficulty beginner  # re-seeds on start

# Docker
docker-compose down -v  # removes the dvmcp-data volume
docker-compose up       # re-creates and seeds

Contributing

PRs welcome! Ideas for new challenges, vulnerability categories, or tools are especially appreciated.

License

MIT — This is educational software. Use responsibly.

Disclaimer

DVMCP is designed exclusively for security education and authorized testing. Do not use these techniques against systems you don’t own or have explicit permission to test.

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "novatech": { "command": "dvmcp", "args": ["--difficulty", "beginner"] } } }