It runs at user scope, so reading a challenge, bringing its container up, trying a flag and shutting the container down again all happen without an admin token in play. The container start auto-detects which CTFd deployment style the event uses, which is the part that differs from event to event.
A CTFd client with a regular player's permissions: it lists visible challenges, reads their details and attachments, starts and stops dynamic containers, and submits flags.
- Visible challenges listed, filtered by category or to the unsolved ones
- Full challenge detail: description as HTML and plain text, metadata, attachment URLs, solved status
- Flag submission, returning the platform's own status and message
- Dynamic instances started, with dynamic_docker, ctfd-owl and k8s deployments auto-detected
- Instances stopped again by container or challenge ID
Python 3.13 managed by uv, CTFD_URL, and one auth method: CTFD_TOKEN (a user token, not an admin one), or a copied browser session cookie if the event has tokens disabled. A CSRF token is needed only if the ctfd-owl plugin enforces CSRF. Runs with uvx ctfd-mcp.
One command plus a key — uvx ctfd-mcp, then supply credentials
