Demonstration MCP server with security-hardened tools for records management, URL fetching with SSRF protection, and health check patterns. Includes both a corrected version (main) and vulnerable version (broken branch) for audit/learning purposes.
Server defines 8 tools with complete JSON schemas and parameter descriptions. Naming follows verb_noun convention (list_, create_, delete_, fetch_). Descriptions are present but vary in quality, some are in Russian and lack LLM-optimized clarity. Critical strengths: explicit input validation (minLength, maxLength, minimum constraints), SSRF protection in fetch_url, and confirmation gates on destructive operations. Weaknesses: descriptions lack actionable context (when to use, what to return), no output schemas documented, and 'example_*' tools duplicate production tools without clear purpose. Average tool score: 62/100.
Создать запись с текстом `data` (1..255 символов).
Удалить запись по id. Деструктивная операция — требует confirm=true.
Пример write tool с валидацией длины/непустоты входа.
Пример деструктивного tool — требует confirm=true.
Пример tool с сетевым выходом, защищённого от SSRF. Реальную выборку (requests.get / httpx.get) добавьте сами — здесь оставлен только сам guard, чтобы шаблон не тянул requests/httpx как обязательную зависимость.
Пример read-only tool с ограниченным limit.
Получить содержимое страницы по URL. Разрешены только http/https на публичные адреса — приватные сети, loopback и cloud-metadata endpoint заблокированы (SSRF-guard, см. `validate_fetch_url`).
Descriptions lack LLM-optimized context. Russian text ('Вернуть список записей...') is not actionable for English-speaking LLMs. Descriptions do not explain WHEN to use each tool, what it returns, or dependencies between tools.
No output schemas documented. LLMs cannot infer what fields to expect from responses (e.g., does list_records return {records: [...], total: N} or just [...]?). This forces agents to guess and risks parsing failures.
Duplicate tool definitions (example_* tools mirror production tools). This creates ambiguity for LLMs, which should they call? Remove template tools or clearly mark them as non-functional examples.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Вернуть список записей (не более `limit`, максимум 100).
fetch_url description mentions SSRF protection but does not explain what happens on blocked URLs. Error message should guide LLM to retry with a public URL, not just reject silently.
delete_record requires confirm=true but description does not explain the consequence of confirm=false (operation is rejected, not executed). LLMs may not understand the gate.