API & endpoints

Calling the API with curl

The Actuant MCP endpoint is JSON-RPC 2.0 over HTTP POST. Initialize, list tools, call a tool — with the exact headers and payloads, and the header everyone forgets.

Last updated 2026-08-08

You do not need an MCP client to use Actuant programmatically. The endpoint is a plain POST that takes a JSON-RPC 2.0 body and returns one back.

The headers

HeaderValueRequired
AuthorizationBearer act_… or Bearer mca_…Yes
Content-Typeapplication/jsonYes
Acceptapplication/json, text/event-streamYes
Mcp-Session-IdEchoed from a previous responseOnly to continue a session

The Accept header is not optional

Streamable HTTP requires BOTH media types in Accept. Send only application/json and the transport rejects the request before your tool call is even parsed — which reads like an auth failure and sends you looking in the wrong place.

1. List the tools

The quickest way to confirm a credential works. No side effects, nothing metered.

bash
curl -sX POST https://www.actuant.dev/api/mcp \
  -H "Authorization: Bearer $ACTUANT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Returns every tool with its JSON Schema. Plan-gated tools are listed too — they are advertised to everyone and rejected at call time, so an agent can see what an upgrade unlocks.

2. Run an audit

Tool calls go through tools/call with the tool name and its arguments:

bash
curl -sX POST https://www.actuant.dev/api/mcp \
  -H "Authorization: Bearer $ACTUANT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "scan_app",
      "arguments": { "url": "https://myapp.lovable.app" }
    }
  }'

scan_app runs to completion and returns the finished report — score, every check with its status and evidence, and prioritised advice. It takes roughly 20 seconds, so set a generous client timeout.

3. Whole-site audits are asynchronous

audit_app cannot return the report inline: a real-browser crawl runs for minutes. It returns an auditId immediately, plus a browserViewer link that shows the live browser mid-crawl.

bash
# Start it
curl -sX POST https://www.actuant.dev/api/mcp \
  -H "Authorization: Bearer $ACTUANT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":
       {"name":"audit_app","arguments":{"url":"https://myapp.lovable.app"}}}'

# Then poll with the returned auditId
curl -sX POST https://www.actuant.dev/api/mcp \
  -H "Authorization: Bearer $ACTUANT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":
       {"name":"get_audit","arguments":{"auditId":"<id>"}}}'

The live link is perishable

The browserViewer link dies when the run ends. If you are relaying it to a human, do it immediately — a link surfaced after the crawl finishes was never usable.

Reading the response

Tool results come back as MCP content blocks. The payload you want is JSON encoded inside the first block's text field, so most callers do a double parse:

bash
res=$(curl -sX POST https://www.actuant.dev/api/mcp \
  -H "Authorization: Bearer $ACTUANT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":
       {"name":"get_account","arguments":{}}}')

echo "$res" | jq -r '.result.content[0].text' | jq .