CTFd MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CTFd MCP Serverlist the available challenges"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
CTFd MCP Server
A Model Context Protocol (MCP) server for interacting with any CTFd v3 instance. It lets AI tools (Claude Desktop, Cursor, custom agents, ...) authenticate, list and inspect challenges, submit flags, and query instance state through a stable, type-safe interface.
The project ships two interfaces built on the same client library:
MCP tools (primary) —
ctfd_mcp_server.py, used overstdioorsse.REST API (optional) —
server/main.py, a FastAPI mirror for scripting, debugging, and Docker deployments.
┌──────────────────────────────────────────────┐
AI agent / MCP │ FastMCP (MCP tools) │
client ────────►│ set_token · login · challenges · submit_flag │
└──────────────────┬───────────────────────────┘
│ shared client
┌──────────────────▼───────────────────────────┐
curl / scripts ─►│ FastAPI REST (/api/v1/...) (optional) │
└──────────────────┬───────────────────────────┘
│
┌──────────────────▼───────────────────────────┐
│ server.ctfd_client.CTFdClient │
│ └─ gateway.py (HTTP, auth, timeouts) │
└──────────────────┬───────────────────────────┘
│ HTTPS / HTTP
┌─────▼─────┐
│ CTFd │
└───────────┘Credentials (token / cookie / password) live in memory only and are never
echoed in tool output, written to server_state.json, or logged.
Features
Multiple authentication modes — API token, session cookie, or username/password form login (with CSRF handling).
Rich challenge queries — paginated listing with
category,search(name), andsolved/unsolvedfilters, plus per-challenge detail retrieval.Safe flag submission — requires an explicit
confirm=True, returns clear success/failure, and surfaces rate-limit errors. Flags are never logged.Instance introspection — public instance info, health check, and an authentication-status tool that reveal no secrets.
Consistent structured errors —
AuthenticationError,CTFdAPIError,ChallengeNotFoundError,SubmissionError,ValidationError,ConfigurationError.Pagination by default — one page of challenges per call; no accidental full-dump downloads.
Hardened HTTP — configurable timeouts, one safe retry for idempotent
GETs, no retries forPOSTs (no duplicate submissions), strict JSON/content parsing.REST + MCP from one codebase — identical behaviour on both interfaces.
No hardcoded instance —
BASE_URLis validated and configurable at startup and at runtime.
Related MCP server: CyberEdu MCP Server
Installation
Requires Python 3.10+.
The fastest way is to install from PyPI:
pip install ctfd-mcp-server
# MCP stdio server with env config:
CTFD_BASE_URL=https://ctf.example.com CTFD_ADMIN_TOKEN=ctfd_... ctfd-mcp
# optional REST interface:
ctfd-restFor MCP clients, point your config at the packaged entry point:
{
"mcpServers": {
"ctfd-mcp": {
"command": "ctfd-mcp",
"env": {
"CTFD_BASE_URL": "https://demo.ctfd.io",
"CTFD_ADMIN_TOKEN": "ctfd_..."
}
}
}
}Or run from source:
git clone https://github.com/MrJamescot/ctfd-mcp-server.git
cd ctfd-mcp-server
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then edit .envConfigure
Variable | Default | Meaning |
| (empty) | CTFd instance root, e.g. |
| (empty) | API token (preferred auth) |
| (empty) | Session cookie, e.g. |
| (empty) | Username for form login |
| (empty) | Password for form login |
|
| Per-request HTTP timeout (seconds) |
|
| Max redirects followed per request |
|
| File used to cache auth state |
|
| MCP transport: |
|
| REST server bind settings (loopback by default) |
| (empty) | Optional bearer token protecting the optional REST API ( |
|
| Allow connections to private/loopback/metadata addresses (e.g. local CTFd test instances) |
|
| Directory where challenge attachments are saved by |
|
| ⚠ Strongly discouraged: write secrets to disk |
CTFD_BASE_URLmay include a path prefix (e.g.https://host/ctfd); the client appends/api/v1automatically.
Running the MCP Server
Most MCP clients launch the server themselves via a command/args config.
For that, your client config should reference ctfd_mcp_server.py:
// e.g. Claude Desktop / mcp.json
{
"mcpServers": {
"ctfd-mcp": {
"command": "python",
"args": ["/path/to/ctfd-mcp-server/ctfd_mcp_server.py"],
"env": {
"CTFD_BASE_URL": "https://demo.ctfd.io",
"CTFD_ADMIN_TOKEN": "ctfd_..."
}
}
}
}Manual launch:
# stdio (default) — used by MCP clients
python ctfd_mcp_server.py
# SSE — expose over HTTP for remote/Docker use
CTFD_MCP_TRANSPORT=sse python ctfd_mcp_server.py # http://127.0.0.1:8000/sseMCP tools
Tool | Parameters | Description |
|
| Point the server at a CTFd instance |
|
| Adopt an API token (memory only) |
|
| Adopt a session cookie (memory only) |
|
| Form login; keeps the session cookie |
|
| Paginated challenge list with filters |
|
| Full detail of one challenge |
|
| Submit a flag (requires |
|
| Download a challenge attachment over the CTFd |
|
| Unlock and read a hint (paid hints cost points) |
| — | Public scoreboard standings |
| — | Your score + solved challenges |
| — | Safe public instance metadata |
| — | Auth mode + validity (no secrets) |
| — | Reachability, API and auth checks |
With token auth, requests are sent with
Content-Type: application/json(CTFd only honoursAuthorization: Token ...on JSON requests). With cookie/credentials auth, state-changing requests echo the session CSRF nonce as theCSRF-Tokenheader, which is re-fetched from the site after login.
Tools return JSON text. Errors are structured, e.g.:
{ "error": { "type": "ChallengeNotFoundError", "message": "Challenge '99' not found (or not visible)." } }Running the REST API (optional)
python scripts/run_local.sh # reads .env, default http://127.0.0.1:8000
# or
uvicorn server.main:app --host 0.0.0.0 --port 8000Endpoints (all under /api/v1):
Method | Path | Description |
POST |
| Validate & set the CTFd base URL |
POST |
| Set API token |
POST |
| Set session cookie |
POST |
| Store username/password for later login |
POST |
| Form login (session cookie) |
GET |
| Paginated + filtered challenge list |
GET |
| Challenge detail |
POST |
| Submit a flag ( |
POST |
| Download a challenge attachment (body: |
POST |
| Unlock and read a hint (body: |
GET |
| Public standings |
GET |
| Your score and solves |
GET |
| Public instance metadata |
GET |
| Auth mode + validity |
GET |
| Health check |
The optional REST API can be protected with an extra bearer token: set
CTFD_API_TOKEN, and requests to/api/v1/*will requireAuthorization: Bearer <token>. The server binds to loopback by default (MCP_HOST=127.0.0.1).
Docker
A ready-made image is published on Docker Hub:
docker run --rm -p 8000:8000 \
-e CTFD_BASE_URL=https://ctf.example.com \
-e CTFD_ADMIN_TOKEN=ctfd_... \
jamescot/ctfd-mcp-serverOr build locally (REST mode):
docker build -t ctfd-mcp .
docker run --rm -p 8000:8000 \
-e CTFD_BASE_URL=https://ctf.example.com \
-e CTFD_ADMIN_TOKEN=ctfd_... \
ctfd-mcpdocker compose up --build also works (REST API on http://localhost:8000).
To run the MCP SSE server in a container instead:
docker run --rm -it -e CTFD_BASE_URL=https://ctf.example.com ctfd-mcp python ctfd_mcp_server.py
# stdio on the attached terminalUsage examples
MCP (agent)
1. set_base_url url="https://ctf.example.com"
2. set_token token="ctfd_..."
3. challenges category="web", solved=false, page=1, per_page=25
4. challenge identifier="3"
5. submit_flag flag="flag{...}", challenge_id=3, confirm=trueREST
curl -X POST http://localhost:8000/api/v1/set_base_url \
-H 'Content-Type: application/json' -d '{"url":"https://ctf.example.com"}'
curl -X POST http://localhost:8000/api/v1/set_token \
-H 'Content-Type: application/json' -d '{"token":"ctfd_..."}'
curl 'http://localhost:8000/api/v1/challenges?search=web&solved=false&per_page=10'
curl -X POST http://localhost:8000/api/v1/submit \
-H 'Content-Type: application/json' \
-d '{"challenge_id":3,"flag":"flag{...}","confirm":true}'
curl http://localhost:8000/api/v1/healthSee DEMO.md for a complete walkthrough and
examples/ for curl and Python snippets.
Development & testing
pip install -r requirements-dev.txt
python -m pytest -q # 76 unit tests, mocked CTFd API (no network)
ruff check server ctfd_mcp_server.py testsThe test suite mocks the CTFd API (tests/conftest.py::FakeGateway), so unit
tests run offline.
Integration testing against a real CTFd
Run a local CTFd for live tests (recommended over the shared demo instance, which serves HTML on public auth-gated routes):
git clone https://github.com/CTFd/CTFd.git /tmp/CTFd
docker compose -f /tmp/CTFd/docker-compose.yml up
# create a user/challenge, then:
CTFD_BASE_URL=http://localhost:8000 python ctfd_mcp_server.py
CTFD_BASE_URL=http://localhost:8000 uvicorn server.main:app --port 8001
curl http://localhost:8001/api/v1/healthSecurity considerations
Credentials are memory-only. By default nothing is written to
server_state.json. EnablingCTFD_PERSIST_SECRETSis discouraged.Secrets are never echoed. Tool and API responses, error messages and logs redact tokens, cookies, passwords and flags (
server/utils.py).Every tool validates its input before touching the network (
set_base_urlrequires an absolutehttp(s)URL,submit_flagrequiresconfirm=True, etc.).Controlled retries. Only idempotent
GETrequests are retried (once). Flag submissions are never automatically replayed.Trust model. The server is a local/dev tool: whoever can call its tools can point it at any CTFd instance and (with a valid credential) read data or submit flags. Do not expose the REST/SSE endpoints on an untrusted network.
SSRF guard. By default connections to private / loopback / link-local / metadata addresses are refused (
CTFD_ALLOW_PRIVATE_IPS=1opts out). A local container or a tool pointed at a private instance will get a clear error.
Limitations
Requires CTFd v3+. The
/api/v1routes used are standard CTFd v3 API routes.Form login depends on CTFd's web session flow (CSRF nonce extraction is best-effort). API tokens are the recommended authentication method.
difficultyis not a standard CTFd field; challengevalue(points) is returned instead.solvedfiltering uses CTFd'ssolved_by_meflag, which is only meaningful when authenticated.Instance "version" is reported only when it appears in the rendered page; CTFd has no public version API endpoint.
Tokens are per-instance. CTFd redirects
/api/v1calls to its login page when a credential is invalid. The server detects this and reports: "the credential is not valid for THIS instance" — a token from one CTFd instance never works on another.When
CTFD_USERNAME/CTFD_PASSWORDare configured, the server auto-logs-in on demand (rotating the session cookie) whenever a call returns unauthenticated, so expired sessions self-heal. After each login the CSRF nonce is re-fetched from the site (a fresh nonce is required for flag submissions over a web session).A teamless account sees no
/api/v1/challengeson team-mode instances until it joins or creates a team; the server surfaces CTFd's permission message.
Contributing
Pull requests are welcome. Please:
Open an issue describing the change.
Add tests in
tests/(mocked CTFd API preferred).Run
python -m pytest -qandruff check server ctfd_mcp_server.py tests.Do not ship credentials in code, tests, or commit
server_state.json/.env.
License
MIT — repository: https://github.com/MrJamescot/ctfd-mcp-server
Available Tools
14 toolsauth_statusA
Report whether the current session is authenticated and which auth mode is active.
Reveals no tokens/cookies/passwords.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden and does well: it explicitly discloses that the tool reveals no tokens, cookies, or passwords, which is exactly the safety-relevant behavior an agent needs to know before calling. It could go further on whether the call has side effects (it implies a pure read) but the disclosure is a genuine value-add beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core purpose, followed by the safety-relevant caveat. Zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param status tool with an output schema (which presumably documents the return shape), the description is complete enough: purpose and safety posture are covered. Minor gap: it doesn't state that the call is side-effect-free/read-only, which would help an agent reason about retries.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so per the rubric the baseline is 4. The description correctly implies no input is needed; there is nothing further to specify.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('Report whether ... authenticated and which auth mode is active'). An agent can immediately distinguish this read-only status check from mutation siblings like set_token, set_cookie, and login.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and purpose — use it to discover current auth state — but there is no explicit when-to-use guidance or named alternative. No exclusions or preconditions are stated, though the tool is simple enough that heavy guidance is less critical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
challengeB
Get the full detail of a single challenge by numeric id or name.
Includes description, category, value, files, hints and connection info.
Args: identifier: challenge id (e.g. "3") or challenge name.
| Name | Required | Description | Default |
|---|---|---|---|
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden, and it does disclose the returned payload ('description, category, value, files, hints and connection info'), implying a read-only lookup. It does not state whether calling it starts or affects an instance, nor whether it requires authentication, which matters given siblings like `login` and `set_token`.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then a single line enumerating the returned fields and an Args block. The 'Args:' formatting is slightly mechanical but every line carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be spelled out, yet the description still summarizes the payload usefully. For a one-parameter lookup tool this covers what an agent needs, with the only gap being the absence of any auth or state-side-effect note.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate — and it does, clarifying that `identifier` accepts either a numeric-looking id (with example '3') or a challenge name. That is genuine meaning beyond the schema's bare 'Identifier' string title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get the full detail of a single challenge by numeric id or name.' The word 'single' implicitly separates it from the plural sibling `challenges`, but the description never names that sibling or explicitly contrasts listing vs. detail retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives such as `challenges` for listing or `instance_info` for connection details. The agent must infer that this tool is the detail-lookup counterpart to `challenges` purely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
challengesA
List challenges with optional filters and pagination.
Args: category: filter by challenge category (exact match). search: case-insensitive substring match on challenge name. solved: only show solved (True) or unsolved (False) challenges. page: page number (1-based) when no filters are applied. per_page: number of challenges per page (1-100).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| search | No | ||
| solved | No | ||
| category | No | ||
| per_page | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose a non-obvious behavioral rule (pagination only applies without filters) and the per_page bounds, but says nothing about authentication requirements, ordering of results, or total-count behavior despite siblings like set_token/login implying an auth prerequisite.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line summary followed by a tight Args list, with no filler sentences. The bullet-per-parameter format is scannable and every line carries parameter meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. Combined with the full parameter documentation, the definition is nearly sufficient; the only meaningful omission is any statement about auth or prerequisites for listing challenges.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: all five parameters are explained, including match semantics (exact for category, case-insensitive substring for search), boolean polarity for solved, 1-based page numbering, and a 1-100 range for per_page.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ('List challenges') plus its scope (optional filters and pagination). It does not explicitly distinguish itself from the singular sibling 'challenge', but the list-vs-single distinction is strongly implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the filter set: browse/search challenges, narrow by category, search text, or solved status. There is no explicit when-to-use guidance versus siblings like 'challenge' or 'progress', though the note that page only applies 'when no filters are applied' is a useful conditional hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_fileA
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.
Args: file_url: absolute http(s) URL or site-relative path to the file. dest_dir: optional local directory to store the file in (default: CTFD_DOWNLOAD_DIR or ./downloads).
| Name | Required | Description | Default |
|---|---|---|---|
| dest_dir | No | ||
| file_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses accepted URL forms (absolute http(s) or site-relative like /files/<hash>/<name>, sometimes signed) and the dest_dir default resolution, but says nothing about authentication requirements, whether existing files are overwritten, or side effects on disk.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, followed by a targeted pointer to the source of the input and a compact Args block. Every line earns its place, though the Args block partly restates schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. The description covers the workflow link, both parameters, and the default directory, leaving only auth and overwrite behavior unstated for a simple two-parameter download tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does for both parameters: file_url's accepted formats and dest_dir's optionality plus the CTFD_DOWNLOAD_DIR/./downloads default, which the schema only shows as null. It stops short of path/filename collision or directory-creation semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (download a challenge attachment to the local machine) and ties it to the sibling 'challenge' tool that produces the input. An agent can distinguish it immediately from challenge, challenges, or instance_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: get the files array from the 'challenge' tool, then pass one of those values here. It gives the condition that supplies the input, though it never states when this tool should not be used (e.g., non-challenge URLs).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
healthA
Perform a health check: CTFd reachability, API status and authentication state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose the three things inspected, which is meaningful behavioral context, but it never states that the call is a read-only, side-effect-free probe or what happens when a check fails (error vs. degraded status field).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that states the operation first and then the three checks. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not describe return values, and it correctly focuses on what is checked. The only gap is the absence of guidance on what to do with the result or how it relates to auth_status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. No parameter information is needed or missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operation (health check) and enumerates what it verifies: CTFd reachability, API status, and authentication state. It is clear what the tool does, though it never explicitly distinguishes itself from the sibling auth_status, which likely overlaps on the authentication-state portion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the nature of a diagnostic check; there is no statement of when to call it (e.g. before other calls, after set_base_url) and no mention of alternatives such as auth_status. An agent can infer the intent but must guess the conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
instance_infoA
Return safe, public metadata about the configured CTFd instance.
No secrets are included.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that output is safe/public and contains no secrets, but omits other relevant traits such as read-only nature, authentication requirements, or prerequisites like set_base_url.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core purpose and followed by a useful safety note. Every sentence earns its place with no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, zero parameters, and an existing output schema, the description is largely complete about what it returns. It could be strengthened with usage context relative to sibling tools, but no critical information is missing for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description adds no parameter semantics, but none are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Return safe, public metadata about the configured CTFd instance.' This is clear, though it does not explicitly distinguish the tool from siblings like health or auth_status that also return instance-oriented information.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. The description does not say when to call it, when not to, or how it relates to siblings such as health or auth_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
loginB
Log in to CTFd with a username and password (kept in memory only).
Creates a session cookie; the password is never returned.
Args: username: CTFd account name. password: CTFd account password.
| Name | Required | Description | Default |
|---|---|---|---|
| password | Yes | ||
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose useful traits: the password is kept in memory only, a session cookie is created, and the password is never returned. However, it says nothing about failure modes, error handling, or whether the session persists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and key security behavior, followed by a short Args block. Efficient overall, though the Args lines add little beyond the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained. The description covers purpose and the security posture adequately, but omits when to prefer this over the other auth siblings, leaving a gap for an auth-related tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does map both params (username = CTFd account name, password = CTFd account password). The added meaning is minimal and largely restates the parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Log in to CTFd') and adds the security detail that credentials are kept in memory only. An agent can tell this is the authentication step, though it is not explicitly distinguished from siblings like set_token or set_cookie that also establish auth.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use login versus the sibling auth tools (set_token, set_cookie, auth_status). Usage is only implied by the name; there are no exclusions or preconditions stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
progressA
Return the authenticated user's progress (score and solved challenges).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It discloses that the result is scoped to the authenticated user and lists the returned fields, implicitly signalling an auth requirement, but says nothing about caching/freshness, rate limits, or what happens if unauthenticated, leaving real gaps for a read tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with no filler; the scoping and returned fields are front-loaded. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read tool with an output schema that already documents the return shape, the description covers what is needed to call it correctly. The only shortfall is the absence of any sibling disambiguation from 'scoreboard' and the lack of behavioral notes that, with no annotations, would have added value.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which is the baseline-4 case per the rubric. There is nothing for the description to clarify beyond the implicit scoping to the authenticated user.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and resource ('authenticated user's progress') and even names the payload ('score and solved challenges'), so the agent knows exactly what it gets. It does not, however, differentiate itself from the sibling 'scoreboard', which an agent could easily confuse with this per-user progress view.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'authenticated user's progress' implies the usage context (fetching the calling user's own stats rather than a global ranking), which is enough to infer when to reach for it over 'scoreboard'. But no explicit when-to-use or when-not-to-use guidance, prerequisites, or alternative routing is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scoreboardA
Return the public CTFd scoreboard (top standings).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does usefully disclose that the scoreboard is 'public' (implying no token/login required), but says nothing about result size, pagination, rate limiting, or whether it reflects live scoring. An output schema exists, so return-value structure is covered elsewhere.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the resource front-loaded and a clarifying parenthetical. Nothing is wasted and nothing important is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read tool with an output schema, the description covers what is returned and that it is public. The only real gap is guidance on when in the workflow to call it, which is minor given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to clarify beyond the schema. Baseline 4 applies for a parameterless tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Return the public CTFd scoreboard (top standings)'. The parenthetical clarifies what a scoreboard returns (top standings), so the agent knows exactly what it gets. It does not need to differentiate from siblings since none of the other tools (challenges, submit_flag, login, etc.) overlap with fetching standings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: there are no alternatives to route between, and the word 'public' hints that no authentication is required. However, the description never says when to call it (e.g., after login, to check rank) or whether auth state matters, leaving the trigger condition to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_base_urlB
Configure the CTFd instance this server talks to.
Args: url: absolute http(s) URL of the CTFd instance, e.g. https://ctf.example.com
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it says nothing about whether the setting persists across calls, whether the URL is validated or the connection tested, what happens on an unreachable host, or whether it requires prior authentication. For a stateful configuration mutation with zero annotation coverage, this is a substantial gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short lines, front-loaded with the action and followed by the parameter constraint and example. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return values, so the description needn't explain them. However, for a one-shot global configuration tool with no annotations, the description omits persistence semantics, validation behavior, and ordering relative to auth siblings, leaving it adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema only declares a bare string, so the description must compensate, and it does: it constrains the value to an absolute http(s) URL and gives a concrete example (https://ctf.example.com). This adds real meaning beyond the schema, though it doesn't cover trailing slashes or path handling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: configure the CTFd instance this server talks to, which is unambiguous and distinct from siblings like set_token, set_cookie, and login. It stops short of explicitly contrasting itself with those sibling configuration tools, but the resource is clear enough that an agent can pick it out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this must be called before other CTFd operations, but there is no statement of when to use it, when not to, prerequisites, or how it relates to set_token/set_cookie/login. Implied context only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_cookieB
Use a session cookie for authentication (memory only, never logged).
Args: cookie: full session cookie value, e.g. "session=abc..." or "name=..; session=..".
| Name | Required | Description | Default |
|---|---|---|---|
| cookie | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose a meaningful trait — 'memory only, never logged' — which tells the agent the value is not persisted or written to logs. However, it omits whether the cookie overwrites existing auth, whether it is validated before use, and what happens on an invalid value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, with the parameter detail following in a compact args block. No filler, though the trailing format examples are slightly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. For a credential-setting tool with no annotations, the description still leaves gaps: relationship to sibling auth tools, overwrite behavior, and failure modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains the parameter is the full session cookie value and gives two concrete formats ('session=abc...' and 'name=..; session=..'). This meaningfully clarifies what string to pass.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: setting a session cookie used for authentication. It is clear what the tool does, but it never distinguishes itself from close siblings like set_token or login, which an agent must choose between in this toolset.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus set_token or login, no prerequisites, and no statement about whether it replaces existing credentials. The phrase 'for authentication' implies context but gives no selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_tokenB
Use an API token for authentication (stored in memory only, never logged).
Args: token: CTFd API access token.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does add genuine behavioral context: the token is 'stored in memory only, never logged.' However, it omits whether it overwrites an existing token, whether it is validated against the server, or how it affects the current session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with the security-relevant behavior stated up front, followed by a minimal Args block. No padding, though the Args section adds little beyond the parameter name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the memory-only disclosure covers the key safety concern. Still missing for a state-mutating auth tool: replacement semantics, validation behavior, and any failure modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema only repeats the property title 'Token'. The description adds a modest gloss ('CTFd API access token'), clarifying the source of the credential, but no format, prefix, or validation expectations for the single required parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: configure authentication with an API token. It is distinguishable from siblings like login and set_cookie by naming the credential type, though it never explicitly contrasts itself with those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says to 'Use an API token for authentication' but gives no when-to-use guidance relative to login or set_cookie, nor any prerequisite (e.g., that a token must first be obtained from CTFd). Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_flagA
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.
Args: flag: the flag to submit. challenge_name: name of the challenge to submit against. challenge_id: numeric id of the challenge to submit against. confirm: must be set to True as an explicit submission opt-in.
| Name | Required | Description | Default |
|---|---|---|---|
| flag | Yes | ||
| confirm | No | ||
| challenge_id | No | ||
| challenge_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose meaningful traits: an explicit confirm opt-in is required before submission, exactly one identifier must be supplied, and the flag value is never logged. It does not describe what a success/failure response looks like, though an output schema exists to cover returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The safety and exclusivity constraints are front-loaded in the first two lines, then the Args list fills the 0%-coverage schema gap without padding. Every sentence serves selection or invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating submission tool with a confirm gate and an existing output schema, the description covers the safety prerequisite, parameter exclusivity, and privacy behavior. Return handling is delegated to the output schema, so what remains is minimal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the Args block is doing real work: it documents all four parameters and adds semantics beyond the schema's bare titles, notably that confirm must be True (not merely default) and that challenge_id and challenge_name are mutually exclusive. This mutual-exclusion rule is not encoded in the schema and is genuinely useful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('Submit a flag for a challenge'), so the agent knows exactly what the tool does. It does not explicitly distinguish itself from siblings like unlock_hint or scoreboard, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete preconditions: 'requires confirm=True' and 'Provide exactly one of challenge_id or challenge_name.' That tells the agent how to call it safely. It stops short of naming when an alternative tool should be used instead, so it is clear context without full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlock_hintA
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.
Args:
hint_id: numeric id of the hint (see the challenge tool result).
| Name | Required | Description | Default |
|---|---|---|---|
| hint_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it discloses the most important hidden behavior: point deduction on cost-bearing hints and ordering constraints for dependent hints. It omits auth/permission requirements and what happens on a repeat unlock, but the risky side effect is surfaced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, the cost warning follows immediately, and the Args block is a single line. Slightly redundant with the schema's required-field declaration but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter action with an output schema, the description covers what the tool does, the key side effect, and where the ID comes from; return values need not be explained. Missing only edge cases like re-unlocking or error behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate; it does so by explaining that hint_id is the numeric id available in the 'challenge' tool result, which is more useful than a bare type declaration. It adds no validation or format detail beyond that, so not a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Unlock a challenge hint') plus the side effect of returning content, which is enough to separate it from siblings like 'challenge' and 'challenges'. The reference to hint IDs coming from the 'challenge' tool ties it into the workflow explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete context for use: hints cost points when 'cost' is non-zero, and prerequisite hint IDs must be unlocked in order. It does not name an alternative tool or state when *not* to unlock, but the operational conditions are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v1.0.4- First observed
auth_status - First observed
challenge - First observed
challenges - First observed
download_file - First observed
health - First observed
instance_info - First observed
login - First observed
progress - First observed
scoreboard - First observed
set_base_url - First observed
set_cookie - First observed
set_token - First observed
submit_flag - First observed
unlock_hint
TDQS
Scored across 14 tools
Most tools have clearly distinct purposes, but the authentication group (set_token, set_cookie, login, auth_status) plus health overlap around session/state checking, and challenge vs challenges differ only by singular/plural which can cause misselection. Descriptions do help disambiguate the intended usage.
A mix of conventions: verb_noun tools (set_token, submit_flag, download_file, unlock_hint) coexist with bare-noun tools (challenges, challenge, scoreboard, progress, instance_info, health). Each name is readable in isolation, but there is no single predictable pattern.
14 tools is well within a healthy range and each earns its place, covering setup, auth, challenge interaction, and status without bloat.
For a player-facing CTFd client the surface is strong: auth, listing/reading challenges, flag submission, file download, hint unlock, scoreboard, and progress. Minor gaps remain (e.g. category listing, team/teammate endpoints), but core workflows have no dead ends.
Maintenance
Related MCP Connectors
MCP server for AI dialogue using various LLM models via AceDataCloud
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects AI clients to a Linux terminal for real-time automated penetration testing and CTF challenge solving. It enables AI models to execute terminal commands and interact with offensive security tools like Nmap, SQLMap, and Gobuster.-
- FlicenseNot gradedqualityDmaintenanceOfficial MCP server for the CyberEdu CTF platform that automatically discovers and exposes all CyberEduClient methods as tools, enabling seamless interaction with the platform through MCP-compatible clients.8-
- FlicenseNot gradedqualityDmaintenanceA vulnerable MCP server designed for educational CTF challenges. It demonstrates various MCP security vulnerabilities in a controlled environment.8-
- FlicenseBqualityDmaintenanceA lightweight MCP server that enables AI assistants to interact with the local machine through terminal, filesystem, and Python execution tools.91-