ModernPentestModernPentest

Tools

Every tool the MCP server exposes, the permission it needs, and whether it writes

The server exposes 30 tools across seven areas. Your client always shows the live list after it connects; if this page and your client ever disagree, believe your client.

The server also exposes the enroll_application prompt and sends enrollment instructions when a client connects. See Enroll from your repository.

Three columns matter:

  • Scope: the permission the tool needs. A call without it fails with an error naming the missing permission; retrying will not help, you have to reconnect and grant it.
  • Writes: whether the tool changes anything.
  • Confirm: whether the tool is marked as needing confirmation. Most clients ask you to approve these before calling. It is set for anything that spends quota, changes customer-visible security state, or produces an artifact that outlives the conversation.

Organizations

ToolScopeWritesConfirmWhat it does
list_organizationsmcp:read--The organizations this credential can act in, and the identifier to pass as organization
get_organization_usagemcp:read--Plan tier, usage against every limit, and whether an operator has put the organization on hold
create_organizationmcp:organizations:writeyesyesCreates an organization owned by the calling account, active from the start, and returns the URL a human opens to choose a plan

create_organization never charges anything and never collects payment details. It hands back a link; a person completes checkout in the browser. An organization-scoped API key cannot call it at all; see Agents as customers.

Applications

ToolScopeWritesConfirmWhat it does
list_applicationsmcp:read--Applications with vulnerability counts by severity and scan schedule
get_applicationmcp:read--One application, its web and REST targets, and a non-secret test-user configuration summary
register_applicationmcp:applications:writeyes-Registers an application and its targets, starts proof of domain control for every target host, and returns the DNS record and the well-known file to publish. Uses an application slot from your plan
configure_applicationmcp:applications:writeyesyesAttaches an inline OpenAPI JSON/YAML specification (up to 512 KB) to an existing REST surface, or enables specification discovery during scanning
update_applicationmcp:applications:writeyes-Changes name, environment or criticality, and sets, replaces or removes the web and REST API targets. A new or changed host has to be proven before the application can be scanned again
verify_application_domainmcp:applications:writeyes-Checks every pending proof of the application's hosts, both methods, and reports which method proved each host. Issues the record and file for a host that has none yet
get_domain_verification_statusmcp:read--Per host: proven or not, by which method, and the exact record and file still to publish. For one application or the whole organization

Credentials

Write-only, under their own scope. Nothing on the MCP ever returns a password, an authenticator seed or a code; these tools confirm the account and the kind of code source, never the value. They exist so an agent can keep a target scannable when its test account rotates, without a person in the dashboard. Because a secret sent as a tool argument passes through the client's context and usually its local transcript, mcp:credentials:write is separate from mcp:applications:write: grant it only to clients whose logs you trust.

ToolScopeWritesConfirmWhat it does
set_test_usersmcp:credentials:writeyesyesReplaces the test-user strategy and the full account list (role, email or username, password). Accounts left out lose their stored credentials
set_verification_code_sourcemcp:credentials:writeyesyesAttaches a TOTP seed or a fixed code to one configured account, or removes them. Fixed codes on production applications require an explicit acknowledgement

verify_application_domain is not read-only even though it looks like a lookup: it performs DNS queries and HTTPS fetches against your hosts, spends a bounded attempt budget (25 per proof), and can flip a host to proven. It also issues the record and file for a host that has no proof started yet, which is how a surface added after registration gets one, and re-issues a proof that spent every attempt with a new token. get_domain_verification_status answers the same question without spending an attempt and reports pending automatic starts, their last refusal and any creation failure. When pendingFirstPentest is set, checking proof can release that scan: finish authentication and API configuration, then approve the targets and entitlement before checking.

No application can be scanned until you prove you own its domains. This applies to every application, whether it was created over the MCP server, the REST API or the dashboard, and every way of starting a scan refuses until every target host is proven. There is no operator approval that replaces the proof. Two methods, either of which proves a host:

  • a DNS TXT record named _modernpentest-verify.<host> with the value modernpentest-verify=<token>, one record per host, which proves that one host;
  • an HTTPS file at https://<host>/.well-known/modernpentest-verify.txt containing the line modernpentest-verify=<token>, served with status 200 and no redirect, which proves that one host.

A proof never expires, so a host the organization has already proven is proven for every application that targets it. Hosts on shared hosting (run.app, vercel.app, netlify.app and the like) can only use the file, because only the provider controls that DNS zone; the tools say so per host. Full details in Prove you own the domain.

Attack surface

ToolScopeWritesConfirmWhat it does
get_asset_graphmcp:read--The discovered attack surface: asset nodes, their relationships, per-node open-vulnerability counts and test coverage
expand_asset_clustermcp:read--Lists the individual nodes folded into one cluster card returned by get_asset_graph

get_asset_graph returns a partial view by design: low-interest nodes are folded into clusters and large graphs are truncated, and the result says so. An assistant should check that before concluding something is absent from your attack surface, and use expand_asset_cluster rather than assuming a cluster is uninteresting.

Pentests

ToolScopeWritesConfirmWhat it does
list_pentestsmcp:read--Scans newest first, with status, timing, severity counts and cost
get_pentestmcp:read--One scan in full, including failure details when it did not finish cleanly
get_pentest_progressmcp:read--Live phase, per-agent execution counts and cost so far. Poll this, not list_pentests
start_pentestmcp:pentests:writeyesyesStarts a real scan against your live systems and spends the plan's quota, a pentest credit or the free preview, in that order. Refused until every target host is proven
cancel_pentestmcp:pentests:writeyesyesMarks a pending or running scan cancelled. See the warning below; it is not a kill switch

