A Model Context Protocol (MCP) server for
the Mayhem for API CLI
(mapi).
Note
The code in this repository is provided as-is and is intended only for demonstration purposes. This project is not officially supported or actively maintained.
Note
Not all MCP clients surface prompts as slash commands. VS Code Copilot shows
/onboard-mapi-scan and /generate-exploit in the prompt picker. Claude
Desktop, Claude Code, and most other clients require asking the model to run
the prompt by name (e.g., "Run the onboard-mapi-scan prompt") or using the
individual tools directly.
Discover APIs running on a single host, multiple hosts, CIDR blocks, or domains.
Run a scan to check an API for defects.
The /onboard-mapi-scan prompt runs an end-to-end fuzzing workflow. It verifies
your environment, runs an initial scan, evaluates endpoint coverage, suggests
configuration improvements, and emits a bash script you can commit to CI. The
loop iterates until coverage meets a target threshold or the iteration limit is
reached.
Tools used:
evaluate_scan_quality- parses the HAR output and spec to compute endpoint coverage (covered_pct), surface auth hints, and identify unreachable endpointssuggest_tune_changes- applies heuristic rules (auth headers, request count, duration, endpoint exclusions, validation errors) to propose the next tuning stepemit_scan_script- writes aset -euo pipefailbash script with all finalized flags and env-var guards for the leave-behind artifact
Invoking the prompt:
In your MCP client, invoke /onboard-mapi-scan with the following arguments:
| Argument | Required | Default | Description |
|---|---|---|---|
workspace |
yes | — | Mayhem workspace name (e.g. myorg) |
project |
yes | — | Mayhem project name (e.g. my-api) |
target_name |
no | "" |
Specific target within the project; omit to use the project default |
specification |
yes | - | Path to an OpenAPI/Swagger/Postman spec file |
url |
yes | - | Base URL of the API under test |
duration |
no | 30s |
Initial scan duration |
max_iterations |
no | 3 |
Maximum tune-loop iterations |
min_covered_pct |
no | 25 |
Coverage threshold that stops the loop early |
The --har flag is handled automatically. mapi writes HAR output to /tmp;
evaluate_scan_quality reads it from there.
Note
Any suggestion to add --ignore-endpoint (which narrows the fuzzer's attack
surface) will be surfaced with a [FUZZING NARROWING WARNING] and requires
explicit confirmation before it is applied.
After the first quality evaluation, the /onboard-mapi-scan prompt optionally
analyzes the API spec and source code to propose targeted configuration improvements:
resource hints for low-coverage PATH parameters, rule prioritization based on
observed code patterns, and endpoint or tag filters where appropriate.
Tools used:
mapi_describe_specification- fetches the full parameter table from a spec (used internally by the prompt to identify which parameters need seeding)suggest_source_aware_changes- applies heuristic rules to spec parameters and source-extracted values to propose--resource-hint,--include-rule, and--experimental-ruleschangesemit_mapi_config- generates a.mapiYAML configuration file with correlated resource hint groups and issue suppressions for team sharing or SCM storage
How it works:
Capability 2 runs as an optional Step 4.5 inside the /onboard-mapi-scan
flow, after the first scan quality evaluation. The prompt identifies PATH parameters
with zero coverage, asks you to point to relevant source files (fixture data, enum
definitions, seed files), reads them, and generates a small number of targeted
hints. It also detects code patterns (SQL queries, subprocess calls, file operations,
PII fields) and suggests enabling the corresponding mapi rules.
You don't need a separate invocation. It runs inside the standard
/onboard-mapi-scan flow.
Fuzziness guardrail:
--resource-hintand--include-rulesuggestions are applied without extra confirmation - they expand mapi's reach, not narrow it- Any suggestion involving
--ignore-endpoint,--ignore-endpoints-by-tag, or--ignore-rulecarries a[FUZZING NARROWING WARNING]and requires explicit confirmation before it is applied - Resource hints are capped at 3-5 per session to preserve fuzzer input entropy (mapi applies hints on the majority of generated requests)
.mapi config file:
At the end of the flow, the prompt optionally offers to generate a .mapi YAML
config file via emit_mapi_config. This is most useful when you need correlated
parameter groups (multiple parameters seeded together consistently) or want to
commit suppressions to source control for team sharing. For one-off scans, the
emitted bash script is sufficient.
Warning
The server never sends exploit requests. All output is text for the user to review and decide whether to run. Obtain appropriate authorization before executing any suggested request.
For each defect found by a mapi run, the /generate-exploit prompt confirms
the defect still reproduces, crafts a targeted HTTP request demonstrating its
impact, and emits a leave-behind markdown report.
How to invoke:
In your MCP client, invoke /generate-exploit with:
| Argument | Required | Default | Description |
|---|---|---|---|
run_id |
yes | - | Mayhem run ID containing the defects (e.g. myorg/api/42) |
url |
yes | - | Base URL of the API under test |
specification |
no | "" |
Spec path for endpoint context |
source_dir |
no | "" |
Source root for higher-fidelity exploit crafting |
output_path |
no | exploit-report.md |
Path for the leave-behind report |
Note
The server resolves output_path on its own filesystem. When the server runs
in a Docker container (the default for all client configurations shown below),
that path lives inside the ephemeral container and disappears when it exits.
Two options:
- The inline chat output from the prompt is the reliable artifact and works regardless of how you launch the server.
- To write a file to the host, add a volume mount to the Docker args
(
-v /path/to/workspace:/work) and setoutput_pathto a path under/work.
For a local uv run launch (see Local Development),
output_path writes to the host directly.
Leave-behind tool:
emit_exploit_report generates a markdown file with one section per defect:
the reproducing request, the suggested exploit, and source code references if
available.
Safety boundary:
- The server never issues HTTP requests to the API. The exploit suggestion is text only; the user manually copies and runs it.
- Any suggestion that would mutate or delete server state (account changes, data
deletion, DoS) is tagged
[DESTRUCTIVE]and requires explicit user confirmation before it is included in the report. - The prompt replaces any credentials or tokens observed in defect data with
typed placeholders (
<BEARER_TOKEN>,<PASSWORD>, etc.). Real values never reach the report. - Safety warnings appear at four points: prompt start, before each exploit is crafted, at the destructive-action gate, and after the report is generated.
MCP servers connect to AI applications like Claude, Cursor, or VS Code Copilot. The sections below cover setup for each supported client.
If necessary, follow
the steps
to authenticate to the GitHub Container registry with a personal access token
(classic). You only need the read:packages scope.
Note
To check login status, run docker login ghcr.io.
Visual Studio Code has
native MCP support.
This repository includes a reference .vscode/mcp.json.
To add the server to a project, copy .vscode/mcp.json to the same location in
your target project. If your project already has a .vscode/mcp.json, merge the
mapi entry into it. To apply it across all projects in a
VS Code profile, place
the file in the profile directory instead.
Once configured, open the Copilot Chat window, start the server, and use the tool
picker to enable the mapi server. See the
official documentation
for details.
VS Code supports prompted input via ${input:promptString}. The included
.vscode/mcp.json prompts for MAYHEM_TOKEN and MAYHEM_URL on first use
and stores them in VS Code's secret storage.
Add the following to .cursor/mcp.json in your project (or ~/.cursor/mcp.json
for global access):
{
"mcpServers": {
"mapi": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--network", "host",
"-e", "MAYHEM_URL",
"-e", "MAYHEM_TOKEN",
"ghcr.io/forallsecure/mcp-server-mapi:latest",
"uv", "run", "mcp-server-mapi", "mcp"
]
}
}
}Both come from the host environment via the -e flags in the Docker args.
Cursor does not support prompted input. Export both before launching:
export MAYHEM_TOKEN=your-token-here
export MAYHEM_URL=https://app.mayhem.securityAdd these lines to your shell startup file (~/.zshrc, ~/.bashrc, etc.) to
avoid setting them manually each session.
This repository also includes a reference .cursor/mcp.json.
Add the following to .windsurf/mcp.json in your project (or
~/.codeium/windsurf/mcp_config.json for global access):
{
"mcpServers": {
"mapi": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--network", "host",
"-e", "MAYHEM_URL",
"-e", "MAYHEM_TOKEN",
"ghcr.io/forallsecure/mcp-server-mapi:latest",
"uv", "run", "mcp-server-mapi", "mcp"
]
}
}
}Like Cursor, Windsurf picks up MAYHEM_TOKEN and MAYHEM_URL from the host
environment. Export both before launching:
export MAYHEM_TOKEN=your-token-here
export MAYHEM_URL=https://app.mayhem.securityThis repository also includes a reference .windsurf/mcp.json.
Add the following to .mcp.json at your project root (project-scoped), or
configure globally with claude mcp add:
{
"mcpServers": {
"mapi": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--network", "host",
"-e", "MAYHEM_URL",
"-e", "MAYHEM_TOKEN",
"ghcr.io/forallsecure/mcp-server-mapi:latest",
"uv", "run", "mcp-server-mapi", "mcp"
]
}
}
}Like Cursor and Windsurf, both come from the host shell. Export them before launching:
export MAYHEM_TOKEN=your-token-here
export MAYHEM_URL=https://app.mayhem.securityNote
Claude Code does not surface MCP prompts as slash commands. To run
/onboard-mapi-scan or /generate-exploit, ask the model to invoke the prompt
by name, or use the individual tools directly.
A reference .mcp.json is not included in this repository.
Add the following to your Claude Desktop config file.
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mapi": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--network", "host",
"-e", "MAYHEM_URL",
"-e", "MAYHEM_TOKEN",
"ghcr.io/forallsecure/mcp-server-mapi:latest",
"uv", "run", "mcp-server-mapi", "mcp"
]
}
}
}Both come from the shell you launched Claude Desktop from. On macOS, start it from a terminal with both exported:
export MAYHEM_TOKEN=your-token-here
export MAYHEM_URL=https://app.mayhem.security
open -a "Claude"This repository includes a reference
claude_desktop_config.json.
Note
Claude Desktop does not surface MCP prompts as slash commands. To run
/onboard-mapi-scan or /generate-exploit, ask the model to invoke the prompt
by name, or use the individual tools directly.
This section describes how to acquire and run the code locally for development purposes.
Clone this repository:
git clone git@github.com:ForAllSecure/mcp-server-mapi.gitUse uv to run the MCP server for mapi:
MAYHEM_TOKEN=your-token-here uv run mcp-server-mapi mcp