Skip to main content
Glama
FlagForge MCP Server

FlagForge MCP Server

by ballz4z4

FlagForge MCP Server

MCP (Model Context Protocol) server ที่เปลี่ยน FlagForge REST API เป็นเครื่องมือสำหรับ AI agent — ให้ agent ค้นคลัง CTF ที่เคยแก้, ทำงานกับโจทย์ระหว่าง event สด, บันทึก evidence, ส่ง flag, และเขียน writeup ได้โดยตรง

การติดตั้งและรัน

cd C:/Users/Admin/Desktop/files/mcp-ai/flagforge-mcp
npm install
npm run build        # tsc → dist/index.js

Environment variables (จำเป็น)

ตัวแปร

ค่า

ตัวอย่าง

FLAGFORGE_BASE_URL

URL ของ FlagForge web app

http://localhost:3000

FLAGFORGE_TOKEN

Bearer token ของ agent (สร้างจากหน้า admin → Agents)

ff_xxxxxxxx หรือ admin bootstrap token

Token ต้องเป็นของ agent principal ที่สร้างไว้ในระบบ (role: reader/solver/submitter/admin) หรือ FLAGFORGE_ADMIN_TOKEN สำหรับการทดสอบ — สิทธิ์ทุกอย่างถูกบังคับตาม role ของ token นั้น

การเชื่อมต่อกับ Claude Desktop / Claude Code

เพิ่มใน claude_desktop_config.json (Claude Desktop):

{
  "mcpServers": {
    "flagforge": {
      "command": "node",
      "args": ["C:\\Users\\Admin\\Desktop\\files\\mcp-ai\\flagforge-mcp\\dist\\index.js"],
      "env": {
        "FLAGFORGE_BASE_URL": "https://your-flagforge.example.com",
        "FLAGFORGE_TOKEN": "ff_your_agent_token"
      }
    }
  }
}

สำหรับ Claude Code:

claude mcp add flagforge -e FLAGFORGE_BASE_URL=http://localhost:3000 -e FLAGFORGE_TOKEN=ff_your_token -- node C:/Users/Admin/Desktop/files/mcp-ai/flagforge-mcp/dist/index.js

Related MCP server: ctfd-mcp

เครื่องมือทั้ง 18 ตัว

Events

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

list_events

reader

รายการ event ทั้งหมด พร้อมจำนวนโจทย์/แก้แล้ว

create_event

admin

สร้าง event ใหม่ (name, slug, platform_type: ctfd/custom/manual, organizer, description, flag_pattern, status)

Challenges

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

list_challenges

reader

โจทย์ใน event (รับ event id หรือ slug) + filter ได้ (category, status)

get_challenge

reader

รายละเอียดโจทย์เดี่ยว: คำอธิบาย, สถานะ, flag status, writeup status

create_challenge

solver+challenge.write

สร้างโจทย์ (title, category, points, description, connection_info, tags, external_id) — slug สร้างอัตโนมัติจาก title

update_challenge

solver+challenge.write

แก้ไขฟิลด์โจทย์

delete_challenge

admin

ลบโจทย์ + evidence/flags/artifacts (cascade)

claim_challenge

solver

จองโจทย์ (lock กันซ้ำ มี expiry)

release_challenge

solver

ปลดล็อกโจทย์ที่จองไว้

set_challenge_status

solver

เปลี่ยนสถานะ: unopened triaging in_progress blocked solved verified failed

Evidence (บันทึกระหว่างแก้)

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

save_evidence

solver

บันทึก evidence: command output observation hypothesis request response reference

list_evidence

reader

ดู evidence ทั้งหมดของโจทย์

Flags (ห้องนิรภัย — เข้ารหัส AES-256-GCM)

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

submit_flag_candidate

submitter

เก็บ flag candidate (เข้ารหัส, กันซ้ำด้วย HMAC)

list_flags

reader

ดู flags — ได้เฉพาะ redacted preview เช่น TCTT20…_ok} ไม่มี plaintext ยกเว้น admin reveal

Writeups

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

save_writeup

solver

บันทึก writeup เป็น markdown (render จริงบนหน้าเว็บ: หัวข้อ, code block, ตาราง, รูป) — language: thai = มนุษย์เขียน / english = AI generate, status: draft/reviewed/final

get_writeup

reader

อ่าน writeup ทั้งสองภาษา

