HTTP API

Everything an MCP client can do in your workspace can also be done with plain HTTP calls and an API key. The same tools, the same permissions, the same audit trail; no MCP client to configure. This is the path for a script, a CI job, or any tool that does not speak MCP.

The tool catalogue is the contract. A tool you see in GET /api/tools behaves identically over MCP and over HTTP, and the catalogue is what XPT Tracker keeps stable.

The key

Create a key under Settings → MCP Server. It is shown once, does not expire, and acts as you, with exactly your permissions. Create one per machine or pipeline so that a single one can be revoked without disturbing the others; revoke from Settings → API tokens and connected apps, which takes effect immediately.

Only a key created this way (it starts with xpt_) works on the HTTP API. The tokens an MCP client obtains through the browser (xpto_), and the tokens issued to agents, are confined to the MCP endpoint and are refused here.

The key travels as a Bearer token:

Authorization: Bearer xpt_...

The endpoints

Both live on the MCP host, https://mcp.xpt.ai, and both need the key.

Call What it does
GET /api/tools Lists the tools available to you in this workspace, each with its name, description and JSON Schema for the arguments.
POST /api/tools/{name}/execute Runs one tool. The body is {"arguments": { ... }}, matching the tool's schema.

The list is specific to your workspace: it includes your workspace's AI Workflows as wf_* tools, and the enums in the schemas (statuses, priorities, labels) are the ones your teams actually use.

1. List the tools

curl -s https://mcp.xpt.ai/api/tools \
  -H "Authorization: Bearer $XPT_KEY"
{
  "tools": [
    {
      "name": "task_get",
      "description": "Get a task by key (e.g. 'BE-14'). Returns full details.",
      "inputSchema": {
        "type": "object",
        "properties": { "key": { "type": "string", "description": "Task key (e.g. 'BE-14')" } },
        "required": ["key"]
      }
    }
  ]
}

2. Check the key: who am I

The simplest call, and the one to try first. workspace_me takes no arguments, so the body is an empty arguments object; it answers with the person the key acts as.

curl -s https://mcp.xpt.ai/api/tools/workspace_me/execute \
  -H "Authorization: Bearer $XPT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"arguments": {}}'
{
  "status": "ok",
  "data": {
    "id": "019c0000-0000-7000-8000-000000000001",
    "name": "Jane Doe",
    "email": "jane.doe@example.com"
  },
  "meta": { "traceId": "8ac478ef" }
}

3. Read a task

curl -s https://mcp.xpt.ai/api/tools/task_get/execute \
  -H "Authorization: Bearer $XPT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"arguments": {"key": "ENG-51"}}'
{
  "status": "ok",
  "data": {
    "id": "019c0000-0000-7000-8000-000000000051",
    "key": "ENG-51",
    "team": "ENG",
    "title": "Add CSV export to reports",
    "status": "In Progress",
    "statusKey": "in_progress",
    "priority": 2,
    "estimatePoints": 3,
    "assigneeName": "Jane Doe",
    "labels": ["Feature"],
    "blockedBy": [],
    "blocks": ["ENG-52"],
    "createdAt": "2026-10-12T09:14:03Z",
    "updatedAt": "2026-10-13T11:02:41Z"
  },
  "meta": { "traceId": "a1b2c3d4" }
}

4. Write

Tools that change something take a changes object and touch only the fields it names, so a field you leave out is left alone:

curl -s https://mcp.xpt.ai/api/tools/task_update/execute \
  -H "Authorization: Bearer $XPT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"arguments": {"key": "ENG-51", "changes": {"status": "review"}}}'

The change appears in the task's activity attributed to you, exactly as if you had made it in the app.

The answer

Every tool answers with the same envelope.

On success, HTTP 200:

{ "status": "ok", "data": { ... }, "meta": { "traceId": "a1b2c3d4" } }

When the tool cannot do what was asked, the status line says so and the body names the reason:

{
  "status": "error",
  "meta": { "traceId": "e5f6a7b8" },
  "error": { "code": "validation_failed", "message": "'key' is required" }
}
HTTP status error.code Meaning
400 validation_failed An argument is missing or malformed.
404 not_found The object does not exist, or you cannot see it. The two are deliberately indistinguishable.
409 revision_conflict The object changed since you read it; read it again and retry.
422 any other code The request was well-formed, but the tool could not act on it in the current state.

meta.traceId identifies the call in XPT Tracker's logs. Quote it when you write to support@xpt.ai about a call that did not behave as expected.

Two answers come from the transport rather than from a tool:

  • 401 with a WWW-Authenticate header: no key, a revoked key, or a key whose owner is no longer a member of the workspace.
  • 404 with {"error": "Tool not found: …"}: the name is not in your catalogue.

What the HTTP API is not

It is a direct line to the tool catalogue, not a resource-style REST API: there are no /tasks/{id} URLs, no pagination headers, and no public GraphQL schema. It also has none of what the MCP connection adds on top, such as a session, notifications when the tool list changes, or a browser-based sign-in. For an interactive assistant, connect it through MCP (see Connect any MCP client); for everything that runs without you, this page is enough.

Every call, over HTTP or MCP, is recorded in Insights → Tool usage, and your key shows under Settings → API tokens and connected apps with the time it was last used.