MCP

Connect an MCP client to Assistant Cloud project reads.

Assistant Cloud exposes a stateless Model Context Protocol endpoint for agents that need to inspect a project's runs, usage, threads, scores and topics. It uses the backend host and an API key, and the API key strategy still requires Aui-Workspace-Id even though the tools scope their reads to the project.

The MCP endpoint

POST /v1/mcp
Request itemRequiredRules
AuthorizationyesA bearer API key.
Aui-Workspace-IdyesRequired by the API key strategy.
AcceptnoWhen sent, it must include application/json, text/event-stream or */*, or the transport answers 406. A missing header counts as */*.
HTTP methodyesOnly POST is accepted.
TransportyesStateless streamable HTTP with JSON responses.

The server identifies itself as { name: "assistant-cloud", version: "1.0.0" }. It creates no MCP session because the transport is configured without a session id generator. Every exposed tool has annotations: { readOnlyHint: true }.

Request
POST /v1/mcp
Authorization: Bearer sk_aui_proj_…
Aui-Workspace-Id: usr_000000000000000000000000
Content-Type: application/json
Accept: application/json, text/event-stream

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": { "name": "list_runs", "arguments": { "limit": 50 } }
}
Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"runs\":[],\"next_cursor\":null}"
      }
    ]
  }
}

The body is a JSON-RPC 2.0 message as the MCP streamable HTTP transport defines it; initialize and tools/list use the same envelope, and the tool sections below show only the result each tool returns.

The successful tool result is { content: [{ type: "text", text: JSON.stringify(result) }] }. A tool failure adds isError: true and serializes { error: message } as the text result. Only the messages in this table pass through unchanged. Every other tool failure becomes Request failed.

