Ctfd Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Ctfd Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.

MCP server that lets a regular CTFd user list challenges, read details, start/stop dynamic docker instances, and submit flags.
uv).CTFD_URL (e.g. <https://ctfd.example.com>)CTFD_TOKEN (user token, not admin) or CTFD_SESSION (session cookie if tokens are disabled).CTFD_CSRF_TOKEN (optional, only if the server/plugin requires CSRF for ctfd-owl).You can store them in a .env file in the repo root:
CTFD_URL=https://ctfd.example.com/
CTFD_USERNAME=your_username
CTFD_PASSWORD=your_password
# or, if you prefer to use a token:
# CTFD_TOKEN=your_ctfd_api_token_here
# or, if tokens are disabled:
# CTFD_SESSION=your_session_token_here
# and, if the owl plugin enforces CSRF:
# CTFD_CSRF_TOKEN=your_csrf_token_hereuvx ctfd-mcp --helpuvx --from . ctfd-mcp --help# installed from PyPI
uvx ctfd-mcp
# from local checkout
uvx --from . ctfd-mcp{
"mcpServers": {
"ctfd-mcp": {
"command": "uvx",
"args": ["ctfd-mcp"],
"env": {
"CTFD_URL": "https://ctfd.example.com",
"CTFD_TOKEN": "your_user_token"
}
}
}
}[mcp_servers.ctfd-mcp]
command = "uvx"
args = ["ctfd-mcp"]
[mcp_servers.ctfd-mcp.env]
CTFD_URL = "https://ctfd.example.com"
CTFD_TOKEN = "your_user_token"list_challenges(category?, only_unsolved?) — list visible challenges, optional category/unsolved filter.challenge_details(challenge_id) — description (HTML + description_text), metadata, attachment URLs, solved status.submit_flag(challenge_id, flag) — attempt a flag; returns status/message.start_container(challenge_id) — unified start; auto-detects dynamic_docker, ctfd-owl or k8s /api/v1/k8s.stop_container(container_id?, challenge_id?) — unified stop; whale can be stopped with just container_id, owl/k8s need challenge_id.Attachments are returned as absolute URLs in files; the client/host can fetch them directly.
resource://ctfd/challenges/{challenge_id} — markdown snapshot of a challenge (metadata, description, attachment URLs, connection info if present)./api/v1/containers returns 404.dynamic_check_docker) use a different endpoint: /plugins/ctfd-owl/container?challenge_id=<id>. They usually require a session cookie, and some setups require a CSRF token; set CTFD_CSRF_TOKEN if needed./api/v1/k8s/{get,create,delete} with multipart form data; the client will try these when the challenge type includes k8s (or when a dynamic_docker endpoint is missing)./login (302) when using a token, switch to a browser session cookie: set CTFD_SESSION from the session cookie after logging in.CTFD_USERNAME and CTFD_PASSWORD; these fields take precedence over stale tokens/sessions.If something breaks or you have questions, reach out:
uv run pytest.CTFD_TIMEOUT (total), CTFD_CONNECT_TIMEOUT, CTFD_READ_TIMEOUT (seconds). Defaults are 20s total / 10s connect / 15s read.uv sync --group devuv run ruff check . and uv run ruff format .uv run pytestuv run pre-commit install (see CONTRIBUTING.md)Apache-2.0. See LICENSE.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.