What It Does
Two ways to interact with your Caido proxy:
- MCP Server - expose 67 tools and 6 read-only resources to AI assistants (Claude Code, Cursor, etc.) via the Model Context Protocol
- CLI - standalone terminal client for pentesters who prefer the command line
Both share the same auth token, the same Go SDK, and the same codebase.
Features
Built-in security and performance:
- Credential redaction - Authorization, Cookie, and API key headers are redacted in tool output by default (including raw request/response dumps and the
caido://requests/{id}resource); opt out withCAIDO_ALLOW_SENSITIVE_HEADERS(see Revealing sensitive headers) - Tool annotations - every tool declares
readOnlyHint/destructiveHint/idempotentHint/openWorldHintso MCP clients can distinguish read-only, destructive, and external-network tools - Session cookie jar - RFC 6265 jar per replay session;
Set-Cookiefrom a response is auto-attached to the nextsend_requestagainst the same session - Response fingerprinting - auto-detects content kind (json/html/xml/text/binary) so agents know what they're dealing with
- Adaptive body limits - JSON gets 4KB, HTML 3KB, binary 200B (override with explicit
bodyLimit) - Response diff - repeated identical responses in the same session collapse to a one-line summary, saving tokens
- Input validation - length limits on all string inputs to prevent context flooding
- Token auto-refresh - expired OAuth tokens refresh mid-session automatically
- Session reuse - single replay session per server lifetime, no sprawl
Session cookie jar
The caido_send_request tool maintains an in-memory http.CookieJar per replay session. Cookies set via Set-Cookie in any response are stored and auto-injected into subsequent requests targeting the same RFC 6265 domain/path. Pass useCookieJar: false to a single call to disable injection (useful for session-fixation testing or to verify auth gates). Use caido_clear_session_cookies to wipe a session jar between test runs and caido_get_session_cookies to introspect what is stored (cookie values are not returned, only metadata).
The output of caido_send_request includes a cookieJar block with injectedCookies (names sent on this call) and storedCookies (names captured from Set-Cookie), so the LLM can verify the chain stayed authenticated.
Response fingerprinting
Every caido_send_request / caido_batch_send response includes a compact fingerprint so an agent can reason about a response without the full body:
title- HTML<title>, if presentredirect- Location target on a 3xxcookieNames- names set viaSet-Cookie(values are never included)wordCount- body word count, for size/diff comparisonnotableHeaders- non-standard response headers (Server,X-Powered-By, customX-*). App and flag signal often hides here - check these on every response, including 4xx/5xx.
The fingerprint stays populated even when includeBody: false.
Revealing sensitive headers
By default, sensitive headers (Authorization, Cookie, Set-Cookie, Proxy-Authorization, X-Api-Key, X-Auth-Token, X-CSRF-Token, X-XSRF-Token) are replaced with [REDACTED] in tool output to avoid leaking credentials into the model context. On an authorized engagement where you need the real values — to analyze or replay a captured authenticated request, or to produce a working caido_export_curl PoC — set CAIDO_ALLOW_SENSITIVE_HEADERS to a truthy value (1, true):
{
"mcpServers": {
"caido": {
"command": "caido-mcp-server",
"args": ["serve"],
"env": {
"CAIDO_URL": "http://127.0.0.1:8080",
"CAIDO_ALLOW_SENSITIVE_HEADERS": "true"
}
}
}
}
When enabled, real credential values flow through tool output to the model; leave it unset to keep redaction. This toggle does not affect the session cookie jar, which only ever reports cookie names and metadata, never values.
MCP Server
Install
curl -fsSL https://raw.githubusercontent.com/c0tton-fluff/caido-mcp-server/main/install.sh | bash
Or download a pre-built binary from Releases (macOS, Linux, Windows - amd64/arm64).
Or install with the Go toolchain (Go 1.25+):
go install github.com/c0tton-fluff/caido-mcp-server/v4/cmd/caido-mcp-server@latest
The binary lands in $(go env GOPATH)/bin (add it to your PATH). The installed binary reports its module version via caido-mcp-server --version.
git clone https://github.com/c0tton-fluff/caido-mcp-server.git
cd caido-mcp-server
go build -ldflags "-X github.com/c0tton-fluff/caido-mcp-server/v4/internal/buildinfo.version=$(git describe --tags)" -o caido-mcp-server ./cmd/caido-mcp-server
Quick Start
Option A: Static access token (recommended)
This server talks to the local Caido app's GraphQL API, which authenticates with the access token from your Caido login session — not a Caido Cloud Personal Access Token. A Cloud PAT (prefixed caido_) is for the cloud/dashboard API and will not authenticate against your local instance.
Grab the access token from the Caido GUI: open developer tools (CTRL+SHIFT+I) and run this in the Console tab:
JSON.parse(localStorage.CAIDO_AUTHENTICATION).accessToken
Pass it via the CAIDO_ACCESS_TOKEN environment variable. No login command needed.
{
"mcpServers": {
"caido": {
"command": "caido-mcp-server",
"args": ["serve"],
"env": {
"CAIDO_URL": "http://127.0.0.1:8080",
"CAIDO_ACCESS_TOKEN": "your-caido-access-token"
}
}
}
}
Note: this token expires after ~7 days; for a long-lived setup use Option B (OAuth), which refreshes automatically. The older
CAIDO_PATvariable is still accepted as a deprecated alias forCAIDO_ACCESS_TOKEN.
Option B: OAuth device flow
CAIDO_URL=http://localhost:8080 caido-mcp-server login
This opens your browser for OAuth authentication and saves the token under ~/.caido-mcp/tokens/. Then configure your MCP client:
{
"mcpServers": {
"caido": {
"command": "caido-mcp-server",
"args": ["serve"],
"env": {
"CAIDO_URL": "http://127.0.0.1:8080"
}
}
}
}
Credentials are stored per instance, keyed by the canonical CAIDO_URL, so you can stay
logged in to several Caido instances at once and switch between them without
re-authenticating. Run login once per instance. An existing
~/.caido-mcp/token.json from an earlier version is migrated automatically the first time
you use it, so upgrading does not require a fresh login.
3. Use it
"List all POST requests to /api"
"Send this request with a modified user ID"
"Create a finding for this IDOR"
"Show fuzzing results from Automate session 1"
"What's in scope?"
MCP Tools (66)
MCP Resources (6)
Read-only data exposed via the MCP resources protocol. Agents can read these without consuming tool calls.
caido_list_requests
caido_get_request
caido_send_request
caido_get_replay_entry
caido_get_automate_entry
caido_create_finding
caido_create_scope
caido_select_project
caido_intercept_control
caido_list_intercept_entries
caido_forward_intercept
caido_drop_intercept
caido_automate_task_control
caido_delete_findings
caido_export_findings
caido_list_environments
No parameters required. Returns all environments with variables and selected/global context.
caido_select_environment
caido_run_workflow
caido_toggle_workflow
caido_list_tamper_rules
No parameters required. Returns all tamper rule collections with nested rules
(id, name, section, enabled, condition, sources).
caido_create_tamper_rule
Operation modes
match_kind selects how match is read: regex (default), value (literal
substring, no escaping) or full (the entire section, match must be omitted).
Use workflow_id instead of value to supply the replacement from a convert
workflow.
All four modes are available on requestHeader, responseHeader and
requestQuery. Every other section supports exactly one mode, and asking for
another returns an error naming the modes it does support:
requestAll, requestBody, requestFirstLine, requestPath, responseAll,
responseBody, responseFirstLine take updateRaw; requestMethod,
requestSNI, responseStatusCode take updateValue (they always apply, so
they accept no match or name).
Omitting operation entirely falls back to the section's default mode with the
legacy match/replace fields, so existing callers keep working unchanged.
caido_update_tamper_rule
Full update: pass the complete rule state, not a partial patch. Accepts the same
section, operation and legacy match/replace parameters as
caido_create_tamper_rule.
caido_test_tamper_rule
Dry-run a rule against a raw HTTP request or response and return the transformed
result. Nothing is persisted and no traffic is sent. Accepts the same section,
operation and legacy match/replace parameters as
caido_create_tamper_rule.
Returns raw (the transformed message) and changed (whether the rule matched
anything at all), which is the quickest way to catch a rule that silently
matches nothing.
caido_toggle_tamper_rule
caido_delete_tamper_rule
CLI
Standalone terminal client for Caido. No MCP required - use it directly from your shell.
Install
curl -fsSL https://raw.githubusercontent.com/c0tton-fluff/caido-mcp-server/main/install.sh | TOOL=cli bash
Or download from Releases.
Or install with the Go toolchain (Go 1.25+):
go install github.com/c0tton-fluff/caido-mcp-server/v4/cmd/caido-cli@latest
git clone https://github.com/c0tton-fluff/caido-mcp-server.git
cd caido-mcp-server
go build -o caido-cli ./cmd/caido-cli
Usage
Requires authentication - run caido-mcp-server login first to store a token. (The CLI reads the stored login token; it does not consume the CAIDO_ACCESS_TOKEN env var that the MCP server uses.)
# Check connection and auth
caido-cli status -u http://localhost:8080
# Send structured requests
caido-cli send GET https://target.com/api/users
caido-cli send POST https://target.com/api/login -j '{"user":"admin","pass":"test"}'
caido-cli send PUT https://target.com/api/profile -H "Authorization: Bearer tok" -j '{"role":"admin"}'
# Send raw HTTP requests
caido-cli raw 'GET /api/users HTTP/1.1\r\nHost: target.com\r\n\r\n'
caido-cli raw -f request.txt --host target.com --port 8443
echo -n 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | caido-cli raw -
# Parallel requests via Replay (BAC sweeps, param fuzzing, endpoint sweeps)
caido-cli batch sweep https://target.com/api/profile -t "owner=eyJ1...,cross=eyJ2...,noauth"
caido-cli batch fuzz "https://target.com/api/search?q=test" -p q -v "test,test',1 OR 1=1" -H "Authorization: Bearer eyJ..."
caido-cli batch ep -t eyJ... https://target.com/dashboard https://target.com/admin
caido-cli batch file batch.json
# Browse proxy history
caido-cli history
caido-cli history -f 'req.host.eq:"target.com"' -n 20
# Get full request/response details
caido-cli request 12345
# Encode/decode
caido-cli encode base64 "hello world"
caido-cli decode url "%3Cscript%3E"
caido-cli encode hex "test"
Commands
Global Flags
Architecture
caido-mcp-server/
cmd/
caido-mcp-server/ MCP server (stdio transport)
caido-cli/ Standalone CLI
internal/
auth/ OAuth device flow, static access token (CAIDO_ACCESS_TOKEN), token store, auto-refresh
buildinfo/ Version resolution (ldflag or go-install module version)
httputil/ HTTP parsing, fingerprinting, response diff, CRLF normalization
replay/ Replay session management, cookie jar, response polling
resources/ MCP read-only resources (requests, sessions, sitemap, findings)
tools/ MCP tool definitions (one file per tool)
testutil/ Mock GraphQL server, MCP test helpers, fixtures
The cmd/ directory names match the installed binary names so go install .../cmd/caido-mcp-server@latest produces a correctly-named binary. Both commands share internal/ packages. The project uses caido-community/sdk-go for all GraphQL communication with Caido.
Troubleshooting
MCP server logs: ~/.cache/claude-cli-nodejs/*/mcp-logs-caido/
Security
Sensitive HTTP headers (Authorization, Cookie, Set-Cookie, API keys) are redacted everywhere output leaves the server - structured tool output, raw request/response dumps, fuzz templates, and the caido://requests/{id} resource all pass through a single redaction choke-point to prevent credential leakage to LLM context. On an authorized engagement you can opt out with CAIDO_ALLOW_SENSITIVE_HEADERS (see Revealing sensitive headers). All string inputs are length-validated server-side, and request batch sizes are capped.
Access tokens (via CAIDO_ACCESS_TOKEN) and OAuth tokens are stored with 0600 permissions and never appear in process arguments or log output.
To report a security issue, open a GitHub issue or contact the maintainer directly.
Contributing
- Fork the repo
- Create a feature branch
go build ./...andgo test ./... -race- Open a PR (CI runs build, test, vet, staticcheck)
Local pre-push gate
A tracked .githooks/pre-push runs the same checks as CI's lint + test jobs (gofmt, go vet, golangci-lint run ./..., go test ./... -race) so failures are caught before they reach CI. Enable it once per clone:
git config core.hooksPath .githooks
go install github.com/golangci/golangci-lint/v2/cmd/[email protected]
Built with caido-community/sdk-go and modelcontextprotocol/go-sdk.