Cancelling a scan does not stop it costing you. It marks the scan cancelled, which discards whatever it had found: nothing is consolidated into vulnerabilities, triaged, or written into a report. But work already running keeps running to completion, so charges continue to accrue for some minutes after the call returns, and a scan cancelled while running keeps the credit or free preview it claimed; one cancelled while still pending releases it. It cannot be undone.

start_pentest sends genuine attack traffic (authentication attempts, injection payloads, active probing) at the surfaces you registered, and spends a scan from your quota. It is deliberately marked as requiring confirmation. An assistant should never call it to "check" something it could have answered from existing results. If you created the application in the dashboard and asked for the first pentest to start as soon as ownership is verified, the platform starts it on its own; the tools report that as pendingFirstPentest so an assistant does not start a second one.

Vulnerabilities

ToolScopeWritesConfirmWhat it does
list_vulnerabilitiesmcp:read--Summary rows, filterable by application, severity and status
get_vulnerabilitymcp:read--One finding in full: impact, technical context, remediation guidance
get_vulnerability_activitymcp:read--Merged timeline of status, assignment, due-date and note changes
transition_vulnerabilitymcp:vulnerabilities:writeyesyesMoves a finding through its lifecycle

Exploit detail

get_vulnerability accepts includeExploitDetail, which defaults to false. While it is false, everything weaponisable is withheld: proof-of-concept and exploit code, test payloads, attack scenarios, patch-verification code, the resources a finding touched, and raw HTTP request/response logs. The response lists which of them were withheld, so the assistant knows they exist and can ask you before requesting them. The call is recorded in your audit log either way.

The default is false because the common question ("summarise my open criticals") has no need of exploit code, and an unattended agent should not pull a working exploit into a transcript by accident.

Status transitions

transition_vulnerability enforces the same lifecycle the dashboard does:

open           → in_remediation | accepted_risk | false_positive
in_remediation → remediated | open | accepted_risk | false_positive
remediated     → fixed | open
any            → open

Moving to accepted_risk or false_positive requires a reason, which is recorded on the finding for the humans who will later rely on it. Moving to remediated schedules an automatic remediation-verification run against your target, which is why the tool asks for confirmation despite deleting nothing.

Reports

ToolScopeWritesConfirmWhat it does
list_reportsmcp:read--Published and failed reports. A report still generating is deliberately not listed
get_reportmcp:read--One report with severity totals, risk score and the written summary
generate_reportmcp:reports:writeyesyesRequests the report for a completed pentest. Asynchronous; publishing emails you
export_reportmcp:reports:writeyesyesRenders and returns a PDF download URL

export_report puts a PDF of your findings behind a permanent, unauthenticated link: it does not expire and cannot be revoked. Anyone who receives it can read the whole report. The same is true of an attestation's PDF link, including a private one.

Attestations

ToolScopeWritesConfirmWhat it does
list_attestationsmcp:read--Letters with visibility, redaction profile, expiry and view counts. Share ids are excluded
get_attestationmcp:read--One letter, including its share link and content hash
generate_attestationmcp:attestations:writeyesyesCreates a signed Letter of Attestation for a completed pentest

generate_attestation takes a redactionProfile (minimal, standard, detailed) and a visibility (private, unlisted, public). Visibility defaults to private. It requires a paid plan and spends one of the organization's attestations for the month; a call that exceeds either comes back as a plan-limit error.

Under the minimal profile the published severity counts are emitted as zeros by construction. They mean "suppressed", not "no findings"; do not read a minimal letter as a clean bill of health.

unlisted and public are both world-readable to anyone holding the share link, as soon as the PDF renders; there is no separate publish step. Only choose them when you actually want a shareable letter. Endpoints, payloads and evidence are never published at any redaction profile.


The organization argument

Every tool accepts an optional organization, a slug or organization id that chooses which of your organizations the call acts in. You only need it if you belong to more than one; if you do and you omit it, the call fails with an error naming them rather than guessing.

It selects among the organizations you already belong to. It cannot grant access to one you do not, and an organization-scoped API key rejects it outright if it names a different organization.

What tools never return

  • Credentials of any kind. Test-user passwords, API keys, bearer tokens, OAuth client secrets, deployment-protection bypass secrets, saved browser sessions and TOTP seeds are unavailable at every permission level.
  • Session material captured during a scan, by default but not unconditionally. Raw request and response logs from a finding can contain Authorization headers, cookies and session tokens our agents captured from your live system. They are withheld unless a call passes includeExploitDetail: true. They are gated, not scrubbed: redaction removes known fields, and it cannot reliably find a token embedded in the body of a raw HTTP log. Treat exploit detail as sensitive whenever you ask for it.
  • Anything outside your organization. Every call is re-authorized against your actual role, by the same permission checks the dashboard uses.

Untrusted text

Vulnerability titles, descriptions, application names and endpoint paths are partly derived from content our agents read on your target, which means an attacker who can influence a page can influence that text. Tools wrap it in an <untrusted> marker and the server tells your assistant, on connect, to treat those spans as data and never as instructions.

This makes injection visible rather than impossible. If an assistant ever reports that a finding "instructed" it to do something, that is the mechanism working; do not act on it.

Last updated: September 7, 2026

On this page