opsdocsConsole

Ops platform / HTTP API

Assistant and tools

The tools the assistant and an MCP client call, each run with the permissions of whoever calls it.

Updated 13 Oct 2026View as Markdown

The tools the assistant and an MCP client call, each run with the permissions of whoever calls it.

GET /api/v1/assistant/status

Whether the assistant is set up, and when it is not, the sentence that says why.

StatusMeansBody
200DoneAssistantStatusResponse
401Bad token

GET /api/v1/assistant/threads

This operator's threads, newest first, with their messages and proposals.

StatusMeansBody
200Donearray of ThreadResponse
401Bad token

POST /api/v1/assistant/threads

Open a thread. The project and the environment are the panel's own scope, and they are what fills in a tool argument the model leaves out, so a thread opened on staging never silently acts on production.

Body: OpenThreadBody

StatusMeansBody
200DoneThreadResponse
401Bad token
404No such project

GET /api/v1/assistant/threads/{id}

One conversation with its messages and proposals.

ParameterInTypeAbout
idpathstring (uuid)
StatusMeansBody
200DoneThreadResponse
401Bad token
404No such thread

DELETE /api/v1/assistant/threads/{id}

Delete a thread, and forget every secret value parked for it.

ParameterInTypeAbout
idpathstring (uuid)
StatusMeansBody
204Deleted
401Bad token
404No such thread

POST /api/v1/assistant/threads/{id}/messages

Send a message and get the answer, with any changes the assistant proposes. Refused while a proposal still waits for a decision.

ParameterInTypeAbout
idpathstring (uuid)

Body: PostMessageBody

StatusMeansBody
200DoneThreadResponse
401Bad token
404No such thread
409A proposal is still waiting for a decision
422Empty or oversized text
429Too many assistant messages from this operator
503No model is configured, or the provider did not answer

POST /api/v1/assistant/threads/{id}/proposals/accept-all

Accept every waiting proposal of the newest answer, in order, stopping at the first one that fails. The rest stay waiting.

ParameterInTypeAbout
idpathstring (uuid)
StatusMeansBody
200DoneThreadResponse
401Bad token
404No such thread

POST /api/v1/assistant/threads/{id}/proposals/{proposal_id}/accept

Accept one proposal, which carries out the change with your permissions.

ParameterInTypeAbout
idpathstring (uuid)
proposal_idpathstring (uuid)
StatusMeansBody
200DoneThreadResponse
401Bad token
404No such thread or proposal
409Already decided, or no longer executable

POST /api/v1/assistant/threads/{id}/proposals/{proposal_id}/reject

Reject one proposal. Nothing changes.

ParameterInTypeAbout
idpathstring (uuid)
proposal_idpathstring (uuid)
StatusMeansBody
200DoneThreadResponse
401Bad token
404No such thread or proposal
409Already decided

GET /api/v1/assistant/tools

Every tool, with the permission it costs and whether this caller could run it where the query points.

ParameterInTypeAbout
project (optional)querystring or null
environment (optional)querystring or null
StatusMeansBody
200DoneToolsResponse
401Bad token

POST /api/v1/assistant/tools/{name}

Run one tool AS THE CALLER. The body IS the tool input, verbatim.

ParameterInTypeAbout
namepathstring

Body: object

StatusMeansBody
200DoneToolCallResponse
401Bad token
404No such tool
422The input does not match the tool's schema

Types

AssistantStatusResponse

FieldTypeAbout
configuredboolean
model (optional)string or nullanthropic or fake; null when nothing is configured.
sentencestringThe sentence the panel prints when configured is false, "" otherwise.

ThreadResponse

FieldTypeAbout
created_atstring
environmentstring
idstring (uuid)
messagesarray of ThreadMessage
pagestring
project (optional)string or null
proposalsarray of ProposalResponse
rolestringThe caller's role name in this thread's project, which is what the change set footer's chip prints.
statestringidle (nothing pending), waiting (one or more pending proposals) or refused (the last turn stopped on a refusal).
titlestring
updated_atstring

OpenThreadBody

FieldTypeAbout
environment (optional)string or null
page (optional)string or null
project (optional)string or null

PostMessageBody

FieldTypeAbout
textstringWhat the operator typed. 1 to 8000 characters.

ToolsResponse

Everything the caller may see, whether or not they may run it.

FieldTypeAbout
toolsarray of ToolDescriptor

ToolCallResponse

The answer to one tool call. It is a 200 even when the tool refused or failed, which is what lets ops mcp copy is_error into MCP's isError inside a RESULT rather than inventing one out of a 403 body.

FieldTypeAbout
is_errorbooleantrue when the tool refused or failed; the MCP proxy copies it into isError and the assistant loop into is_error.
resultobjectThe tool's own answer. On an error, {"error": "<sentence>"}.
toolstring

ProposalResponse

FieldTypeAbout
decided_at (optional)string or null
environmentstring
idstring (uuid)
message_idinteger
permissionstring
project (optional)string or null
resultobjectPresent once decided. {"error": "…"} on a rejection or a failure.
rowsarray of ProposalRow
statusstringpending, accepted, rejected or failed.
tagstringread or write, the same tag GET /assistant/tools reports.
titlestring
toolstring

ThreadMessage

FieldTypeAbout
atstring
idinteger
rolestringuser or assistant.
stop_reason (optional)string or null
textstringEvery text block of the turn, joined with a blank line. The console renders this; the raw blocks stay in the database.

ToolDescriptor

FieldTypeAbout
allowedbooleanWould this caller be allowed to run it, in the project and environment the query named? ADVISORY: the executor checks again, so a stale true here costs a refusal and never an action.
descriptionstring
input_schemaobjectJSON Schema of the input.
namestring
permission (optional)string or null
tagstringread or write. Drives ONLY the console's Accept gate.

ProposalRow

FieldTypeAbout
kstring
vstring