mcpField
C
CTFd

CTFd

ローカル
github.com/MrJamescotセキュリティ75 週間前に更新

CTFd について

CTFdは、CTFd v3のチャレンジ確認、フラグ送信、スコアボード照会を行うMCPサーバーで、任意のREST APIも備えています。複数の認証方式に対応し、認証情報は既定でメモリ内に保持します。

主な機能

  1. 01トークン、Cookie、フォームログイン
  2. 02ページ分割されたチャレンジ検索と詳細表示
  3. 03確認付きフラグ送信
  4. 04スコアボードと進捗の照会
  5. 05任意のREST API

活用シーン

  1. 01AIエージェントでCTFチャレンジを閲覧
  2. 02フラグを送信して結果を確認
  3. 03順位と解答済みチャレンジを確認

MCP 対応

stdioまたはSSEを通じて、チャレンジ照会、フラグ送信、スコアボード取得などのCTFd v3操作ツールをMCPクライアントに提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの 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 インスタンスと連携するための Model Context Protocol(MCP)サーバーです。 AI ツール(Claude Desktop、Cursor、カスタムエージェントなど)が、安定した 型安全なインターフェースを通じて認証し、チャレンジの一覧表示と詳細確認、 フラグの送信、インスタンスの状態照会を行えます。

このプロジェクトには、同じクライアントライブラリを基盤とする2つのインターフェースが用意されています。

  • 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 フィルターを利用でき、チャレンジごとの詳細も取得できます。
  • 安全なフラグ送信 — 明示的な confirm=True が必要です。成功/失敗を明確に返し、レート制限エラーも通知します。フラグがログに記録されることはありません。
  • インスタンスの情報取得 — 公開インスタンス情報、ヘルスチェック、秘密情報を漏らさない認証状態確認ツールを利用できます。
  • 一貫した構造化エラー — AuthenticationError、CTFdAPIError、ChallengeNotFoundError、SubmissionError、ValidationError、ConfigurationError。
  • デフォルトでページネーション — 1回の呼び出しで取得するチャレンジは1ページのみです。意図しない全件ダウンロードを防ぎます。
  • 堅牢な HTTP 通信 — タイムアウトを設定でき、冪等な GET は安全に1回再試行します。POST は再試行せず(重複送信を防止)、JSON とコンテンツを厳密に解析します。
  • 1つのコードベースで 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/*)を保護する任意のベアラートークン
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_tokentokenAPI トークンを設定します(メモリ内のみ)
set_cookiecookieセッション Cookie を設定します(メモリ内のみ)
loginusername、passwordフォームからログインし、セッション Cookie を保持します
challengescategory、search、solved、page、per_pageフィルター付きのページ分割されたチャレンジ一覧です
challengeidentifier(id または name)1 件のチャレンジの詳細情報です
submit_flagflag、challenge_name/challenge_id、confirmフラグを送信します(confirm=True が必要です)
download_filefile_url、dest_dirCTFd の /files/… ルート経由でチャレンジの添付ファイルをダウンロードします
unlock_hinthint_idヒントのロックを解除して読み取ります(有料ヒントはポイントを消費します)
scoreboard—公開スコアボードの順位です
progress—あなたのスコアと解決済みのチャレンジです
instance_info—安全な公開インスタンスメタデータです
auth_status—認証モードと有効性(シークレットは含みません)
health—到達可能性、API、認証のチェックです

トークン認証では、リクエストは Content-Type: application/json を付けて送信されます (CTFd は JSON リクエストに対する Authorization: Token ... のみを有効として扱います)。Cookie/認証情報を使った認証では、 状態を変更するリクエストにセッションの CSRF nonce を 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_urlCTFd のベース URL を検証して設定します
POST/set_tokenAPI トークンを設定します
POST/set_cookieセッション Cookie を設定します
POST/set_creds後でログインするためにユーザー名とパスワードを保存します
POST/loginフォームログイン(セッション Cookie)
GET/challengesページネーションとフィルターに対応したチャレンジ一覧
GET/challenges/{id-or-name}チャレンジの詳細
POST/submitフラグを送信します(confirm: true が必要)
POST/downloadチャレンジの添付ファイルをダウンロードします(本文:file_url)
POST/unlock_hintヒントのロックを解除して読み取ります(本文:hint_id)
GET/scoreboard公開順位
GET/progress自分のスコアと解答状況
GET/instance_infoインスタンスの公開メタデータ
GET/auth_status認証方式と有効性
GET/healthヘルスチェック

任意の 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(エージェント)
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、パスワード、フラグがマスキングされます(server/utils.py)。
  • 各ツールはネットワークにアクセスする前に入力を検証します(set_base_url は絶対 http(s) URL を要求し、submit_flag は confirm=True を要求するなど)。
  • 再試行は制御されています。 冪等な GET リクエストのみ、一度だけ再試行されます。 フラグの送信が自動的に再実行されることはありません。
  • 信頼モデル。 このサーバーはローカル/開発用ツールです。このツールを呼び出せる人は誰でも、 接続先として任意の CTFd インスタンスを指定し、有効な認証情報があればデータを読み取ったり、 フラグを送信したりできます。信頼できないネットワークに REST/SSE エンドポイントを公開しないでください。
  • SSRF ガード。 デフォルトでは、プライベート/ループバック/リンクローカル/ メタデータアドレスへの接続は拒否されます(CTFD_ALLOW_PRIVATE_IPS=1 で無効化できます)。ローカル コンテナやプライベートインスタンスを指定したツールには、明確なエラーが返されます。

制限事項

  • CTFd v3+ が必要です。使用する /api/v1 ルートは、標準の CTFd v3 API ルートです。
  • フォームログインは、CTFd のウェブセッションフローに依存します(CSRF nonce の抽出はベストエフォートです)。認証方法としては API トークンを推奨します。
  • difficulty は CTFd の標準フィールドではないため、代わりにチャレンジの value(ポイント)が返されます。
  • solved によるフィルタリングには CTFd の solved_by_me フラグを使用します。このフラグは、認証済みの場合にのみ意味があります。
  • インスタンスの「バージョン」は、レンダリングされたページに表示されている場合にのみ報告されます。CTFd には公開バージョン API エンドポイントがありません。
  • トークンはインスタンスごとに異なります。 CTFd は認証情報が無効な場合、/api/v1 への呼び出しをログインページにリダイレクトします。サーバーはこれを検出し、*「このインスタンスでは認証情報が無効です」*と報告します。ある CTFd インスタンスのトークンが別のインスタンスで機能することはありません。
  • CTFD_USERNAME/CTFD_PASSWORD が設定されている場合、呼び出しが未認証で返されるたびに、サーバーは必要に応じて自動ログインし(セッション Cookie を更新)、期限切れのセッションを自動的に復旧します。ログインのたびに、サイトから CSRF nonce を再取得します(ウェブセッション経由でフラグを送信するには、新しい 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

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。