mcpField
C
CTFd

CTFd

本地服务
github.com/MrJamescot安全75 周前更新

关于 CTFd

CTFd 是面向 CTFd v3 实例的 MCP 服务端和可选 REST API,供 AI 工具及脚本查询挑战、提交 Flag 和查看积分榜。它支持多种认证方式,并默认将凭据保留在内存中。

主要功能

  1. 01支持令牌、Cookie 和表单登录
  2. 02分页筛选并查看挑战详情
  3. 03确认后提交 Flag
  4. 04查询积分榜与个人进度
  5. 05可选 REST API

适用场景

  1. 01让 AI Agent 浏览 CTF 挑战
  2. 02提交答案并检查提交结果
  3. 03查询排行榜和已解题进度

MCP 相关

通过 stdio 或 SSE 向 MCP 客户端提供 CTFd v3 操作工具,包括挑战查询、Flag 提交和积分榜查询。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mrjamescot-ctfd": {
"command": "uvx",
"args": [
"ctfd-mcp-server"
],
"env": {
"CTFD_BASE_URL": "<CTFD_BASE_URL>",
"CTFD_ADMIN_TOKEN": "<CTFD_ADMIN_TOKEN>",
"CTFD_SESSION_COOKIE": "<CTFD_SESSION_COOKIE>",
"CTFD_USERNAME": "<CTFD_USERNAME>",
"CTFD_PASSWORD": "<CTFD_PASSWORD>",
"CTFD_HTTP_TIMEOUT": "<CTFD_HTTP_TIMEOUT>"
}
}
}
}
启动命令uvx ctfd-mcp-server
需要配置的环境变量
CTFD_BASE_URLRoot URL of the CTFd v3 instance, e.g. https://ctf.example.com (without /api/v1)
CTFD_ADMIN_TOKEN密钥CTFd API access token (preferred authentication method)
CTFD_SESSION_COOKIE密钥Full CTFd session cookie, e.g. session=abc...
CTFD_USERNAMEUsername for CTFd form login
CTFD_PASSWORD密钥Password for CTFd form login
CTFD_HTTP_TIMEOUTPer-request HTTP timeout in seconds (default 15)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypictfd-mcp-server1.0.4

工具

14

收录的工具列表 · 更新于 2 周前

参数类型必填说明
urlstring是

详细介绍

CTFd MCP 服务

PyPI - Version PyPI - Python Versions Docker Pulls License: MIT GitHub Stars

一个用于与任意 CTFd v3 实例交互的模型上下文协议(MCP)服务。 它允许 AI 工具(Claude Desktop、Cursor、自定义 Agent 等)进行身份验证、列出 和查看挑战、提交 Flag,并通过稳定、类型安全的接口查询实例状态。

本项目提供两个基于同一个客户端库构建的接口:

  • MCP 工具(主要接口)— ctfd_mcp_server.py,通过 stdio 或 sse 使用。
  • REST API(可选)— server/main.py,一个用于脚本编写、 调试和 Docker 部署的 FastAPI 镜像。
                 ┌──────────────────────────────────────────────┐
 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    │
                              └───────────┘

凭据(令牌 / Cookie / 密码)仅存储在内存中,绝不会回显在工具输出中、写入 server_state.json 或记录到日志中。


功能特性

  • 多种身份验证模式 — API 令牌、会话 Cookie 或用户名/密码表单登录 (支持 CSRF 处理)。
  • 丰富的挑战查询 — 支持分页列出挑战,并按 category、search(名称) 和 solved/unsolved 筛选,还可获取单个挑战的详细信息。
  • 安全提交 Flag — 需要显式设置 confirm=True,返回明确的成功/失败结果,并显示速率限制错误。Flag 绝不会记录到日志中。
  • 实例信息查询 — 提供公开的实例信息、健康检查和身份验证状态工具,不会泄露任何机密。
  • 一致的结构化错误 — AuthenticationError、CTFdAPIError、 ChallengeNotFoundError、SubmissionError、ValidationError、 ConfigurationError。
  • 默认分页 — 每次调用仅获取一页挑战;不会意外下载全部数据。
  • 强化的 HTTP 处理 — 可配置超时时间,对幂等的 GET 请求安全重试一次, 不重试 POST 请求(避免重复提交),严格解析 JSON 和内容。
  • REST + MCP 共用一个代码库 — 两种接口的行为一致。
  • 不硬编码实例 — BASE_URL 会在启动时和运行时进行验证和配置。

