$ man ctfbase

Documentation

Everything you need to search CTF writeups via API or connect your AI assistant via MCP.

$ cat quick-start/README.md

1.Sign in

Click Sign in in the navbar. Free account gives you unlimited search, all writeup previews, full text on free writeups, and 1 API key for MCP (search tool). Pro unlocks full content & flags for every writeup.

2.Search writeups

Use the search page or call the API directly:

bash
curl "https://api.ctfbase.com/api/v1/search?q=sql+injection"

3.Connect your AI assistant

Add CTF Base as an MCP server to Claude, Cursor, or any MCP-compatible client:

bash
claude mcp add ctfbase https://mcp.ctfbase.com/mcp

$ man api

Base URL: https://api.ctfbase.com/api/v1

GET/search

Hybrid AI search (full-text + vector similarity). If q is omitted, browse all writeups in a category. At least one of q or category is required.

Parameters:

qstringSearch query (optional if category is provided)
categorystringFilter by category (web, crypto, pwn, ...). Use alone to browse all writeups in a category.
limitintResults per page (default: 10, max: 50)
offsetintPagination offset (default: 0)

Example:

bash
curl "https://api.ctfbase.com/api/v1/search?q=buffer+overflow&category=pwn&limit=5"
# Browse all writeups in a category:
curl "https://api.ctfbase.com/api/v1/search?category=web&limit=10"

Response:

json
{
  "results": [
    {
      "id": "picoctf2024_heap_overflow",
      "title": "Heap Overflow — PicoCTF 2024",
      "category": "pwn",
      "difficulty": "medium",
      "event": "PicoCTF 2024",
      "description": "Task: Exploit a heap overflow...",
      "tags": ["heap", "overflow", "glibc"],
      "techniques": ["heap-overflow", "use-after-free"]
    }
  ],
  "total": 42,
  "limit": 5,
  "offset": 0,
  "query_time_ms": 823.5
}
GET/categories

List all categories with writeup counts.

Example:

bash
curl "https://api.ctfbase.com/api/v1/categories"

Response:

json
{
  "categories": [
    { "category": "web", "count": 297 },
    { "category": "crypto", "count": 197 },
    { "category": "reverse", "count": 134 }
  ]
}
GET/writeups/{id}

Writeup preview: metadata, tags, techniques. No full content or flag.

Parameters:

idstringrequiredWriteup ID (path parameter)

Example:

bash
curl "https://api.ctfbase.com/api/v1/writeups/picoctf2024_heap_overflow"

Response:

json
{
  "id": "picoctf2024_heap_overflow",
  "title": "Heap Overflow — PicoCTF 2024",
  "category": "pwn",
  "difficulty": "medium",
  "event": "PicoCTF 2024",
  "description": "Task: Exploit a heap overflow...",
  "tags": ["heap", "overflow", "glibc"],
  "techniques": ["heap-overflow", "use-after-free"]
}
GET/writeups/{id}/fullpro+

Full writeup content (markdown). Anonymous + Free can read writeups marked is_free=true. All other writeups require Pro+ (counts against Pro 100/day, Scale 500/day quota).

Parameters:

idstringrequiredWriteup ID (path parameter)

Example:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.ctfbase.com/api/v1/writeups/picoctf2024_heap_overflow/full"

Response:

json
{
  "id": "picoctf2024_heap_overflow",
  "title": "Heap Overflow — PicoCTF 2024",
  "content": "## Analysis\n\nThe binary has a heap overflow...",
  "tools": ["gdb", "pwntools", "ghidra"],
  "indicators": ["CVE-2024-XXXX"]
}
GET/writeups/{id}/flagpro+

Returns the flag. Requires Pro+ tier. Counts against the per-user daily quota (Pro 100, Scale 500). Free returns 403 with upgrade URL.

Parameters:

idstringrequiredWriteup ID (path parameter)