ค้นหา + Artifacts

Tool

สิทธิ์ขั้นต่ำ

คำอธิบาย

search_knowledge

reader

ค้นหาทุก event: คำอธิบายโจทย์, writeup ไทย/อังกฤษ, tags — หาว่าโจทย์แนวนี้เคยแก้ยังไง

list_artifacts

reader

ไฟล์แนบโจทย์ (images, pcaps, notes) พร้อม sha256

upload_artifact

solver (หรือ permission artifacts.upload)

อัปโหลดไฟล์ (รูป, pcap, note) — ส่ง file_path (อ่านจากดิสก์) หรือ content_base64 + filename — ตอบกลับพร้อม markdown_snippet สำหรับฝังรูปใน writeup

Workflow ที่แนะนำ

1. ก่อนเริ่มโจทย์ใหม่ — ค้นความรู้เดิมก่อนเสมอ

search_knowledge(q="SQL injection union")     → เจอโจทย์คล้ายที่เคยแก้ + writeup
search_knowledge(q="buffer overflow", language="english")

2. ระหว่าง event สด

list_events()                                  → หา event ที่กำลัง live
list_challenges(event="tctt-2026", status="unopened")
get_challenge(challenge_id=...)                → อ่านคำอธิบาย
claim_challenge(challenge_id=...)              → จองก่อนใคร
set_challenge_status(challenge_id=..., status="in_progress")
save_evidence(challenge_id=..., evidence_type="command",
             content="nmap found port 1337", command_text="nmap -sV target")
submit_flag_candidate(challenge_id=..., value="TCTT{...}")
set_challenge_status(challenge_id=..., status="solved")

3. หลังแก้เสร็จ — เขียน writeup

# ฝังรูปใน writeup: upload ก่อน แล้วใช้ markdown_snippet ที่ได้
upload_artifact(challenge_id=..., file_path="screenshot.png")
# → { artifact: {...}, markdown_snippet: "![screenshot.png](/artifacts/<id>)" }
save_writeup(challenge_id=..., language="thai",
             markdown="## วิธีแก้\n\n...", status="final")

4. ตัวอย่างการสร้าง event + โจทย์ด้วยมือ

create_event(name="My CTF 2026", slug="my-ctf-2026", platform_type="manual", status="live")
create_challenge(event="my-ctf-2026", title="Baby SQLi", category="Web",
                 points=100, description_markdown="Find the flag in /search",
                 tags=["sqli", "web"])

การทดสอบ

มี e2e test 2 ชุด (ต้องรัน web app ที่ localhost:3000 ก่อน):

# ชุดพื้นฐาน 17 tests — flow หลักครบ
FLAGFORGE_TOKEN=<admin token> node test-mcp.mjs

# ชุดละเอียด 39 tests — ทุก tool + error paths + permission + dedup + bilingual
FLAGFORGE_TOKEN=<admin token> READER_TOKEN=<reader token> node test-mcp-exhaustive.mjs

ผลล่าสุด: 17/17 และ 39/39 ผ่านทั้งหมด — ครอบคลุม:

  • Validation (slug ซ้ำ, slug format ผิด, status ไม่มีอยู่)

  • Permission (reader ปฏิเสธการเขียนทุกชนิด: 403)

  • Flag security (list ไม่เคยคืน plaintext, dedup ซ้ำ, มีเฉพาะ redacted preview)

  • Claim/release lifecycle (lock/unlock จริง)

  • Bilingual writeup (ไทย+อังกฤษ)

  • Search (อังกฤษ, ไทย, ไม่เจอ = ชุดว่าง)

  • Not-found paths (404 ทุก tool)

ข้อควรระวังด้านความปลอดภัย

  • Flag ถูกเข้ารหัสตอนพัก (AES-256-GCM) — MCP ไม่มี tool ไหนคืน plaintext เด็ดขาด

  • ทุก writeup ห้าม log flag เต็ม — ใช้ redacted preview เท่านั้น

  • Token ของ agent มี SHA-256 hash lookup — หากโดนขโมยให้ revoke ทันทีจาก admin UI

  • ทุกการเขียนผ่าน MCP มี audit log ผูกกับ agent principal "# flagforge-mcp"

Available Tools

19 tools
claim_challengeA

Lock a challenge to this agent (15-min lease; 409 if someone else holds it)

Inputs: challenge_id (required).

