hackerone-mcp
Read-only access to the HackerOne Hacker API: lists programs visible to the account, retrieves program details, policy, structured scopes and scope exclusions, accepted weaknesses (CWE types), and derives a submission-options summary. Combined with local draft tools to create, read, update, list, delete, and validate bug-bounty report drafts (title, vulnerability information, impact, severity rating, weakness/scope ids, CVSS vector, references) — drafts are never submitted; they are validated offline and previewed as never_sent request bodies for manual submission in the HackerOne web UI.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
hackerone-mcp
A stdio MCP server that helps a bug-bounty hacker prepare HackerOne report drafts locally. It reads program information from the HackerOne Hacker API (read-only) and stores drafts as files on your machine.
Non-goal: it never submits anything
This server does not submit, send, or publish reports, and it is built so that it cannot:
The only HTTP client code lives in
src/client/and only issuesGETrequests to the fixed originhttps://api.hackerone.com.There is no submit tool. A test (
src/tools/guard_tests.rs) pins the exact set of 12 tools and asserts no tool name containssubmit,send,post,publish,uploadorreport_remote.draft_validateonly shows a preview of the request body that would be sent; it is markednever_sent.
You review the draft and submit it yourself in the HackerOne web UI.
Related MCP server: h1-brain
Tools
Tool | Description | Parameters |
| List programs visible to your account (needs credentials) |
|
| Get one program incl. policy and submission state |
|
| List a program's structured scopes (assets) |
|
| List scope exclusions (report categories excluded from rewards) |
|
| List weaknesses (CWE types) the program accepts |
|
| Derived summary: submission state, scopes, accepted weaknesses |
|
| Create a local draft |
|
| Read a draft |
|
| Update fields; optimistic locking and field clearing |
|
| List draft summaries, newest first |
|
| Delete a local draft file |
|
| Offline validation plus a request-body preview (never sent) |
|
The program_* tools need HackerOne credentials; the draft_* tools work without them.
weakness_id and structured_scope_id are HackerOne's integer ids (take them from
program_submission_options), not CWE numbers.
Running with Docker
The server is distributed as a container image and is started over stdio, so the MCP client runs
docker run -i.
Image: ghcr.io/tkgstrator/hackerone-mcp, platforms linux/amd64 and linux/arm64. Tags per release:
X.Y.Z, vX.Y.Z, latest and sha-<full commit SHA>. Pin an explicit version in your client config rather
than latest.
The first push to GHCR creates the package as private. Until the owner has made it public once (manually, in the package settings), pull it after
docker login ghcr.iowith a token that hasread:packages.
docker pull ghcr.io/tkgstrator/hackerone-mcp:<version>
docker run -i --rm -v hackerone-mcp-drafts:/data/drafts ghcr.io/tkgstrator/hackerone-mcp:<version>The command above is draft-only (no credentials). To enable the program_* tools pass credentials
as described under Configuration.
Image details
Runtime is
gcr.io/distroless/cc-debian12(no shell); the entrypoint is the binary.It runs as non-root uid/gid
10001./data/draftsis pre-created with mode0700, owned by10001, declared as aVOLUME, andH1_MCP_DRAFTS_DIR=/data/draftsis preset.Named volumes (
-v hackerone-mcp-drafts:/data/drafts) need no setup: they inherit the right owner and mode.Bind mounts must satisfy the same rules, because the server refuses a drafts directory that is accessible by group/other (
drafts directory is accessible by group/other (expected mode 0700)) or not owned by the container user (cannot stat drafts directory: Permission denied). Prepare the host directory first:mkdir -p "$HOME/hackerone-drafts" chown 10001:10001 "$HOME/hackerone-drafts" && chmod 700 "$HOME/hackerone-drafts" # may need sudo docker run -i --rm -v "$HOME/hackerone-drafts:/data/drafts" ghcr.io/tkgstrator/hackerone-mcp:<version>Running with
--user "$(id -u):$(id -g)"instead is not verified and did not work on Docker Desktop / OrbStack because of ownership mapping.The filesystem behind
/data/draftsmust support hard links (named volumes do).
Configuration
Environment variables:
Variable | Meaning |
| HackerOne API username. Only needed for |
| HackerOne API token. Only needed for |
| Directory for drafts. Preset to |
Without credentials the server still starts and the draft tools work; program_* tools return a
clear configuration error.
Registering with an MCP client
Do not put the token in command-line arguments or in a config file that is world-readable:
arguments are visible to other local users via ps, and client config files are often synced or
committed. Keep the secrets in a file only you can read and hand it to Docker with --env-file
(Docker reads it; the values never appear in the command line). Alternatively use value-less
-e H1_USERNAME -e H1_API_KEY, which copies the variables from the environment of the launching
process, so the values are still not in argv.
# secrets file, readable only by you
mkdir -p ~/.config/hackerone-mcp
install -m 600 /dev/null ~/.config/hackerone-mcp/env
$EDITOR ~/.config/hackerone-mcp/env # add the two lines below
# H1_USERNAME=your-username
# H1_API_KEY=your-tokenClaude Code:
claude mcp add hackerone -- docker run -i --rm \
-v hackerone-mcp-drafts:/data/drafts \
--env-file "$HOME/.config/hackerone-mcp/env" \
ghcr.io/tkgstrator/hackerone-mcp:<version>Claude Desktop (claude_desktop_config.json; use an absolute path, $HOME is not expanded):
{
"mcpServers": {
"hackerone": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "hackerone-mcp-drafts:/data/drafts",
"--env-file", "/Users/you/.config/hackerone-mcp/env",
"ghcr.io/tkgstrator/hackerone-mcp:<version>"
]
}
}
}For draft-only use, drop the --env-file option; no credentials are needed.
Release archives
Each GitHub release also carries hackerone-mcp-vX.Y.Z-<target>.tar.gz archives (binary, LICENSE,
README.md) for aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu and
aarch64-unknown-linux-gnu, plus SHA256SUMS. They are attested; verify with:
gh attestation verify <archive> --repo tkgstrator/hackerone-mcp
shasum -a 256 -c SHA256SUMSThe Linux archives are built in the Debian bookworm toolchain; the binary's highest required glibc symbol version is 2.34 (measured). Docker is the documented way to run the server.
Draft file format
Each draft is <id>.md in the drafts directory: TOML frontmatter between +++ lines, then the
Markdown body (the report's vulnerability_information). Ids match [a-z0-9-]{1,64}.
+++
id = "example-xss"
revision = 1
created_at = 1792838334
updated_at = 1792838334
status = "draft"
team_handle = "acme"
title = "Stored XSS in profile bio"
impact = "Account takeover"
severity_rating = "high"
cwe = "cwe-79"
cvss_vector = "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N"
affected_versions = "< 2.4.1"
references = ["https://example.com/advisory"]
+++
## Steps
1. Open profilerevision increases on every update; pass expected_revision to draft_update/draft_delete to
avoid overwriting concurrent edits.
Draft tool outputs return the full body, up to the 200,000-byte body limit. Only a hand-edited file whose body exceeds that limit is returned truncated; the result then carries a server-generated top-level body_truncation object (truncated, returned_bytes, total_bytes, warning) outside the draft fields, and such a body must not be written back with draft_update.
Workflow
program_submission_optionsfor the target program (submission state, scope ids, weakness ids).draft_create, then refine withdraft_update.draft_validatefor an offline check of the required fields and a preview of the request body. It does not prove you are allowed to submit to the program.Copy the draft into the HackerOne web UI and submit it there, manually.
For CVE preparation the drafts carry cwe, cvss_vector and affected_versions. These are local
notes only. CVE IDs are assigned by a CNA (the vendor, a CNA-of-last-resort, or MITRE), never by this tool.
Security notes
Token handling: the API key is read from the environment, redacted in
Debugoutput, and is not written to stdout or stderr (checked bytests/stdio_e2e.rs). Use a0600env file as above.Data flows to your LLM client: tool results, including draft contents and program data, are sent to whatever model your MCP client uses. Do not store secrets in drafts.
Untrusted text: program policies, scope descriptions and other API-derived text are attacker-influenced. Responses are labelled as untrusted, but a model can still be prompt-injected by such text; review what the model does and writes.
Files: Unix only. The drafts directory is created with mode
0700and draft files with0600. New drafts are created atomically usinghard_link, so the drafts directory must be on a filesystem that supports hard links.Dependencies: HTTP is
reqwestwith rustls only (no OpenSSL / native-tls).deny.tomlbans alternative HTTP clients and TLS stacks, restricts licenses and sources. CI also checks that no direct dependency onhyperor other HTTP client crates is declared.
Development
Building from source requires Rust 1.89 or newer (edition 2024). Unix only (macOS, Linux).
cargo build --release # binary at target/release/hackerone-mcp
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test
cargo deny check
cargo audit
docker build -t hackerone-mcp:local .
scripts/docker-smoke.sh hackerone-mcp:local # needs docker and jq
bun install --frozen-lockfile --ignore-scripts && bunx commitlint --last --verbosetests/stdio_e2e.rs spawns the real binary and talks JSON-RPC over stdio. scripts/docker-smoke.sh
starts the image, checks initialize, that tools/list returns 12 tools, and a draft_create /
draft_get round trip.
Commits
Use Conventional Commits. CI commitlint checks PR commits and
non-master branch push tips; it skips normal GitHub merge commits on master. Configuration is in
.commitlintrc.yaml, with dependencies pinned in bun.lock. Allowed types: build, ui,
ci, docs, feat, fix, perf, refactor, revert, format, test, chore; header up to
128 characters.
CI (.github/workflows/integration.yaml)
Runs on pull requests, branch pushes, master pushes, and manual dispatch. On master, all checks
must pass before it calls the reusable Deployment workflow for the same commit:
Integration / Commit LintIntegration / rustfmtIntegration / Clippy (ubuntu-latest)andIntegration / Clippy (macos-latest)Integration / Test (ubuntu-latest)andIntegration / Test (macos-latest)Integration / Supply chain:cargo deny,cargo audit, and a guard against direct HTTP-client dependenciesIntegration / Docker (amd64)andIntegration / Docker (arm64): build each native-platform image (no push) and runscripts/docker-smoke.sh
Branch protection on master is expected to require these checks to pass before merge and to
disallow direct and force pushes (a repository setting, not enforced by files in this repo).
All third-party GitHub Actions are pinned to commit SHAs. Dependabot
(.github/dependabot.yml) proposes weekly updates for GitHub Actions, Cargo, Docker and Bun (package.json / bun.lock).
Releasing (.github/workflows/deployment.yaml)
For the first release, merge the release workflow to
master. For subsequent releases, bumpversioninCargo.tomland merge tomasterthrough a pull request. The version must be plainMAJOR.MINOR.PATCH; prerelease and build suffixes (-rc.1,+build) are not supported.Successful Integration checks call Deployment at that same commit. Deployment builds the four archives, then pushes the multi-arch image under a commit-SHA tag. After verifying the archives, checksums and draft release, and generating attestations, it points the version and
latesttags at the exact image digest and publishes the GitHub release.
Behaviour to know about:
Deployment checks that its tested commit is still the
masterhead before the image push, before moving version tags, and before publishing the release. A new push between a check and publication can still race; check the final tag and image after release.A push that does not change the version is a green no-op once a release for that version is published.
A tag
vX.Y.Zthat exists at another commit without a published release fails the run visibly; fix or delete the tag manually.Version and
latestimage tags are updated only after the draft assets are verified. GHCR and GitHub Releases are separate services: a failure after tag promotion can leave image tags before the release appears. Inspect the state before retrying Integration onmaster.A failed upload or publication can leave a draft release. A retry refuses to overwrite any draft with the same tag, including one written by a person. Inspect its assets and notes, then remove that draft manually before retrying. The workflow never deletes a draft automatically.
[skip ci]/[ci skip]suppresses the automatic run; dispatch Integration onmastermanually to run all checks and publish. The first GHCR push creates a private package; make it public in the package settings if anonymous pulls are required, then verify without Docker credentials.
License
MIT, see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Offline methodology engine for authorized penetration testing, CTF, and security research.
Search and monitor bug bounty programs and audit contests across ten platforms.
Programmatic control of the Hiro security platform: scans, tasks, plans, and approvals.
Bug Bounty Programs - HackerOne + Bugcrowd Lookup | Bulk
Related MCP Servers
- FlicenseAqualityDmaintenanceProvides read-only access to HackerOne reports, program scopes, and bounty earnings through the HackerOne API. It enables users to analyze hunting patterns, check asset eligibility, and retrieve report details or triage conversations via natural language.946 npm41-
- AlicenseNot gradedqualityCmaintenanceConnects AI assistants to HackerOne to pull bug bounty history, program scopes, and report details into a local SQLite database, exposing tools for searching, analyzing, and generating attack briefings using both personal and public disclosed reports.355MIT
- FlicenseAqualityDmaintenanceA local, read-only MCP server that connects your HackerOne researcher account to Claude Desktop and Claude Code, helping you find targets, analyze program scopes, review reports and earnings, and draft bug reports.174-
- FlicenseNot gradedqualityCmaintenanceConnects Claude to the HackerOne Hacker API, enabling program listing, scope retrieval, report management, and balance checks via natural language.6-