Example:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.ctfbase.com/api/v1/writeups/picoctf2024_heap_overflow/flag"

Response:

json
{
  "id": "picoctf2024_heap_overflow",
  "flag": "picoCTF{h34p_0v3rfl0w_m4st3r}"
}

$ man mcp

CTF Base exposes an MCP server at mcp.ctfbase.com/mcp. Connect your AI assistant to search writeups directly from chat.

available on all tiers including Free — agents can use the search tool freely, and get_writeup returns a preview with paywall hint when full content requires Pro. Pro+ unlocks get_writeup (full body) and get_flag. generate an API key to get started.

mcp-tools

$ mcp tools/list

search

Search CTF writeups by query and optional category.

params: query: string, category?: string, limit?: int

get_writeup

Get full writeup content by ID. Returns markdown with solution.

params: writeup_id: string

get_flag

Get the flag for a specific writeup.

params: writeup_id: string

Claude Code

bash
claude mcp add ctfbase \
  --transport streamable-http \
  --url "https://mcp.ctfbase.com/mcp" \
  --header "Authorization: Bearer YOUR_MCP_KEY"

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json

json
{
  "mcpServers": {
    "ctfbase": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.ctfbase.com/mcp",
        "--header",
        "Authorization: Bearer YOUR_MCP_KEY"
      ]
    }
  }
}

Cursor

.cursor/mcp.json

json
{
  "mcpServers": {
    "ctfbase": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.ctfbase.com/mcp",
        "--header",
        "Authorization: Bearer YOUR_MCP_KEY"
      ]
    }
  }
}

Codex CLI

~/.codex/config.toml

toml
[mcp_servers.ctfbase]
command = "npx"
args = [
  "-y", "mcp-remote",
  "https://mcp.ctfbase.com/mcp",
  "--header",
  "Authorization: Bearer YOUR_MCP_KEY",
]
mcp-example

You: How do I exploit a format string vulnerability in a CTF?

[MCP] calling ctfbase.search("format string vulnerability exploit")

[MCP] found 23 results, reading top match...

AI: Based on 23 real CTF writeups, the most common approach is...

$ man auth

Public endpoints

/search, /categories, /writeups/{id} require no authentication.

Protected endpoints

/writeups/{id}/full on paid writeups and /writeups/{id}/flag require Pro+. Free users get full text on is_free writeups only; everything else returns 403 with an upgrade URL. The daily quota for Pro+ is enforced per-user and shared between web (cookie) and API-key (MCP) traffic: Pro 100/day, Scale 500/day.

Authenticate via API key in the Authorization header:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.ctfbase.com/api/v1/writeups/example/full"

Getting an API key

Sign in and generate an API key from your dashboard. Free accounts get 1 key (enough for MCP); Pro gets 3, Scale 10.

$ cat rate-limits.conf

rate-limits
tierrequests/dayapi_keysfull_access
freesearch only1no
pro1003yes
scale50010yes

Public /search and /suggest are capped at 60 requests/minute per IP to prevent scraping. /stats and /categories are unlimited. For Pro+, daily per-user limits apply to /writeups/{id}/full and /writeups/{id}/flag and are shared across cookie and API-key (MCP) transports — no separate MCP quota. Free tier has no quota: paid endpoints return 403 with an upgrade URL.

$ cat errors.log

error-codes
400Bad RequestInvalid query parameters or malformed request.
401UnauthorizedMissing or invalid API key / session.
403ForbiddenValid auth but action requires a paid tier (e.g. free user trying /full on a paid writeup or /flag).
404Not FoundWriteup ID does not exist.
429Too Many RequestsDaily quota reached (Pro 100, Scale 500). Resets at 00:00 UTC. Free tier never hits 429 — it gets 403 instead.
500Internal Server ErrorSomething went wrong. Try again or report the issue.

Error response format:

json
{
  "detail": "Upgrade to Pro to read full writeups & flags: https://ctfbase.com/pricing"
}