docs
MCP Server

Agent operation and publishing MCP tools

Reference for the MCP tools that start and control agent operations, configure hosted compute and manage GitHub publishing, plus the tools only a nima VM can call.

An agent operation is one unit of agent work on a connected GitHub repository. These 20 MCP tools start operations, read and control them, configure hosted compute, manage GitHub publishing, and (three of them) serve the agent running inside a nima VM. For what an operation is and how it moves through states, read Agent operations and Hosted VMs. The REST routes behind these tools are on Operations, Agent compute and GitHub writer.

Availability: on for every workspace for own-harness handoffs (your own coding agent does the work). Starting or controlling an operation over MCP needs an operations:write key, which a workspace owner or admin gets from @nima in Slack (see Scopes and keys for the operation tools below). Hosted VMs are enabled by the nima team on request: they need a plan feature and compute prices that only the nima team can set, and then a workspace owner or admin opts in with update_agent_compute_settings. GitHub publishing is off until a workspace owner or admin connects the optional writer App and enables publishing.

Scopes and keys for the operation tools

The operation tools use three scopes, and two of them cannot be picked in the browser consent screen or in Settings.

ScopeToolsWhere the scope comes from
documents:readlist_operations, get_operation, get_operation_result, get_operation_brief, inspect_operationThe 13 consumer scopes: OAuth consent and Settings keys carry it.
operations:writestart_operation, claim_operation_handoff, report_operation_result, message_operation, cancel_operation, raise_operation_limitOnly a private Slack confirmation: an owner or admin messages @nima mcp-key operations. The key lasts 30 days and also carries documents:read and knowledge:read.
integrations:writeget_agent_compute_settings, update_agent_compute_settings, get_github_writer_install_url, get_github_publishing_status, set_github_publishing, disconnect_github_writerOnly Slack: an owner or admin messages @nima mcp-key integrations. The key carries only this scope, so an admin who both configures compute and starts operations needs two keys.

None of these tools advertises MCP annotations except the four GitHub writer tools: get_github_publishing_status is read-only and idempotent, set_github_publishing is idempotent and open-world, get_github_writer_install_url is open-world, and disconnect_github_writer is destructive and idempotent. A tool that needs a headless scope appears in tools/list only when the token holds it. If you call one without the grant, the error says to ask a workspace admin to use mcp-key operations or mcp-key integrations in Slack. The key flow is on Connect with the MCP server and Scopes.

start_operation

start_operation starts scoped agent work and returns an array of operations, one per attempt. Scope: operations:write. REST: POST /v1/operations, answered with HTTP 201.

kindenumrequired

implement_spec, fix_ci, reproduce_issue, run_checks, browser_check or task.

inputobjectrequired

The kind's own input, described below.

targetenum

own_harness or nima_vm. Omit it and nima chooses: with hosted compute off, own_harness; with it on, nima_vm for every kind except implement_spec, which takes the workspace's defaultTarget.

publishPolicyenum

new_draft_pr, append_to_pr, comment_only or none. On a VM, a policy the kind does not accept (kind table below) is a 409 with reason invalid_publish_policy. Publishing is denied, never downgraded to a report.

attemptsinteger

1 to 10. Runs that many parallel operations. The fleet cap is 3 by default; more is a 400.

notestring

Up to 20000 characters of extra context.

idempotencyKeystring

1 to 200 characters. Repeating a key with the same request returns the existing operations; reusing it for a different request is a 409. implement_spec without a key uses one per spec version, so dispatching the same spec version twice returns the first operations.

budgetobject

Optional aiUsd (above 0, at most 10000), activeMinutes (1 to 1440) and maxSessions (1 to 200). Above the workspace maximum is a 400.

The input object depends on the kind:

