An intentionally vulnerable MCP server exposing five deliberately insecure tools for security education and attack demonstration. Includes a confused deputy pattern with no authorization, input validation, or output sanitization (when SAFE_MODE=0). Supports both OpenAI-driven and offline StubPlanner agents.
This is a deliberately vulnerable teaching lab, not a production MCP server. All 5 tools have descriptions and basic schemas, but lack depth expected of production tools. Descriptions are adequate (50-150 chars) but generic. Parameters have types but minimal constraints. No error recovery guidance, no pagination, no output schema documentation. Tool names are clear (search_kb, fetch_web_document, read_file, run_sql, send_telegram_message) but descriptions don't explain WHEN to use each tool or what downstream tools expect. The server intentionally omits input validation and sanitization in vulnerable mode, which is pedagogically correct but fails production rubric standards. No tool annotations (readOnlyHint, destructiveHint) despite clear risk profiles (run_sql is DESTRUCTIVE, send_telegram_message is WRITE).
Fetch the contents of a URL and return the response body as text. Useful for reading external documentation or web pages the user references.
Read a local file and return its contents. Handy for reading project documents and configuration files.
Run a SQL query against the application database and return the result. Use this to look up application data when asked.
Search the internal knowledge base and return the most relevant documents. Use this to answer questions about the company, its products and policies.
Send a text message to the configured Telegram chat. Use this to notify the operator or deliver a report.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles. run_sql is DESTRUCTIVE, send_telegram_message is WRITE, but LLM has no machine-readable signal of these consequences.
No output schema documentation. Tools return free-text strings; LLM cannot parse structured results or extract IDs for chaining. E.g., search_kb returns concatenated docs with no field structure.
No error recovery guidance. Errors return raw exceptions (e.g., '[search_kb error] {exc}') without actionable next steps. LLM cannot self-correct or retry intelligently.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 51 | <=2025-11-25 | v2 |
Parameter descriptions lack constraints. 'query' in search_kb has no length limit, format, or example. 'url' in fetch_web_document has no scheme allowlist documented in description (only in code). LLM cannot infer valid inputs.
run_sql accepts arbitrary SQL with no input validation in vulnerable mode. Description does not warn LLM of injection risk or document expected query format (SELECT vs INSERT/UPDATE/DELETE).