Offline methodology engine for authorized penetration testing, CTF, and security research.
Offline methodology engine and payload workshop for authorized penetration testing, CTF, security research, and education via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://pentest.caseyjhand.com/mcp
Authorized use only. This server is designed for penetration testers, red teamers, CTF players, security researchers, and students working on systems they own or have explicit written authorization to test. Users are solely responsible for ensuring their testing is lawful and appropriately scoped. Unauthorized access to computer systems is illegal — this server does not and cannot enforce authorization on your behalf.
Dual-audience design. Every offensive technique is paired with detection indicators and mitigations. Blue teamers, developers, and anyone building detection coverage will find the methodology and ATT&CK data as useful as the red team workflows.
Offline penetration-testing methodology engine: MITRE ATT&CK techniques and threat groups, OWASP Testing Guide methodology, and annotated payload templates for authorized penetration testing, CTF, and security research. Generate a phased testing playbook, map techniques to a target profile, analyze HTTP responses for leakage, and generate or encode payload templates from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
pentest_guide | Step-by-step authorized-testing methodology playbook for a chosen attack vector, phase-filterable, with detection and mitigation per technique. |
pentest_analyze_response | Analyzes raw HTTP response headers/body from authorized probing for leakage, fingerprinting, and misconfiguration. |
pentest_lookup_technique | Looks up a MITRE ATT&CK technique by ID or keyword, with detection data, mitigations, and procedure examples. |
pentest_lookup_group | Looks up a MITRE ATT&CK threat group or software entry by ID or name, with aliases and technique usage. |
pentest_map_techniques | Ranks ATT&CK techniques and OWASP test cases against a target profile (stack, services, auth type, OS). |
pentest_generate_payloads | Generates annotated payload templates for a vulnerability category and injection context, with optional WAF bypass variants and encoding. |
pentest_encode | Applies an ordered encoding chain to a payload string with decode-path tracing. |
pentest_guide toolvector enum: auth_bypass, idor, ssrf, xss, sqli, xxe, path_traversal, cors, csrf, open_redirect, deserialization, race_condition, ssti, command_injection, jwt_attacktarget_context (stack, waf, recon_notes) narrows the playbook to stack-specific techniques and WAF-bypass-aware variantsphase filter: all (default), recon, enumeration, exploitation, or post_exploitationdetection and mitigation; response also includes owasp_references (WSTG IDs) and attack_technique_ids for cross-referencingauthorized_use_reminder rendered as the first line of every responsenextToolSuggestions pre-filled with payload-generator and ATT&CK-lookup calls derived from the methodology contextpentest_analyze_response toolresponse_headers (≤20,000 chars), response_body (≤10,000 chars), status_code (100–599), and freeform context (≤2,000 chars) — at least one of headers or body is requiredseverity (info/low/medium/high)detection and remediation; results are ordered by severity descendingfingerprints block (server_software, framework, language, database, cloud_provider, other) ready for use as target context in pentest_guide or pentest_map_techniquesno_input error when neither response_headers nor response_body is suppliednextToolSuggestions pre-filled from detected fingerprints and findingspentest_lookup_technique toolT1190, T1059.001) or a keyword; ID lookup is exact, keyword falls back to best-match searchsummary, data_sources, indicators), mitigations, and procedure examples from public ATT&CK reportinginclude_subtechniques (default true) toggles sub-technique inclusionattack_version echoes the embedded ATT&CK dataset version (e.g. "Enterprise v19.1") on every responseno_match error when the ID or keyword resolves to nothingpentest_lookup_group toolG0007) or software ID (S0002), or a name/keyword (APT28, Mimikatz)type discriminates group (intrusion set) from software (malware/tool); aliases lists known alternate namestechniques_used returns up to 20 techniques with procedure-level context, each linking to pentest_lookup_technique by technique_iddescription truncated to 800 charactersno_match error when the ID or name resolves to nothingpentest_map_techniques toolstack (array), services (array), auth_type (jwt/session_cookie/api_key/oauth2/basic_auth/ntlm/kerberos/none/unknown), os (linux/windows/macos/unknown) — at least one requiredrelevance_rationale lists exactly which criteria matchedlimit caps ranked_techniques at 1–50 (default 15); enrichment (truncated, shown, cap) discloses when results were cappeddetection_opportunity, mitigation_summary, and an optional pentest_guide_vector for follow-upowasp_test_cases returns up to 10 relevant OWASP Testing Guide test casesno_profile error when no profile field is suppliedpentest_generate_payloads toolxss, sqli, ssrf, xxe, path_traversal, ssti, command_injection, open_redirect, csrf, deserialization, jwt, ldap_injection, nosql_injection, http_header) × 16 injection contexts (html_attribute, html_body, js_string, js_template, js_script_block, url_parameter, url_path, sql_where, sql_integer, xml_element, xml_attribute, http_header, json_value, cookie_value, file_name, generic)waf_profile (cloudflare, aws_waf, modsecurity_crs, imperva, akamai, f5_bigip_asm, nginx_modsecurity, fortinet_fortiwaf, none default, unknown) adds bypass variants referencing public research when setencoding chain applied to each returned template; count caps results at 1–20 (default 5)detection_signature and mitigation; waf_bypass_note present only when waf_profile isn't noneauthorized_use_reminder rendered first in every responsepentest_encode toolpayload string up to 10,000 characters; chain is an ordered list of 1–6 encoding steps applied left to righturl, double_url, html_entity, unicode, hex, base64, js_escape, null_byte, mixed_case, comment_breakintermediate_steps traces the value after each chain step; explain (default true) adds decode_path and bypass_rationaledetection_note on every response — how defenders detect encoded variantsencoding_error when a step produces invalid outputBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Methodology-specific:
scripts/refresh-attack.ts and indexed in memory by ID/keyword; fails fast with an actionable error if the data file is missingreadOnlyHint: true, openWorldHint: false — deterministic output from a bounded embedded datasetAgent-friendly output:
authorized_use_reminder rendered as the first line of content[] on every guide/payload/encoding response — consistent framing regardless of which surface a client forwardsdetection and mitigation fields required (non-optional) on every technique, finding, and payload — defenders always get usable context alongside offense techniqueattack_version echoed on every ATT&CK-backed response so callers can reason about data vintagenextToolSuggestions pre-filled with arguments derived from the current context, reducing agent planning overheadThe server embeds MITRE ATT&CK Enterprise data (~20 MB JSON) fetched by a one-time script into a gitignored path. Self-hosters and Docker builders must run this step before the server will start:
bun run scripts/refresh-attack.ts
This downloads the latest ATT&CK Enterprise JSON from the MITRE GitHub release endpoint, writes it to src/data/attack/enterprise.json (gitignored), and updates src/data/attack/version.ts with a version string such as Enterprise v16.1. The version file is committed; the JSON is not (too large for git history).
The Dockerfile handles this automatically — the build stage runs scripts/refresh-attack.ts before the TypeScript compile, so docker build produces a self-contained image.
If you clone the repo and skip this step, attack-service will fail fast at startup with an actionable error message pointing to scripts/refresh-attack.ts.
Run the script quarterly (or before each release) to pull the latest ATT&CK version.
A public instance is available at https://pentest.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"pentest-mcp-server": {
"type": "streamable-http",
"url": "https://pentest.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"pentest-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/pentest-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"pentest-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/pentest-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"pentest-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/pentest-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
bun run scripts/refresh-attack.ts once after cloning (Docker builds handle this automatically).git clone https://github.com/cyanheads/pentest-mcp-server.git
cd pentest-mcp-server
bun install
bun run scripts/refresh-attack.ts
cp .env.example .env
# edit .env if needed — no required vars beyond transport defaults
No API keys required. The server is fully offline at runtime.
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level: debug, info, notice, warning, error. | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Build and run:
# Seed ATT&CK data (first time, or to update)
bun run scripts/refresh-attack.ts
# Build
bun run rebuild
# Run
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security audit
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions
# Build — ATT&CK data is fetched during the build stage
docker build -t pentest-mcp-server .
docker run --rm -p 3010:3010 pentest-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/pentest-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them. The ATT&CK data refresh runs automatically in the build stage.
| Directory / File | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and initializes services. |
src/services/attack/ | MITRE ATT&CK service — loads and indexes the embedded enterprise JSON at startup. |
src/services/methodology/ | OWASP Testing Guide methodology service — vector branches for pentest_guide. |
src/services/payload/ | Payload template service — keyed by category and injection context. |
src/services/encoding/ | Encoding chain executor — pure TypeScript transforms. |
src/services/response-analysis/ | Pattern library for information leakage and fingerprinting detection. |
src/mcp-server/tools/definitions/ | Tool definitions (*.tool.ts) — one file per tool. |
src/data/attack/ | enterprise.json (gitignored, fetched by scripts/refresh-attack.ts) + committed version.ts. |
src/data/owasp/ | Curated OWASP TG v4.2 methodology content as TypeScript modules. |
src/data/payloads/ | Annotated payload templates by vulnerability category. |
src/data/waf-bypass/ | WAF bypass variants keyed by product and attack vector. |
src/data/encodings/ | Encoding transform functions. |
src/data/patterns/ | Regex patterns and metadata for response leakage detection. |
scripts/refresh-attack.ts | Downloads ATT&CK Enterprise JSON and updates the version string. Run once after cloning, then quarterly. |
tests/ | Unit and integration tests mirroring src/. |
docs/design.md | Design document — tool surface, data strategy, and architectural decisions. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
ctx.fail contractctx.log for request-scoped logging and keep request handling stateless and deterministicsrc/mcp-server/tools/index.tsauthorized_use_reminder is a required output field on every tool that produces methodology or payload content — render it as the first line of every content[] response in format()detection and mitigation fields — this is a schema contract, not documentation guidanceIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/pentest-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-pentest-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/pentest-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/pentest-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.