create_challengeA

Create (write) a new challenge in an event — for manual entry, mockups, or archiving self-made challenges

Inputs: event (required), title (required), category (required), tags, +4 more.

create_eventA

Create a new CTF event (requires admin role)

Inputs: name (required), slug (required), platform_type (required), status, +3 more.

delete_challengeA

Delete a challenge and its evidence/flags/artifacts (admin only, cascades)

Inputs: challenge_id (required).

get_challengeA

Get one challenge's summary: description, status, tags, flag status, lock owner

Inputs: challenge_id (required).

get_writeupA

Read a challenge's writeup (Thai human + English AI)

Inputs: challenge_id (required).

list_artifactsB

List files/artifacts attached to a challenge (images, pcaps, notes) with sha256

Inputs: challenge_id (required).

list_challengesC

List challenges in an event (by event id or slug)

Inputs: event (required), status, category.

list_eventsA

List CTF events with challenge/solved counts

Inputs: no named parameters.

list_evidenceC

List evidence recorded on a challenge

Inputs: challenge_id (required).

list_flagsA

List flags on a challenge (redacted previews only — the vault never returns plaintext)

Inputs: challenge_id (required).

release_challengeB

Release the claim/lock on a challenge

Inputs: challenge_id (required).

save_evidenceA

Record evidence during solving (hypothesis, observation, command output...)

Inputs: content (required), challenge_id (required), evidence_type (required), command_text.

save_writeupA

Save a writeup as markdown. Record Thai for human review, English for AI-generated.

Markdown is rendered on the challenge page — headings, code blocks, tables and images all display. To embed an image:

  1. upload it with upload_artifact → returns an artifact id

  2. reference it in the markdown as alt text

External image URLs (https://...) also render. Do NOT use relative paths like /_astro/... — they will 404 on the FlagForge site.

Inputs: language (required), markdown (required), challenge_id (required), status.

search_knowledgeA

Search across all events: challenge descriptions, writeups (Thai/English), tags — find how similar challenges were solved before

Inputs: q (required), language.

set_challenge_statusC

Update working status: unopened | triaging | in_progress | blocked | solved | verified | failed

Inputs: status (required), challenge_id (required).

submit_flag_candidateB

Store a flag candidate for a challenge (encrypted at rest, deduplicated)

Inputs: value (required), challenge_id (required), source.

update_challengeC

Update an existing challenge's fields (title, description, points, tags...)

Inputs: challenge_id (required), tags, title, points, +3 more.

upload_artifactA

Upload a file (screenshot, pcap, note) to a challenge as an artifact.

Provide either a local file path (read from disk) or raw content bytes with a filename. Returns the artifact record — use its id to embed images in writeups: alt text

Inputs: challenge_id (required), filename, file_path, mime_type, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 19 tools

    Disambiguation5/5

    Every tool targets a specific resource and action pair: events, challenges, evidence, flags, writeups, artifacts, and knowledge search. The only possible near-overlap between update_challenge and set_challenge_status is resolved by the latter being explicitly scoped to lifecycle status.

    Naming Consistency5/5

    Tool names follow a consistent lowercase snake_case verb_noun pattern throughout, such as list_*, create_*, get_*, update_*, delete_*, save_*, and upload_*. This makes the intended action of each tool predictable and easy to select.

    Tool Count4/5

    At 19 tools, the set is slightly above the typical well-scoped range, but the breadth is justified by the full CTF workflow: events, challenge CRUD, status/locking, evidence, flags, writeups, artifacts, and search. No tools are redundant; each contributes a distinct operation.

    Completeness4/5

    The core challenge lifecycle is well covered with create/read/update/delete plus status, locking, evidence, flags, writeups, and artifacts. Minor gaps exist around event updates/deletes and direct artifact retrieval, but agents can work around these for solving and documentation workflows.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      Enables interaction with CTFd platforms for Capture The Flag competitions, allowing users to list challenges, read details, manage dynamic Docker containers, and submit flags through natural language.
      5
      24
      Apache 2.0
    • F
      license
      A
      quality
      D
      maintenance
      Connects AI assistants to AttackForge's Self-Service API with full endpoint coverage, response size optimization, and local caching for efficient use in long conversations.
      11
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to interact with a Forgejo instance as an authenticated user, supporting issues, pull requests, repositories, and notifications.
      70 npm
      MIT