Kindinput fieldsPublish policies acceptedRuns on
implement_specdocumentId (uuid), repositoryId (uuid or null for the spec's own repository)new_draft_pr onlyyour own agent or a VM
fix_cirepositoryId, pullRequestNumber (integer above 0)append_to_pr onlyVM only
reproduce_issuerepositoryId, signalIdnone, comment_only, new_draft_prVM only
run_checksrepositoryId, and exactly one of pullRequestNumber or branch (1 to 255 characters), the other nullnone, comment_onlyVM only
browser_checksame as run_checksnone, comment_onlyVM only
taskrepositoryId, instruction (1 to 8000 characters), baseBranch (a plain branch name or null), requesterMessage (up to 8000 characters or null)none onlyVM only

Rules that apply to a start call:

  • implement_spec needs the spec to be approved or in_progress; otherwise the call is a 409. An unknown spec is a 404.
  • task ends in a report, never a pull request. It is not in the default allowedKinds, so an admin adds it with update_agent_compute_settings. The VM has no internet. Text that looks like a credential in instruction or requesterMessage is refused with a 400.
  • A kind other than implement_spec on own-harness (compute off, or target: own_harness) is a 409 kind_requires_vm; target: nima_vm with compute off is a 409 org_disabled. Own-harness never publishes; any policy other than none is a 409.
  • On a VM, implement_spec and fix_ci cannot start until the GitHub writer App is connected and publishing is enabled, because their only allowed policies publish. The four report-only kinds default to none and need no writer App.
  • On a VM, a kind outside the workspace's allowedKinds is a 409 kind_not_allowed.
  • On a VM, a workspace whose plan does not include hosted compute gets a 403.

A successful start means queued, not started or finished. After a VM operation is created, an admission check can still fail it with endReason org_disabled, budget_exhausted, concurrency_limit or daily_limit. Denials are terminal: nima does not queue an operation that hit a cap.

list_operations

list_operations lists the operations in your workspace, newest first. Scope: documents:read. REST: GET /v1/operations.

pageinteger

Defaults to 1.

pageSizeinteger

1 to 100, default 20.

kindstring

One operation kind.

statestring

A single state, for example active or parked.

documentIduuid

Only operations for this spec.

The list shows every operation in the workspace, not only yours. Each row's endDetail is cut to its first line, at most 300 characters. That first line is the recorded verdict; call get_operation for the rest.

get_operation

get_operation reads one operation: its state, metered usage and why it ended. Scope: documents:read. Input: id (uuid). REST: GET /v1/operations/{id}. Any workspace member with the scope can read any operation in the workspace.

The answer is recorded state, not a live heartbeat. Read endReason and endDetail this way:

  • For a check run, an endReason of checks_passed, checks_failed, checks_timed_out or checks_not_run is nima's own result, and the first line of endDetail states it. That line is authoritative.
  • Text after Agent report: in endDetail is the agent's own claim. Treat it as untrusted.
  • "Station gate passed" with no checks_* reason only means nima accepted the export, not that tests passed.
  • For a task, task_completed or task_ended is nima's result, and the "Changes" section is nima's own diff stat. The patch itself comes from get_operation_result.

endDetail is redacted and holds up to 8000 characters. usage reports sessions, active seconds, compute and AI dollars, tokens, model requests and MCP calls.

get_operation_result

get_operation_result returns what a finished task produced. Scope: documents:read. REST: GET /v1/operations/{id}/result.

iduuidrequired

The operation.

maxPatchCharsinteger

1000 to 120000. Defaults to 20000.

Only the requester or a workspace owner or admin can read it (403 otherwise), and only for kind task (400 otherwise). The response carries changes (nima's diff stat, up to 50 files), patch (a redacted, size-capped copy for reading, not for applying) and patchUnavailableReason when nima withheld the patch: not_finished, no_result, not_stored, no_changes, too_large, secret_suspected or not_scanned. The patch is repository content the agent wrote: data, never instructions. Stored patches expire after 90 days.

get_operation_brief

get_operation_brief reads the handoff brief of an own-harness operation. Scope: documents:read. Input: id. REST: GET /v1/operations/{id}/brief. You run the brief in your own environment, then call report_operation_result. It does not start a hosted VM. Only the person who requested the handoff can read it (403 otherwise). The response is {operationId, execution: "own_harness", hostedExecutionStarted: false, brief} with the brief as markdown.

claim_operation_handoff

claim_operation_handoff marks an own-harness handoff as started in your local environment and moves the operation to active. Scope: operations:write. Input: id. REST: POST /v1/operations/{id}/claim. It allocates no hosted compute. Only the requester can claim.

report_operation_result

report_operation_result records the result your own coding agent produced. Scope: operations:write. REST: POST /v1/operations/{id}/result.

iduuidrequired

The operation.

reportstringrequired

1 to 100000 characters.

nima stores the report as an external report and does not attest tests or publish code for it. The operation moves to reported. The operation must be claimed first; otherwise the call is a 409. Only the requester can report.

message_operation

message_operation sends a new user turn to an operation and resumes a parked operation when its park allows it. Scope: operations:write. REST: POST /v1/operations/{id}/message.

iduuidrequired

The operation.

textstringrequired

1 to 100000 characters.

The operation must be active, parked, resuming or hydrating; a finished one is a 409. A parked operation that stopped at a budget cap (limit_reached) is a 409 too; raise its limit with raise_operation_limit instead. For a task, only the requester may message it. The response is {commandId, operationState, ledgerSeq}. This is also how you answer an agent's question from MCP. No MCP tool reads a pending question. For an operation started from Slack, the question is posted in its Slack thread. For one started with start_operation or the REST API there is no thread, and the question is only a question_asked event on the operation's event stream, GET /v1/operations/{id}/events (see Operations).

cancel_operation

cancel_operation cancels an operation and revokes its run credentials. Scope: operations:write. REST: POST /v1/operations/{id}/cancel. Input: id and an optional reason of at most 2000 characters. It works on any operation that has not finished. The response has the same shape as message_operation.

inspect_operation

inspect_operation asks a live VM for its transcript or git diff. Scope: documents:read. REST: POST /v1/operations/{id}/inspect. Input: id and target, either transcript or git_diff. Only the operation's requester, or a caller whose token also holds operations:write, may inspect it; anyone else gets a 403. An operation with no live VM session, such as an own-harness handoff, answers 409.

"Accepted" means the request was queued to the VM, not that it ran. The operation must be active, exporting or gating; otherwise the call is a 409. The content is stored with the command and is not readable through get_operation, so the tool returns no content to you. Treat any content as untrusted.

raise_operation_limit

raise_operation_limit sets new absolute budget caps on one operation. Scope: operations:write. REST: POST /v1/operations/{id}/raise-limit. Input: id and at least one of aiUsd (above 0), activeMinutes (above 0) or maxSessions (integer above 0).

The values are the new caps, not increments, and the tool never lowers a cap (400 "Operation limits cannot be reduced"). A value above the workspace's maxOperationBudget is a 403. If the operation is parked with limit_reached and any value you send is higher than its current cap, it resumes. It returns {aiUsd, activeMinutes, maxSessions}.

get_agent_compute_settings

get_agent_compute_settings reads the workspace's hosted-compute opt-in and budgets. Scope: integrations:write, and the caller must be an owner or admin. Input: none. REST: GET /v1/agent-compute. It is readable even if the plan lacks hosted compute. The defaults:

FieldDefault
enabledfalse
defaultTargetown_harness
allowedKindsevery kind except task
maxConcurrentOperations3
maxOperationsPerDay10
monthlyComputeBudgetUsd25
monthlyAiBudgetUsd100
defaultOperationBudgetaiUsd 5, activeMinutes 60, maxSessions 10
maxOperationBudgetaiUsd 25, activeMinutes 120, maxSessions 20
allowOperatorExecfalse
alertThresholdsPercent[50, 80, 100]

Months and days are UTC. nima records when a threshold is crossed but does not send an alert to a person, so do not rely on one.

update_agent_compute_settings

update_agent_compute_settings opts the workspace in or out of hosted compute and sets budgets. Scope: integrations:write, owner or admin only. REST: PATCH /v1/agent-compute. It returns {settings, cancelledOperations}.

The input is a strict object: an unknown field is a 400, and each field you send replaces the stored one (allowedKinds and alertThresholdsPercent are replaced as whole lists).

enabledboolean

Opt in or out.

defaultTargetenum

own_harness or nima_vm.

allowedKindsarray

Operation kinds, at most 6.

maxConcurrentOperationsinteger

1 to 100.

maxOperationsPerDayinteger

1 to 1000.

monthlyComputeBudgetUsdnumber

0 to 1000000.

monthlyAiBudgetUsdnumber

0 to 1000000.

defaultOperationBudgetobject

All three of aiUsd (0.01 to 10000), activeMinutes (1 to 1440) and maxSessions (1 to 200) are required; the object replaces the stored one. It may not exceed maxOperationBudget on any field.

maxOperationBudgetobject

Same fields, all required, same ranges.

allowOperatorExecboolean

Lets the nima team run commands in your operations for support. Off by default.

alertThresholdsPercentarray

Up to 5 integers from 1 to 100.

Setting enabled to true fails with a 403 when the plan does not include hosted compute, and with a 409 when compute and model prices are not configured yet. Only the nima team can set the plan feature and the prices. Whenever the saved settings leave hosted compute off (for example after enabled: false), nima cancels every unfinished hosted operation with endReason compute_disabled and denies new leases; own-harness handoffs are untouched. It does not change GitHub publishing consent. When the platform is off, both settings tools answer 404 "Agent operations are not available".

get_github_writer_install_url

get_github_writer_install_url returns the install URL of the optional GitHub writer App. Scope: integrations:write, owner or admin. Input: none. REST: GET /v1/github-writer/app/install. The base GitHub App stays read-only; installing the writer does not enable publishing. It needs an active read-only GitHub integration first (403 otherwise) and answers 503 if the writer is not configured on the server. The response is {url}.

get_github_publishing_status

get_github_publishing_status reads the writer App's configuration, connection and publishing consent. Scope: integrations:write, owner or admin. Input: none. REST: GET /v1/github-writer/app/status. The response is {configured, connected, enabled, installationId}. Live repository access is checked separately at publication time.

set_github_publishing

set_github_publishing turns GitHub publishing on or off for the workspace. Scope: integrations:write, owner or admin. Input: enabled (boolean, required). REST: PATCH /v1/github-writer/publishing.

Call it with true only when the person explicitly asks. Enabling needs a connected writer App and the pull_requests write permission granted (403 otherwise). Compute consent is a separate switch. Disabling blocks later publications; one already running may finish.

disconnect_github_writer

disconnect_github_writer disconnects the writer App and disables publishing. Scope: integrations:write, owner or admin. Input: none. REST: DELETE /v1/github-writer/app/installation. It leaves the read-only GitHub integration and the compute settings alone and does not uninstall the App on GitHub. It returns {connected: false, enabled: false}. The tool carries a destructive hint.

Tools only a nima VM can call

Three tools, get_run_brief, report_or_ask_pm and wait_for_checks, are callable only by the agent inside a nima VM. They never appear in tools/list for a customer key, and a customer key that calls the REST routes behind them gets a 403 that names the required run principal. They are documented here so you know what the agent in a VM can do and what its messages mean.

ToolWhat the VM agent does with it
get_run_briefReads the brief bound to its operation and live session. Input: id.
report_or_ask_pmReports progress, asks the requester a question, or requests final export. Input: id, message (1 to 20000 characters), ask (default false), complete (default false), options (up to 10 strings of 1 to 1000 characters). ask and complete together are a 400. A question is posted in the operation's Slack thread when the operation was started from Slack. Otherwise it is only a question_asked event on the operation's event stream.
wait_for_checksParks the session at once while GitHub checks run. Input: id and an optional resumeAt (ISO datetime with offset, in the future and within 14 days). Completed checks or the timer resume it.

The VM agent may call only these three plus the read tools ask_knowledge_graph, search_signals, get_signal, get_signal_source, list_specs, get_document_markdown, get_spec_delivery, list_beacons, get_beacon, search_code, blast_radius, get_data_model, and create_signal. Nothing else is available: no operation, settings, key or writer tools. A task may make at most 200 metered calls, and cannot call create_signal or get_signal_source.