Error messageMeaning
Invalid cursorA thread or score cursor is not valid.
Invalid run cursorA run cursor is not valid.
Invalid usage day rangeA usage date is not a real UTC day.
Run not foundThe requested run is not visible in the project.
Thread not foundThe requested thread is not visible in the project.
Usage day range must span at most 366 daysThe usage range is negative or spans more than 366 days.
StatusBody or headersWhen
200A JSON MCP responseThe transport returns a tool result. Tool failures use the isError result shape.
401An authentication error object.The authorization header is missing, malformed or expired.
403{ "error": "This endpoint requires an API key" }The request does not use an API key.
405Empty body with Allow: POSTThe request uses a method other than POST.
406A JSON-RPC error, Not Acceptable: Client must accept application/json or text/event-streamAn Accept header was sent without application/json, text/event-stream or */*.
500Empty bodyThe transport returns no response.

The endpoint and all eight tools are read only. They do not create sessions or write project data, so repeating a successful read is idempotent. A client should send the same backend URL, API key and workspace header on every request.

list_runs

List runs in the authenticated project. System runs are excluded, as they are from the project run read.

InputTypeRequiredDefaultRules
statusenumnoOne of the API run status values.
outcome_typeenumnoOne of the API run outcome values.
model_idstringno1 to 255 characters.
providerstringno1 to 255 characters.
created_bystringno1 to 255 characters.
thread_idstringno1 to 48 characters.
environmentstringno1 to 64 characters.
releasestringno1 to 255 characters.
tagstringno1 to 64 characters.
fromISO 8601 datetimenoConverted to a date value.
toISO 8601 datetimenoConverted to a date value.
limitintegerno50Coerced to an integer from 1 to 100.
cursorstringno1 to 512 characters.
Arguments
{ "limit": 50 }
Result
{ "runs": [], "next_cursor": null }

Results are ordered by created_at DESC, id DESC. The cursor is base64url encoded JSON containing created_at as an ISO value and id. Pass next_cursor unchanged to the next call. An invalid cursor produces the Invalid run cursor tool error.

get_run

Get one run and its spans from the authenticated project.

InputTypeRequiredRules
run_idstringyes1 to 48 characters.
Arguments
{ "run_id": "run_000000000000000000000000" }
Result
{ "id": "run_000000000000000000000000", "spans": [] }

The result is the project run object with spans. Spans are ordered by start_ms ASC, span_index ASC. This tool does not use a cursor. A missing run produces the Run not found tool error.

usage_daily

Get daily usage for the authenticated project.

InputTypeRequiredDefaultRules
fromYYYY-MM-DDno30 day windowMust be a real UTC calendar day. Defaults to 29 days before to.
toYYYY-MM-DDnoToday in UTCMust be a real UTC calendar day.
group_byenumnoThe only value is model.
Arguments
{ "from": "2026-09-01", "to": "2026-09-17", "group_by": "model" }
Result
{
  "days": [
    {
      "day": "2026-09-17",
      "provider": null,
      "model_id": null,
      "runs": 0,
      "errors": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "total_tokens": 0,
      "cost_usd": 0
    }
  ]
}

Without group_by, every day in the range is returned with zero filled values. With group_by=model, rows are grouped by day, provider and model as stored, with no zero fill, and provider or model_id can be null. runs counts kind = run rows. errors counts kind = run rows with status = error. Token and cost sums include kind = sampling rows. This tool has no cursor. An invalid date produces Invalid usage day range, and an invalid span produces Usage day range must span at most 366 days.

usage_period

Get the current usage period for the authenticated project.

InputTypeRequiredRules
No fieldsobjectyesThe input object is empty.
Arguments
{}
Result
{
  "plan": "free",
  "period_start": "2026-09-01T00:00:00.000Z",
  "period_end": "2026-10-01T00:00:00.000Z",
  "active_users": 0,
  "included": 200,
  "cap": 200,
  "capped_at": null,
  "thread_titles": {
    "used": 0,
    "completed": 0,
    "included": 500,
    "cap": 500,
    "capped_at": null
  }
}

The result is the full usage period object. period_start and period_end are the UTC calendar month boundaries. active_users is the greater of the stored period count and the sum of period users by day. included and cap come from the limits resolved for the project. This tool has no cursor. A missing project fails with a message outside the passthrough table, so the tool answers Request failed.

list_threads

List threads in the authenticated project.

InputTypeRequiredDefaultRules
created_bystringno1 to 255 characters.
fromISO 8601 datetimenoConverted to a date value.
toISO 8601 datetimenoConverted to a date value.
limitintegerno50Coerced to an integer from 1 to 100.
cursorstringno1 to 512 characters.
Arguments
{ "limit": 50 }
Result
{ "threads": [], "next_cursor": null }

The project scope includes every workspace, including archived threads. Results are ordered by created_at DESC, id DESC. The cursor is base64url encoded JSON containing created_at as an ISO value and id. Pass next_cursor unchanged to the next call. An invalid cursor produces Invalid cursor.

get_thread

Get one thread and its messages from the authenticated project.

InputTypeRequiredRules
thread_idstringyes1 to 48 characters.
Arguments
{ "thread_id": "thread_0qzof3jPoDwr7K3agyJN3D4U" }
Result
{ "thread": {}, "messages": [] }

The result includes the thread and its messages. Messages are mapped to ThreadMessageDTO and ordered by height ASC, created_at ASC, id ASC. This tool has no cursor. A missing thread produces Thread not found.

list_scores

List scores in the authenticated project.

InputTypeRequiredDefaultRules
thread_idstringno1 to 48 characters.
run_idstringno1 to 48 characters.
namestringno1 to 64 characters.
sourceenumnoend_user, human, evaluator or api.
limitintegerno50Coerced to an integer from 1 to 100.
cursorstringno1 to 512 characters.
Arguments
{ "name": "quality", "limit": 50 }
Result
{ "scores": [], "next_cursor": null }

Scores are ordered by created_at DESC, id DESC. Each score contains id, thread_id, message_id, run_id, name, data_type, value, string_value, source, author_id, comment, created_at and updated_at; value is a number or null. The cursor is base64url encoded JSON containing created_at and id. Pass next_cursor unchanged. An invalid cursor produces Invalid cursor.

list_topics

List topics and thread counts in the authenticated project.

InputTypeRequiredRules
No fieldsobjectyesThe input object is empty.
Arguments
{}
Result
{ "topics": [] }

Each topic has id, name, created_at, updated_at and thread_count. Topics are ordered by thread_count DESC, name ASC. This tool has no cursor.

Configure a client

Use the MCP URL and both required headers in your client. The Claude Code command is:

Claude Code
claude mcp add --transport http assistant-cloud https://backend.assistant-api.com/v1/mcp --header "Authorization: Bearer sk_aui_proj_…" --header "Aui-Workspace-Id: usr_000000000000000000000000"

Clients configured through an mcpServers file, such as Cursor, use the same values:

mcp.json
{
  "mcpServers": {
    "assistant-cloud": {
      "url": "https://backend.assistant-api.com/v1/mcp",
      "headers": {
        "Authorization": "Bearer sk_aui_proj_…",
        "Aui-Workspace-Id": "usr_000000000000000000000000"
      }
    }
  }
}

Create a key for this MCP client, scope its use to this tool, give it an expiry and revoke it when the client is no longer needed. The key grants read access to the whole project, so do not reuse it for unrelated access.