安装

需要 Python 3.10+。

最快捷的方式是从 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-rest

对于 MCP 客户端,将配置指向打包后的入口点:

{
  "mcpServers": {
    "ctfd-mcp": {
      "command": "ctfd-mcp",
      "env": {
        "CTFD_BASE_URL": "https://demo.ctfd.io",
        "CTFD_ADMIN_TOKEN": "ctfd_..."
      }
    }
  }
}

或者从源代码运行:

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 .env
配置
变量默认值含义
CTFD_BASE_URL(empty)CTFd 实例根地址,例如 https://ctf.example.com(不含 /api/v1)
CTFD_ADMIN_TOKEN(empty)API 令牌(首选认证方式)
CTFD_SESSION_COOKIE(empty)会话 Cookie,例如 session=abc...
CTFD_USERNAME(empty)表单登录用户名
CTFD_PASSWORD(empty)表单登录密码
CTFD_HTTP_TIMEOUT15每次请求的 HTTP 超时时间(秒)
CTFD_HTTP_MAX_REDIRECTS5每次请求最多跟随的重定向次数
CTFD_STATE_FILE~/.local/state/ctfd-mcp/server_state.json用于缓存认证状态的文件
CTFD_MCP_TRANSPORTstdioMCP 传输方式:stdio 或 sse
MCP_HOST / MCP_PORT127.0.0.1 / 8000REST 服务绑定设置(默认仅绑定环回地址)
CTFD_API_TOKEN(empty)用于保护可选 REST API(/api/v1/*)的可选 Bearer 令牌
CTFD_ALLOW_PRIVATE_IPSfalse允许连接到私有/环回/元数据地址(例如本地 CTFd 测试实例)
CTFD_DOWNLOAD_DIR./downloadsdownload_file 保存挑战附件的目录
CTFD_PERSIST_SECRETSfalse⚠ 强烈不建议:将密钥写入磁盘

CTFD_BASE_URL 可以包含路径前缀(例如 https://host/ctfd);客户端会 自动追加 /api/v1。


运行 MCP 服务

大多数 MCP 客户端会通过 command/args 配置自行启动服务。 因此,客户端配置应引用 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_..."
      }
    }
  }
}

手动启动:

# 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/sse
MCP 工具
工具参数描述
set_base_urlurl将服务指向某个 CTFd 实例
set_tokentoken使用 API 令牌(仅保存在内存中)
set_cookiecookie使用会话 Cookie(仅保存在内存中)
loginusername、password表单登录;保留会话 Cookie
challengescategory、search、solved、page、per_page带筛选条件的分页挑战列表
challengeidentifier(id 或 name)单个挑战的完整详情
submit_flagflag、challenge_name/challenge_id、confirm提交 Flag(需要 confirm=True)
download_filefile_url、dest_dir通过 CTFd /files/… 路由下载挑战附件
unlock_hinthint_id解锁并查看提示(付费提示需要消耗积分)
scoreboard—公开排行榜
progress—你的分数和已解出的挑战
instance_info—安全的公开实例元数据
auth_status—认证模式和有效性(不含机密信息)
health—可访问性、API 和认证检查

使用令牌认证时,请求会以 Content-Type: application/json 发送 (CTFd 仅在 JSON 请求中认可 Authorization: Token ...)。使用 Cookie/凭据认证时,会更改状态的请求会将会话 CSRF 随机数作为 CSRF-Token 标头回传;登录后会从站点重新获取该随机数。

工具会返回 JSON 文本。错误采用结构化格式,例如:

{ "error": { "type": "ChallengeNotFoundError", "message": "Challenge '99' not found (or not visible)." } }

运行 REST API(可选)

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 8000

端点(均位于 /api/v1 下):

方法路径描述
POST/set_base_url验证并设置 CTFd 基础 URL
POST/set_token设置 API 令牌
POST/set_cookie设置会话 Cookie
POST/set_creds保存用户名/密码,以供后续登录使用
POST/login表单登录(会话 Cookie)
GET/challenges分页并筛选挑战列表
GET/challenges/{id-or-name}挑战详情
POST/submit提交 flag(必须设置 confirm: true)
POST/download下载挑战附件(请求体:file_url)
POST/unlock_hint解锁并查看提示(请求体:hint_id)
GET/scoreboard公开排名
GET/progress你的分数和解题记录
GET/instance_info公开实例元数据
GET/auth_status身份验证模式和有效性
GET/health健康检查

可使用额外的 bearer 令牌保护可选 REST API:设置 CTFD_API_TOKEN 后,对 /api/v1/* 的请求将要求提供 Authorization: Bearer <token>。服务默认绑定到回环地址 (MCP_HOST=127.0.0.1)。


Docker

现成的镜像已发布在 Docker Hub:

docker run --rm -p 8000:8000 \
  -e CTFD_BASE_URL=https://ctf.example.com \
  -e CTFD_ADMIN_TOKEN=ctfd_... \
  jamescot/ctfd-mcp-server

也可以在本地构建(REST 模式):

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-mcp

docker compose up --build 也可正常使用(REST API 位于 http://localhost:8000)。

如需在容器中运行 MCP SSE 服务:

docker run --rm -it -e CTFD_BASE_URL=https://ctf.example.com ctfd-mcp python ctfd_mcp_server.py
# stdio on the attached terminal

使用示例

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=true
REST
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/health

完整的操作指南请参阅 DEMO.md,curl 和 Python 代码片段请参阅 examples/。


开发与测试

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 tests

测试套件会模拟 CTFd API(tests/conftest.py::FakeGateway),因此单元测试可离线运行。

针对真实 CTFd 进行集成测试

运行本地 CTFd 进行实时测试(推荐使用本地实例,而非共享演示实例;共享演示实例会在需要身份验证的公开路由上提供 HTML):

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/health

安全注意事项

  • 凭据仅保存在内存中。 默认情况下,不会将任何内容写入 server_state.json。不建议启用 CTFD_PERSIST_SECRETS。
  • 绝不会回显机密信息。 工具和 API 响应、错误消息及日志会对令牌、Cookie、密码和 flag 进行脱敏(server/utils.py)。
  • 每个工具都会先验证输入,再访问网络(set_base_url 要求绝对 http(s) URL,submit_flag 要求 confirm=True, 等等)。
  • 受控重试。 仅幂等的 GET 请求会重试一次。 flag 提交绝不会自动重放。
  • 信任模型。 该服务是本地/开发工具:任何能够调用其工具的人,都可以将其指向任意 CTFd 实例,并且(凭借有效凭据)读取数据或提交 flag。请勿在不受信任的网络上公开 REST/SSE 端点。
  • SSRF 防护。 默认情况下,会拒绝连接到私有、回环、链路本地或 元数据地址(设置 CTFD_ALLOW_PRIVATE_IPS=1 可选择退出)。本地 容器或指向私有实例的工具将收到明确的错误信息。

局限

  • 需要 CTFd v3+。使用的 /api/v1 路由是 CTFd v3 的标准 API 路由。
  • 表单登录依赖 CTFd 的 Web 会话流程(尽力提取 CSRF nonce)。建议使用 API 令牌进行身份验证。
  • difficulty 不是 CTFd 的标准字段;返回的是挑战的 value(分数)。
  • solved 筛选使用 CTFd 的 solved_by_me 标志,该标志只有在通过身份验证时才有意义。
  • 只有在呈现的页面中显示实例“版本”时,才会报告该版本;CTFd 没有公开的版本 API 端点。
  • 令牌按实例区分。 当凭据无效时,CTFd 会将 /api/v1 调用重定向到登录页面。服务会检测到这种情况并报告:"此凭据对 THIS 实例无效"——一个 CTFd 实例的令牌绝不会在另一个实例上生效。
  • 配置 CTFD_USERNAME/CTFD_PASSWORD 后,每当调用返回未通过身份验证时,服务都会按需自动登录(轮换会话 Cookie),从而自动修复过期会话。每次登录后,都会从站点重新获取 CSRF nonce(通过 Web 会话提交 flag 需要新的 nonce)。
  • 在团队模式实例上,未加入团队的账号在加入或创建团队之前看不到 /api/v1/challenges;服务会呈现 CTFd 的权限提示。

贡献

欢迎提交拉取请求。请:

  1. 创建一个 Issue 描述所做的更改。
  2. 在 tests/ 中添加测试(优先使用模拟的 CTFd API)。
  3. 运行 python -m pytest -q 和 ruff check server ctfd_mcp_server.py tests。
  4. 不要在代码或测试中加入凭据,也不要提交 server_state.json / .env。

许可证

MIT — 仓库:https://github.com/MrJamescot/ctfd-mcp-server

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。