Saltar a contenido

MCP Server

Ostorlab exposes an MCP server, letting AI assistants and agent frameworks work with your scans, vulnerabilities, tickets and assets directly — no custom GraphQL client required.

Where the GraphQL API gives you the full platform surface to build against, the MCP server gives an AI client a curated set of typed tools it can discover and call on its own. Ask your assistant "what did the last scan of my app find?" and it will pick the right tools, chain them, and answer.

Endpoint

https://api.ostorlab.co/apis/mcp/{api_key}/

The transport is streamable HTTP. The API key is part of the URL path.

Warning

The trailing slash is required. Without it the server answers with a 307 redirect. Clients that follow redirects will still work but pay an extra round trip on every request; clients that do not follow redirects on POST will fail.

Warning

The key in the URL is a credential. URLs are commonly recorded in proxy logs, browser history and shell history, and MCP client configuration files are usually stored in plain text. Treat the endpoint URL exactly as you would the key itself. To retire a key, revoke it — setting an expiry date does not stop the key from working on this path.

Getting an API key

Create one from the web application under Integrations/API → API Keys (https://report.ostorlab.co/integrations/api). The key's role determines what the MCP tools can do — see Permissions.

Connecting a client

Most clients take a server name, a transport and a URL. The transport is streamable HTTP, so where a client asks for a type, use http.

Claude Code

claude mcp add --transport http ostorlab https://api.ostorlab.co/apis/mcp/YOUR_API_KEY/

Claude Desktop, Cursor, VS Code, Windsurf, Zed

These read a JSON configuration file. The location differs per client and per platform — check your client's documentation for where it lives — but the entry has the same shape:

{
  "mcpServers": {
    "ostorlab": {
      "type": "http",
      "url": "https://api.ostorlab.co/apis/mcp/YOUR_API_KEY/"
    }
  }
}

Some clients name the section servers rather than mcpServers, and some use serverUrl in place of url. If yours rejects the block above, check its documentation for the key names — the transport and the URL are the parts that matter.

Confirming it works

Ask the client to run a read tool, for example listing your scans. A bad key returns Invalid API Key. Asking it to list its tools is not a useful check: the tool list is returned for any key, valid or not.

Permissions

Every tool checks the API key's permissions before doing anything. Keys carry a role, and roles map to actions:

Tool type Required permission
Reading scans, vulnerabilities, tickets read
Creating or modifying tickets, comments, checklists write
Triaging vulnerabilities write
Listing attack-surface assets attack_surface_read

A key without the required permission gets a clear error rather than a partial result.

attack_surface_read is held by every role, so any key can call list_assets. It is worth listing because the reverse is not true: an attack_surface_auditor key has neither read nor write, so list_assets is the only tool it can use.

If your organisation has object-level access enabled, tools respect it, following the same rules as the GraphQL API-key path:

  • Scans and tickets — a non-admin key only sees the individual scans and tickets it has been granted.
  • Assets — the grant is on the owner, not the asset. A key sees every asset belonging to the owners it has been granted.

Available tools

Scans

Tool Description
list_scans List scans, filtered by status, asset_id, scan_profile, risk_rating, created_after, archived.
get_scan One scan's details.
get_scan_status A scan's progress, its recent status history, and any errors it reported.

get_scan and get_scan_status do not return archived scans, even though list_scans can list them. Calling either on an archived scan returns Scan not found.

Vulnerabilities

Tool Description
list_vulnerabilities Findings, filtered by scan_id, risk_rating, kb_detail_id, or the ticket they belong to.
get_vulnerability One finding: technical detail, exploitation detail, CVSS vectors and location metadata.
update_vulnerability Triage: set a custom risk rating or CVSS vector, or mark a finding false positive or an accepted exception.

Two things to know about update_vulnerability:

  • Marking a finding false positive or exception acts on the tickets linked to that finding. A finding with no ticket is unchanged, and the call still reports success.
  • Its all_vulnerabilities parameter applies the change to every finding in the same scan sharing the same knowledge-base detail, and recomputes the scan's overall risk rating. The blast radius is much larger than a single finding.

Every finding carries a dna field — a fingerprint derived from the finding's title, technical detail and location. The same issue found again in a later scan keeps the same dna as long as those three are unchanged, which makes it useful for deduplicating when you import findings elsewhere. It is not guaranteed stable when the technical detail varies between runs.

Tickets

Tool Description
list_tickets Tickets, filtered by status, priority, assigned_email, agent, tag, title, created_since, modified_since. Sortable, with a limit.
get_ticket One ticket, by id or by key (for example os-1234).
create_ticket Create a ticket, optionally with tags, an assignee, a ticket agent, a due date.
update_ticket Change any of the same fields.
delete_ticket Delete a ticket. Not reversible.

Comments and checklists

Tool Description
list_comments, create_comment, update_comment, delete_comment Comment thread on a ticket.
list_checklists, create_checklist, update_checklist, delete_checklist Remediation checklists attached to a ticket.
create_checklist_item, update_checklist_item, delete_checklist_item Individual checklist items.

Note

Adding a comment to a ticket that has a ticket agent assigned will start an agent run.

Comments created through MCP have no author attached, because the server authenticates an API key rather than a user. They render without an author in the web application.

Assets

Tool Description
list_assets Attack-surface assets, filtered by asset_type, owner_id, search, tags.

Result limits

Every list tool caps how much it returns, and the cap is silent — there is no "there is more" marker and no cursor to page with.

Tool Default Maximum
list_scans, list_vulnerabilities, list_assets 200 200
list_tickets 50 200
get_scan_status (status history) 50 50
list_comments, list_checklists no limit no limit

Asking for more than the maximum is clamped down to it rather than rejected. So an organisation with 500 scans gets 200 back with nothing to indicate the other 300 exist. Narrow with filters when the count matters — do not ask a model to count from a list result.

Deleting

delete_ticket, delete_comment, delete_checklist and delete_checklist_item remove data permanently. They are not currently flagged to clients as destructive, so your client will not prompt you to confirm before running them. Treat any prompt that could lead to a delete with that in mind.

Errors

A tool that fails returns a normal successful response whose body carries an error field:

{"error": "Invalid API Key."}

The JSON-RPC isError flag stays false. If your client branches on isError, it will read authentication and permission failures as successes — check for the error field instead.

Examples

Prompts that work well once the server is connected:

  • "List the scans that finished in the last week with a high risk rating."
  • "Show me the critical findings from scan 12345 and open a ticket for each one."
  • "What's the technical detail of vulnerability 987, and has anyone commented on its ticket?"
  • "Mark vulnerability 654 as a false positive."
  • "Which open tickets are assigned to rubberduck?"

Troubleshooting

HTTP 404 on connect The URL is missing the key segment, or the trailing slash. It must be /apis/mcp/YOUR_API_KEY/.

Invalid API Key. The key does not resolve. Check it was copied whole, and that it has not been revoked.

API Key does not have write permission. The tool needs a higher role than the key has. Issue a key with the required role.

Scan not found. for a scan you can see in the web application Three possible causes: the scan is archived (get_scan and get_scan_status refuse archived scans), the scan belongs to another organisation, or your organisation uses object-level access and this key has not been granted that scan. An inaccessible scan is deliberately reported the same way as one that does not exist.