Model Context Protocol (MCP) server for CTFd v3 instances
This MCP server has critical quality gaps across naming, descriptions, and parameter schema. While tools are present and callable, the definitions lack the precision and completeness expected for production agent use. Most tool descriptions are minimal (10-40 chars), parameter types are inferred from Python signatures rather than explicit JSON Schema, and output schemas are completely undocumented. The server uses a proxy pattern (FastMCP wrapper → backend HTTP service) which obscures actual API contracts. Tool names are reasonable but descriptions fail to explain WHEN to use each tool, prerequisites, or what they return. No actionable error guidance is provided, backend errors are simply JSON-dumped. Security is a major concern: authentication credentials (username, password, token, cookie) are passed as tool parameters, violating the secret-injection pattern. The submit_flag tool accepts optional challenge_name OR challenge_id, creating ambiguous behavior not documented in the parameter descriptions.
Report whether the current session is authenticated and which auth mode is active. Reveals no tokens/cookies/passwords.
Get the full detail of a single challenge by numeric id or name. Includes description, category, value, files, hints and connection info.
List challenges with optional filters and pagination.
Download a challenge attachment to the local machine. Challenge detail (``challenge`` tool) returns a ``files`` array with site-relative paths like ``/files/<hash>/<name>`` (signed URLs on some deployments). Pass one of those values here.
Perform a health check: CTFd reachability, API status and authentication state.
Return safe, public metadata about the configured CTFd instance. No secrets are included.
Log in to CTFd with a username and password (kept in memory only). Creates a session cookie; the password is never returned.
Credentials (username, password, token, cookie) passed as tool parameters, violating secret-injection pattern. These parameters are logged in agent traces, leaking secrets into audit logs and prompt history.
No output schemas documented for any tool. Agents cannot plan downstream operations or extract required fields (e.g., challenge IDs for submit_flag, team IDs for scoreboard reasoning). Every tool response is opaque JSON.
Ambiguous parameter relationships in submit_flag: challenge_name and challenge_id are both optional but the fallback logic is undocumented. Backend code tries ID lookup first, then name, agents cannot predict behavior if both are supplied or both are missing.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 0 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 37 | - | v1 |
Return the authenticated user's progress (score and solved challenges).
Return the public CTFd scoreboard (top standings).
Configure the CTFd instance this server talks to.
Use a session cookie for authentication (memory only, never logged).
Use an API token for authentication (stored in memory only, never logged).
Submit a flag for a challenge. Safety: requires confirm=True. Provide exactly one of challenge_id or challenge_name. The flag value is never logged.
Unlock a challenge hint and return its content. WARNING: on CTFd a hint with a non-zero ``cost`` deducts that many points from your account. When two hint IDs are needed (e.g. a hint's prerequisites), unlock them in order.
set_base_url tool is broken: input parameter is ignored and the URL is hardcoded to demo.ctfd.io. The tool claims to set configuration but does not, this is deceptive and will cause agent failures when multiple CTFd instances are expected to be supported.
Most parameter descriptions are missing or generic. The rubric baseline is 100% of A+ tool params have descriptions; this server has 0%. Agents cannot infer parameter semantics from names alone (e.g., is 'identifier' a name, slug, or numeric ID?).
Tool descriptions are too short to guide agent selection. Baseline is 194 chars average (p10=34, p90=392); most tools here are 30-85 chars. Descriptions lack context on WHEN to use each tool, prerequisites, failure modes, and what to do next on error.
No error handling guidance. Backend errors (unreachable service, invalid flag, etc.) are returned as raw JSON without actionable recovery hints. Pattern requires 'Error responses must tell the LLM what to do next', e.g., 'Flag incorrect. Remaining attempts: 2. Re-examine the challenge description.'
No pagination or result-size limits documented. challenges() and scoreboard() could return hundreds of items, exhausting context window. Rubric baseline requires 'cap results at 20-50 and offer pagination', tools lack limit parameters and should document max results.
submit_flag is not marked as an irreversible write operation. Agents do not know this tool has side effects and may retry carelessly, causing duplicate flag submissions. Pattern requires: 'If the tool modifies state (creates, updates, deletes, sends), the description must say so.'