Skip to content

Local HTTP API

The MCP server runs on this API, and you can call it directly too — from Python, Node, n8n, Postman or anything that speaks HTTP.

After Automation → Enable API / MCP access, Accovod starts a server on 127.0.0.1 and writes its details to a file:

~/Library/Application Support/Accovod/control.json
{
"app": "Accovod",
"platform": "macos",
"apiVersion": "1.0",
"port": 25252,
"token": "8f3c…",
"baseUrl": "http://127.0.0.1:25252"
}
  • The port is 25252 when it’s free. Reading baseUrl from the file is more reliable than hard-coding the address.
  • The file is deleted when Accovod quits. No file means the app isn’t running or the API is off.
  • Rotate the token with Automation → Regenerate token.

There’s one endpoint — POST /v1/rpc — with the method and parameters in the body:

Terminal window
CONTROL=~/Library/Application\ Support/Accovod/control.json
BASE=$(jq -r .baseUrl "$CONTROL")
TOKEN=$(jq -r .token "$CONTROL")
curl -s "$BASE/v1/rpc" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"method":"profiles.list","params":{}}'

GET /v1/health answers without a token — use it to check whether the app is running.

Every response uses the same envelope:

{ "ok": true, "result": { } }
{ "ok": false, "error": { "code": "PROFILE_NOT_FOUND", "message": "", "hint": "" } }

hint says what to fix in the request. An optional id in the request is echoed back.

  • profileId is the only reliable profile identifier. Take it from profiles.list and pass it to every page.* method. index changes when the list is reordered.
  • Start with app.status. It reports the profile mode (all or activeOnly), the active group and whether the agent is stopped.
  • Elements come from page.snapshot. It returns interactive elements with a ready-made target object. Pass it to page.click and page.fill as is. Take a new snapshot after navigating.
  • Retries are safe. profiles.create, profiles.createMany and profiles.importMany require an idempotencyKey: a retry with the same key returns what was already created instead of a duplicate.
  • Deletion needs confirm: true. Without it, profiles.delete and sessions.delete delete nothing and report what would have been deleted.
  • Long work can run through operations.start, with the result fetched by operations.get — useful when your client times out long calls.
Code HTTP Meaning
UNAUTHORIZED 401 Missing or wrong token.
BROWSER_ORIGIN_BLOCKED 403 The request came from a page in a browser — those are refused.
AGENT_STOPPED 409 The person pressed Stop. Everything except app.status is refused until Resume.
PROFILE_NOT_FOUND 404 No such profileId in the open group.
PROFILE_NOT_LIVE 409 The profile has no open tab — in activeOnly mode call profiles.open first.
REVISION_MISMATCH 409 The profile changed since you read it. Nothing was written — read it again and retry.
PROFILE_LIMIT_REACHED 409 The cloud group has hit the plan’s limit.
TARGET_NOT_FOUND / AMBIGUOUS_TARGET 404 / 409 No element, or several, matched — nothing was clicked.
ELEMENT_OCCLUDED 409 A banner or dialog covers the element — the message names it.
CONFIRMATION_REQUIRED 400 Deletion without confirm: true.

Every method and its main parameters are in the tools reference. MCP tool and API method names map simply: profiles_listprofiles.list, page_wait_forpage.waitFor.