Skip to main content
Glama

plori

plori (plori.ai): a cloud AI agent with its own persistent environment - durable disk, real CLI tools, and memory.

plori provides the agent: each one gets a persistent machine with a real disk, real tools, and memory of its own. Idle agents scale to zero. You talk to your agents in the web app, or drive them from your own tools over MCP and REST.

This repository is the integration front door. The product itself lives at plori.ai; the remote MCP server lives at https://api.plori.ai/mcp.

Connect your MCP client

plori is a remote MCP server (streamable HTTP). There is nothing to install or run locally. Sign-in happens in your browser via OAuth 2.1 the first time your client connects; headless environments can use an API key instead.

Claude Code

Paste this into your Claude Code conversation:

Set up https://plori.ai/SKILL.md

Claude reads the setup instructions and configures MCP if needed. If the new server has not loaded, type /reload-plugins when Claude asks, then continue in the same conversation. With pairing, open the short address Claude shows, enter the code, sign in, and approve. You can use a phone while Claude Code runs on a remote machine. No installed skill or plugin is required.

Cursor

Use the one-click Add to Cursor button, or add manually: Settings -> MCP -> Add server with URL https://api.plori.ai/mcp.

VS Code

code --add-mcp '{"name":"plori","type":"http","url":"https://api.plori.ai/mcp"}'

Codex CLI

codex mcp add plori --url https://api.plori.ai/mcp
codex mcp login plori

Codex auto-detects plori's OAuth on login. One-install alternative with the skill bundled: codex plugin marketplace add plori-ai/codex-plugin then codex plugin add plori@plori.

Cline

Follow llms-install.md, written for Cline's automated installer.

Any other client

Native streamable-HTTP clients connect to https://api.plori.ai/mcp directly. Clients that only speak stdio can bridge with the plori-mcp npm package (a thin wrapper around mcp-remote with the endpoint pinned; this repository is its source):

npx plori-mcp
# headless / CI: authenticate with an API key instead of the OAuth flow
npx plori-mcp --header "Authorization: Bearer plori_sk_..."
# equivalent, without the wrapper:
npx mcp-remote https://api.plori.ai/mcp

API keys are minted in Dashboard -> Settings on a registered account.

Related MCP server: openpouch

Or skip MCP: your own terminal

The plori CLI is not an MCP client. It is a door of its own, and it opens the same live session the web app shows: the recent history, a prompt, streaming output, and the approval queue in one place. A turn you send in the terminal appears in an open browser tab as it streams.

curl -fsSL https://plori.ai/install.sh | sh
plori login && plori attach <agent-name>

The installer drops one static binary in ~/.local/bin and needs no Node; if that directory is not on your PATH yet, the script prints the line to add. npm i -g @plori/cli works too. The argument to attach is an agent name, an agent id, or a session id, so a session id copied out of the web app works on its own. Ctrl-D detaches and leaves the run going on the server.

The terminal does not give the agent access to your local files. The shell, the disk, and the files are the agent's own cloud environment.

Verify the connection

Ask your client:

List my plori agents and tell me how many credits I have left.

You should see list_agents and get_credits tool calls and a real answer.

What the tools do

The server exposes 25 tools in five groups.

  • Agents (the Plori Router picks each agent's model per task): list_agents (your agents, with model and live session status), get_agent (one agent's name, type, model, and status, plus its mailbox of mail from other agents on the account), create_agent (get or create an agent by name, which reuses an existing agent of that name instead of making a duplicate), delete_agent (permanently delete an agent and revoke its disk).

  • Runs: invoke_agent (send a message and wait for the reply, with wait_seconds to set how long to hold, idempotency_key to make a retry return the original run, and callback_url plus callback_secret to post a signed status notification to your endpoint), get_run_result (a run's status, timestamps, credits, tokens, tool progress, and the reply once it finishes), list_runs (an agent's run history, most recent first), cancel_run (stop an in-flight run, which reports cancelling and then cancelled), schedule_run (invoke an agent once later, after a delay or at a timestamp).

  • Human-in-the-loop: list_pending_inputs (runs paused on an approval or an input request), answer_pending_input (approve, deny, or answer one, which starts a continuation run).

  • Workflows: list_workflows (every workflow, or one agent's with agent_id, or the unassigned ones with agent_id="none"), get_workflow (metadata and the step projection pinned for execution), get_workflow_version (one exact version's full definition and parameter values), create_workflow (an empty workflow on a manual, cron, or webhook trigger, for an agent to build), edit_workflow (a batch of constrained edits as one new draft, under compare-and-swap on base_version), set_workflow_agent (assign one of your agents to a workflow, typically after delete_agent reports paused workflows or run_workflow returns workflow_agentless), run_workflow (run a built workflow now, as a real, billed execution), list_workflow_executions (recent executions with status, fault, trigger source, timing, and credits), get_workflow_execution (one execution's per-step input and output payloads).

  • Account: get_credits (balance and plan), get_usage (spend by meter and by agent), get_disk (included, purchased, and used bytes), empty_trash (permanently empty an agent's trash so deleted files stop counting against the disk; only while that agent's pod is asleep), list_connections (your third-party OAuth providers with status, authorization and expiry times, and the scopes configured for each, never tokens or client secrets).

A turn that is still running when the hold ends continues on the server: invoke_agent returns a run_id with status running and a poll_after_seconds delay, and you read the answer with get_run_result using wait=true (or your own wait_seconds, up to 1800).

Costs: creating and running agents spends plori credits from your account. Reading (lists, results, balances) is free. The pricing page has the details. Revoke a client's access any time in your client's settings, or revoke the API key in Dashboard -> Settings.

For AI agents reading this

The machine-readable entry points:

  • Front door: plori.ai/agents.md

  • Site index: plori.ai/llms.txt

  • Skill: SKILL.md (index: /.well-known/agent-skills/index.json)

  • MCP server card: https://api.plori.ai/mcp/server-card

  • OAuth discovery: RFC 9728 protected-resource metadata on api.plori.ai, dynamic client registration supported

  • Registry entry: ai.plori/plori in the official MCP Registry

Every page on plori.ai is also served as Markdown: append .md to the path or send Accept: text/markdown.

Docs and support

Available Tools

25 tools
answer_pending_inputAnswer pending questionA
Destructive
Inspect

Answer a run that is paused on a human-input request (from list_pending_inputs). For an approval, set approved=true/false. For an input request, set value to the requested text. A successful answer starts a continuation run: the returned run_id is that new continuation run, not the parked run, and is the id to poll with get_run_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNoAn optional note recorded with the answer.
scopeNoSet to "thread" to approve AND allow the rest of this conversation's writes to the same connection, method and host, instead of a standing grant. It expires after 24 hours and covers no other host, method or conversation. Only set it when the human said to stop being asked for the rest of this task; ignored without approved=true, and on a card that has no such scope. Cannot be combined with always_allow.
valueNoFor an input request: the value to supply.
run_idYesThe parked run's id.
approvedNoFor an approval request: approve (true) or deny (false).
always_allowNoApprove AND stop asking for this tool on this agent (a standing grant). Only set it when the human explicitly said to stop being asked, and only on a row whose consent_tool is set; ignored without approved=true. Revoke via DELETE /v1/agents/{agent_id}/tool-consents/{tool}.
tool_call_idYesThe tool_call_id of the pending request (from list_pending_inputs).
max_turn_secondsNoOptional soft wall-clock budget to preserve on the continuation run; it does not change the parked run or impose a hard deadline.

Output Schema

ParametersJSON Schema
NameRequiredDescription
run_idNoThe continuation run created by the answer.
statusYesAnswer status.
alreadyNoWhether this request had already been answered.
session_idNoThe continuation run's session.
tool_call_idYesThe pending tool call that was answered.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a non-obvious and critical behavior: a successful answer starts a continuation run, and the returned run_id refers to that new run, not the parked one, and should be polled via get_run_result. Since annotations already carry destructiveHint and readOnlyHint, the description does not need to repeat them, though it could have warned about double-answering or consent side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states purpose and mode selection, and the second sentence delivers the essential continuation-run caveat. There is no filler or redundant exposition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich parameter schema, annotations, and output schema, the description covers the key non-obvious flow: the continuation run and which run_id to poll. Consent and budget parameters are left to the schema, which is acceptable because the schema documents them thoroughly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already documents each parameter, but the description adds a helpful selection rule: use approved for approvals and value for input requests, and clarifies that run_id is the parked run and tool_call_id comes from list_pending_inputs. This goes slightly beyond a bare restatement, though most parameter-level detail remains in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact action (answer), the target (a run paused on a human-input request), and the source (list_pending_inputs). It also distinguishes the two modes, approval vs input, which differentiates it clearly from sibling tools like list_pending_inputs or cancel_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly identifies when to use the tool: when a run is paused on a human-input request from list_pending_inputs, and it gives branch-level guidance for approvals vs input requests. It does not explicitly state when not to use it or mention alternatives such as cancel_run, so it misses the top anchor.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cancel_runCancel runA
Destructive
Inspect

Stop an in-flight agent run. Cancellation is asynchronous: a successful call returns status "cancelling"; poll get_run_result until the run becomes "cancelled". A run that already finished cannot be cancelled.

ParametersJSON Schema
NameRequiredDescriptionDefault
run_idYesThe run id returned by invoke_agent.
agent_idYesThe agent's UUID.

Output Schema

ParametersJSON Schema
NameRequiredDescription
runIdYesThe run whose cancellation was requested.
statusYesCancellation request status.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing that cancellation is asynchronous, that a successful call returns status 'cancelling', and that the run must be polled until it becomes 'cancelled'. This gives the agent critical expectations about side effects and timing that annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences with no filler. The core purpose is front-loaded, followed by essential async behavior and a practical caveat. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with a full input schema, output schema, and rich annotations, the description supplies the missing operational knowledge: async cancellation, status transition, and the terminal-state limitation. Nothing essential is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with both run_id and agent_id already described meaningfully in the input schema. The description does not add parameter-level detail, but it does not need to because the schema already handles it. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Stop an in-flight agent run.' This clearly distinguishes cancellation from related siblings like invoke_agent or get_run_result. The scope is precise: it targets only runs that are actively in progress.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear usage context by specifying the operation is for in-flight runs and explicitly warns that finished runs cannot be cancelled. It also instructs the agent to poll get_run_result to observe the final state. However, it does not explicitly name alternative tools for finished runs or other scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_agentGet or create agentA
Idempotent
Inspect

Get or create an agent by name: a persistent cloud environment running plori's agent, with its own disk, tools, and memory. Create one when the work should accumulate somewhere the user can return to: a project with files that build up, a repo to keep checked out, tools to install once and reuse, or a long job to hand off. You do not need one for a question you can answer yourself or for a one-off script with no state worth keeping. If the account already has an agent with this name, that agent is returned (marked "existing": true) instead of a duplicate — safe to call repeatedly, and the right way to reconnect to an agent you used before. Creation is subject to the account's agent-count limit. The Plori Router chooses the model for each task.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe agent's name. Reusing a previous name returns that existing agent.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYesThe Agent's unique identifier; pass it to other tools as agent_id.
urlNoThis Agent's page in the plori web app.
nameYesThe Agent's name, chosen by its owner and unique within the account.
modelYesThe model slug this Agent is configured to use. Empty means no explicit choice, which is not the same as no model — read effective_model for what a run will actually use.
configYesArbitrary JSON owned by the producing engine.
movingNoTrue while this Agent's files are being copied to a new disk; check storage_notice rather than a separate route for the outcome.
statusNoThe live warm-session state: warming, ready, or sleeping; empty when no session is active.
backendYesThe compute backend this Agent runs on.
user_idYesThe identifier of the account that owns this Agent.
deletingNoTrue while this Agent's disk is still being erased; offer no action on it besides retrying the deletion itself.
existingNoWhether create_agent returned an existing same-name agent instead of creating one.
queued_atNoWhen a still-warming attach was accepted; present only while it is queued for node capacity.
created_atYesWhen the Agent was created.
last_run_atNoWhen this Agent last started a run; absent when it has never run.
deleting_sinceNoWhen the deletion was first requested; present only while deleting is true.
storage_noticeNoThe one sentence, if any, telling the owner about a storage move that stopped; show it verbatim, not paraphrased.
effective_modelYesThe model a run on this Agent will actually use. plori-auto means the hosted router chooses per turn.
advisor_max_spend_micro_usdYesOptional maximum advisor-completion spend per turn in micro-US-dollars. Zero disables advisor completions; null leaves no spend cap.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate idempotentHint=true and destructiveHint=false. The description adds valuable behavioral context: returned agents are marked 'existing', safe repeated calls, account-level agent-count limits, and the Plori Router choosing the model. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then expands logically into use cases, idempotency, limits, and routing. It is longer than minimal, but each section earns its place. Minor redundancy exists because 'safe to call repeatedly' partly repeats the idempotentHint annotation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a create-or-get tool: it explains the resource, when to use it, idempotency, account limits, and model selection. The output schema exists, so return values need not be described in the text. No critical operational detail appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents the name parameter and its reuse behavior. The description reiterates that reusing a name returns the existing agent but does not add materially new parameter-level detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool gets or creates an agent by name, and defines the agent as a persistent cloud environment with its own disk, tools, and memory. It differentiates from siblings by emphasizing reuse semantics ('If the account already has an agent with this name, that agent is returned'), though it does not explicitly name alternatives like get_agent or invoke_agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: persistent projects, checked-out repos, reusable tools, and long hand-off jobs. It also states when not to use it: simple questions or one-off scripts with no state worth keeping. This is strong, actionable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_workflowCreate workflowAInspect

Create an empty workflow. Returns the new workflow, including its id and — for a webhook trigger — its hook URL. trigger_kind defaults to "manual" (run it on demand with run_workflow); "cron" needs a cron_expr; "webhook" mints a public hook URL. trigger_kind is not read from description: a schedule stated only there leaves the workflow manual. The build can still change it — when the owning agent gives the workflow a schedule or webhook trigger step, trigger_kind and cron_expr follow that step. A new workflow has no steps and cannot run until its owning agent builds them.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesA short name for the workflow.
agent_idNoOptional UUID of one of your agents to own the workflow. That agent is then the one that can build, edit, and run it from a chat; leave it out and the workflow stays unassigned until you set an owner.
cron_exprNoCron schedule (required when trigger_kind is "cron"), e.g. "0 9 * * *". A 5-field cron or an @daily/@hourly descriptor, evaluated in UTC.
descriptionNoOptional description of what the workflow does. It is prose for the reader; no field is derived from it.
trigger_kindNoOptional trigger: "manual" (default), "cron", or "webhook". The build can change it later: a schedule or webhook trigger step sets it.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
engineYes
statusYes
user_idYes
agent_idYes
hook_keyYes
cron_exprYes
created_atYes
updated_atYes
descriptionYes
notify_prefYes
next_fire_atYes
trigger_kindYes
paused_reasonNo
template_slugNo
active_versionYes
current_versionYes
spend_cap_monthYes
agent_deleted_atNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial non-obvious behavior beyond the annotations: trigger_kind is not derived from the description field, the owning agent's build step can override trigger_kind and cron_expr, and the created workflow cannot run until steps are built. These are exactly the hidden behavioral traits an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries distinct value: purpose, return values, trigger behavior, the description-field gotcha, build mutability, and run-readiness. The most essential scoping statement ('empty workflow') is front-loaded, and there is no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers creation semantics, trigger variants, ownership/build constraints, and return values. Since an output schema is present, the response shape does not need to be spelled out here, and no critical operational gap remains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds meaningful cross-parameter semantics: manual is the default trigger, cron makes cron_expr required, webhook generates a public URL, description is purely prose, and the build can later mutate trigger_kind and cron_expr. This goes well beyond the individual parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create an empty workflow') and immediately clarifies what it returns (new workflow id, hook URL for webhook triggers). It also distinguishes itself from built/runnable workflows by noting a new workflow has no steps and cannot run until built.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context on when to use it: run_workflow is referenced for manual execution, cron requires cron_expr, webhook mints a public hook URL, and a description-only schedule does not set trigger_kind. It does not explicitly name edit_workflow as the alternative for modifying workflows, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_agentDelete agentA
DestructiveIdempotent
Inspect

Permanently delete an agent and revoke its disk. This cannot be undone. Workflows the agent built are NOT deleted — they belong to the account — but the ones that were live are paused, and none of them run again until you assign them to another agent.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYesThe agent's UUID to delete.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYesThe successful HTTP status code from the underlying operation.
workflows_pausedNoHow many workflows this agent had built and had running were paused by the deletion. They are not deleted: assign them to another agent to run them again.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even though annotations already mark the tool as destructive and idempotent, the description adds significant behavioral context: deletion is permanent, disk is revoked, workflows are NOT deleted but are paused and will not run until reassigned. This goes well beyond the annotations and clarifies partial data preservation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core action and irreversibility are front-loaded, and the workflow-related caveat is presented in a clear second sentence. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with one parameter, the description fully covers the necessary context: irreversibility, disk revocation, workflow ownership, and runtime behavior of affected workflows. The output schema exists so return-value details are not required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter agent_id is already documented as 'The agent's UUID to delete.' The description adds no additional meaning beyond the schema, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Permanently delete an agent and revoke its disk.' This clearly distinguishes the tool from siblings like create_agent, get_agent, and list_agents, and its scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by explaining the consequences of deletion, especially how workflows are preserved but paused. It implies the alternative of assigning workflows to another agent, though it does not explicitly name set_workflow_agent or state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

edit_workflowEdit workflowA
DestructiveIdempotent
Inspect

Apply a batch of constrained edits as one new draft version under base_version compare-and-swap. Supported ops are set_params, add_step, remove_step, and add_router. Read the exact current definition with get_workflow_version first; a stale base_version is rejected instead of overwriting concurrent work. Editing does not activate the draft.

ParametersJSON Schema
NameRequiredDescriptionDefault
opsYesOne or more edits applied atomically in order.
workflow_idYesThe workflow's UUID.
base_versionYesThe workflow's current_version; the edit conflicts if it changed.

Output Schema

ParametersJSON Schema
NameRequiredDescription
versionYesThe new draft version created by the edit.
resolvedNoExternal identifiers resolved while binding the edit.
projectionYesThe value-light projection of the edited workflow definition.
workflow_idYesThe edited workflow.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and idempotentHint=true. The description adds valuable behavioral context: the compare-and-swap versioning, rejection of stale bases, and the fact that the edit creates a draft without activation. These details go beyond the annotation hints and are not redundant.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core action is front-loaded, followed by operational guidance (read first, stale rejection, no activation). Every sentence contributes to correct usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the key constraints: atomic batch, version conflict handling, prerequisite read, and activation behavior. With a full input schema (100% coverage) and an output schema present, the description provides sufficient context for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters and their purposes. The description adds only minimal extra meaning—confirming supported ops and explaining base_version's compare-and-swap role—but most of this is already present in the schema (e.g., base_version description says 'the edit conflicts if it changed'). Thus, it meets the baseline of 3 without significantly enhancing parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool applies a batch of constrained edits as a new draft version, listing the supported ops (set_params, add_step, remove_step, add_router). It distinguishes itself from siblings like create_workflow, delete_agent, and get_workflow by focusing on editing an existing workflow with a compare-and-swap mechanism.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs the agent to read the current definition with get_workflow_version first, and warns that a stale base_version is rejected. It also clarifies that editing does not activate the draft, setting clear expectations for when to use this tool versus others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

empty_trashEmpty agent trashA
DestructiveIdempotent
Inspect

Permanently empty one agent's trash. Deleting a file moves it into a trash that keeps counting against the account's disk until this is called — get_disk's trash_bytes says how much a call would free. Only works while the agent's pod is asleep: while it has run recently this returns an error asking you to wait for it to go idle (about two minutes with no run) or cancel the run first.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYesThe agent's UUID whose trash to empty.

Output Schema

ParametersJSON Schema
NameRequiredDescription
diskYesThe account's disk state right after emptying, the same shape get_disk returns.
bytes_freedYesBytes freed from the account's shared disk by this call: the account's trash total before minus after when both get_disk reads reported one, otherwise the account's used_bytes before minus after. 0 when nothing was freed or when neither figure was available to diff — the storage worker's own purge result is an entry count, not a byte count, so it cannot supply this number.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and idempotentHint=true, but the description adds substantial behavioral nuance: it explains that trash counts against disk until emptied, how to predict the freed space via get_disk, and the error condition when the pod is active. This goes far beyond the annotations, providing a clear mental model of side effects and preconditions. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each earning its place: the core purpose, the disk-impact rationale, and the operational constraint. It is front-loaded with the verb and resource, and the technical detail about pod-sleep state is presented immediately. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool with an output schema, the description covers all necessary context: what it does, why it matters (disk space), how to check recoverable space, and the exact precondition (pod asleep) with a fallback instruction. An agent has everything needed to call it correctly and understand consequences.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter agent_id is fully documented in the schema (100% coverage) with a clear description ('The agent's UUID whose trash to empty'). The description does not add extra parameter-level meaning, but given the schema already covers it, a baseline 3 is appropriate. The description's context about the tool's behavior does not extend parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Permanently empty one agent's trash') that precisely identifies the tool's action. It distinguishes itself from siblings like delete_agent and get_disk by explaining the trash mechanism and how get_disk reports the recoverable space. No ambiguity about what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on when to use it (when trash is counting against disk, so you want to free space) and explicitly states a critical constraint: it only works while the agent's pod is asleep, with a concrete wait time (about two minutes) and an alternative (cancel the run). It does not explicitly list alternative tools to use instead, but the get_disk reference provides a natural alternative for checking before calling. This is strong enough guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_agentGet agent detailsA
Read-only
Inspect

Get one agent's details (name, type, model, status) by its id, and its mailbox: same-account mail from other agents, open letters first (accepted, delivering, blocked), then applied or undeliverable ones, newest within each group, capped at 20.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYesThe agent's UUID (from list_agents or create_agent).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYesThe Agent's unique identifier; pass it to other tools as agent_id.
urlNoThis Agent's page in the plori web app.
nameYesThe Agent's name, chosen by its owner and unique within the account.
modelYesThe model slug this Agent is configured to use. Empty means no explicit choice, which is not the same as no model — read effective_model for what a run will actually use.
configYesArbitrary JSON owned by the producing engine.
movingNoTrue while this Agent's files are being copied to a new disk; check storage_notice rather than a separate route for the outcome.
statusNoThe live warm-session state: warming, ready, or sleeping; empty when no session is active.
backendYesThe compute backend this Agent runs on.
mailboxYesThis agent's mailbox letters, open ones (accepted, delivering, blocked) first, then applied or undeliverable ones, newest within each group, at most 20.
user_idYesThe identifier of the account that owns this Agent.
deletingNoTrue while this Agent's disk is still being erased; offer no action on it besides retrying the deletion itself.
queued_atNoWhen a still-warming attach was accepted; present only while it is queued for node capacity.
created_atYesWhen the Agent was created.
last_run_atNoWhen this Agent last started a run; absent when it has never run.
deleting_sinceNoWhen the deletion was first requested; present only while deleting is true.
storage_noticeNoThe one sentence, if any, telling the owner about a storage move that stopped; show it verbatim, not paraphrased.
effective_modelYesThe model a run on this Agent will actually use. plori-auto means the hosted router chooses per turn.
advisor_max_spend_micro_usdYesOptional maximum advisor-completion spend per turn in micro-US-dollars. Zero disables advisor completions; null leaves no spend cap.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds substantial behavioral detail: mailbox ordering (open letters first, then applied/undeliverable), grouping by status, newest within each group, and a cap of 20. This goes beyond the structured fields, though error/edge-case behavior is not addressed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one dense sentence with no filler; every clause earns its place, and the main purpose is front-loaded. It could be split into two sentences for readability, but it remains efficient and structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with an output schema covering return structure, the description supplies all necessary behavioral context: the fields returned, mailbox ordering and grouping rules, and the cap. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the agent_id description already explains its source and type. The description only adds 'by its id,' which is redundant with the schema and does not contribute additional semantic constraints or format details. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Get one agent's details'), identifies the resource by id, and enumerates the returned fields ('name, type, model, status') plus the mailbox. The singular 'one' and 'by its id' clearly distinguish it from list_agents and other sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It is clear that this tool is for retrieving a single agent when you already have its UUID, and the schema notes the id comes from list_agents or create_agent. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_creditsGet account balanceA
Read-only
Inspect

Get the authenticated account's US-dollar balance and plan. Running agents spends this prepaid balance, so check it before invoking. For where the money went, use get_usage instead. balance_usd is the dollar-formatted balance.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
packsYesCredit packs this account can buy. Each pack's usd_cents is its price in US cents and its credits are what the purchase adds to balance.
plansYesSubscription plans on offer, with their monthly credit grant.
limitsYesThe caps this account's plan tier enforces.
balanceYesThe account's remaining prepaid balance, in credits. 1,000,000 credits = 1 US dollar.
user_idYesThe identifier of the account this balance belongs to.
audienceYes
plan_tierYesThe plan tier this account resolves to: free, pro or power. An account with no active plan is free.
active_planYesThe account's current subscription, or null when it has none and is on the free tier.
balance_usdYesThe account balance formatted in US dollars, without a currency symbol.
account_emailYesThe email address of the account this balance belongs to.
can_manage_billingYes
low_credit_thresholdYesThe balance, in the same credits, below which this account is warned it is running low.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, so the read-only nature is covered. The description adds useful context beyond the annotations: the balance is prepaid and is spent by running agents, making it important to check before invocation. This is valuable behavioral context for the caller.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, each earning its place: identifying the resource, warning about prepaid spend, directing to the sibling for usage details, and clarifying a returned field. The critical usage guidance is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only balance check with an output schema present, the description covers the purpose, when to call it, what the balance represents, and how it differs from the closely related sibling. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema offers nothing to explain. The description adds relevant output field context by naming balance_usd and noting it is dollar-formatted, which helps the agent interpret results despite no parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get the authenticated account's US-dollar balance and plan.' It also distinguishes itself from the sibling get_usage by clarifying that get_credits is for checking balance, not for seeing where money went.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to use this tool ('check it before invoking' agents that spend prepaid balance) and names the alternative for a different need: 'For where the money went, use get_usage instead.' This fully routes the agent between siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_diskGet disk usageA
Read-only
Inspect

Get the authenticated account's disk state (included, purchased, used bytes, and monthly cost).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
used_bytesYes
total_bytesYes
trash_bytesNo
usage_staleNoTrue when a mount is holding one of the account's disks but has not reported its usage within the writer-lease lifetime. used_bytes is then the last figure that mount reported, not the current one — treat it as a floor and say so rather than quoting it as the account's usage.
warning_levelYes
included_bytesYes
monthly_creditsYes
purchased_bytesYes
usage_observed_atNoWhen a mount last reported the used figure. Present only while a mount is holding one of the account's disks; when none is, nothing can be changing the figure and there is no reporting clock to quote.
storage_credits_per_gbYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safe read-only nature is covered. The description adds useful scoping ('authenticated account's') and mentions monthly cost, but it does not disclose other behavioral details like response shape or potential delays; the output schema covers return format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence contains all essential information without repetition or filler. Every phrase adds meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with an output schema, the description is complete. An agent can correctly determine when and how to invoke this tool without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the baseline is 4. The description adds value by naming the output fields, which is sufficient for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and resource ('disk state') and enumerates the exact data returned: included, purchased, used bytes, and monthly cost. This clearly distinguishes the tool from siblings like get_usage or get_credits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when you need the authenticated account's disk usage or cost, but it does not explicitly say when to use this tool versus alternatives such as get_usage. There is no exclusion or comparison to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_run_resultGet run resultA
Destructive
Inspect

Get a run's status, timing, attributed credits (micro-US-dollars) and tokens, and what it is doing while it runs: last_worklog (the agent's own most recent note), last_tool_step ("running ", or "completed " between calls), last_activity_at, and tool_progress (active calls, last completion time, completed-call count) when telemetry exists. With wait=true it holds your turn until the run finishes, pauses for input, or the hold ends (contract in the server instructions; wait_seconds bounds it). A completed run includes the reply text and a url to its session; files the reply linked come back as absolute URLs in the text and as a "files" list, fetched with the same bearer token you called this tool with. A failed or cancelled run includes its cause, whether it is retryable, and an "error" object saying what happened, whether the work was charged and what to do next. Status "awaiting_input" includes the pending request for answer_pending_input. Once that request is answered, input_status reads "answered" and continuation_run_id names the run to poll next; "cancelled" or "expired" means the run will never resume, so stop polling it. Keep polling a non-terminal run at poll_after_seconds.

ParametersJSON Schema
NameRequiredDescriptionDefault
waitNoWhen true, wait for a terminal result or human input (see this tool's description for how long the hold lasts). After this tool returns, continue polling while status is non-terminal; it cannot wake an idle client.
run_idYesThe run id returned by invoke_agent.
agent_idYesThe agent's UUID.
wait_secondsNoOptional: how many seconds to wait when wait=true (maximum 1800). Omit to use the window your MCP client can hold.

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNoA deep link to this run's session in the plori web app.
hintNoWhat to do next with this run, in one sentence. Present only while the run is non-terminal.
textNoThe assistant's reply once the run has finished. While a run is still going this is the run's own status message, not an answer, and is often absent — read last_worklog and last_tool_step instead.
causeNoMachine-readable cause for a non-normal terminal state.
errorNoWhy a terminal error or cancelled run failed, whether it was charged and what to do about it. Absent for a run that is still going or that finished normally.
filesNoFiles on the agent's disk that this reply linked, in the order they appear. Each url is fetchable with the bearer token you called this tool with. Absent when the reply linked none.
run_idYesThe public run identifier.
statusYesThe current run status.
tokensNoAttributed token count; null when attribution is unavailable.
advisorNoAdvisor calls used and allowed, spend this turn, and its optional spend cap in micro-US-dollars.
creditsNoAttributed spend in micro-US-dollars; null when attribution is unavailable.
ended_atNoWhen the run reached a terminal state.
retryableNoWhether sending the same message again could plausibly succeed. False for a cause the same request would hit again, including time_limit — split the work or raise max_turn_seconds instead of retrying it unchanged.
session_idYesThe durable conversation/session identifier.
started_atNoWhen the run started.
stop_reasonNoController-selected stop reason, when present.
input_statusNoThe durable status of this run's human-input request, when it has one: pending, answered, cancelled or expired. cancelled and expired are terminal — that run will never resume, so stop polling it.
last_worklogNoThe agent's most recent one-sentence note about what it is doing, from the run's durable event log. Absent for a terminal result and for a run that has written none.
input_expiredNoTrue when this run is parked on a question its session has already moved past: a later run in the same conversation has completed. Do not answer it; start a new run instead.
poll_after_msNoLegacy spelling of poll_after_seconds in milliseconds; the two always agree. Prefer poll_after_seconds.
resume_run_idNoThe exact auto-resume successor for an interrupted run; poll this run next.
resume_statusNoAuto-resume disposition for an interrupted run: pending, resumed, failed, or unknown.
tool_progressNoDurable tool execution progress; absent when this run has no tool-progress telemetry.
usage_by_roleNoAttributed spend, tokens, and model-call counts split into executor, advisor, and reviewer roles.
last_tool_stepNoWhat this run last did with a tool: "running <tool>" while a call is in flight, otherwise "completed <tool>" for the most recent finished call. Absent for a terminal result and for a run with no tool-progress telemetry.
pending_inputsNoHuman inputs blocking an awaiting_input run.
elapsed_secondsNoSeconds since the run started; absent for a terminal result.
upstream_statusNoThe model provider's HTTP status when this run died on an upstream fault; absent otherwise.
last_activity_atNoWhen the run last wrote a note or finished a tool call. Absent for a terminal result and for a run that has done neither.
last_heartbeat_atNoMost recent durable executor heartbeat.
poll_after_secondsNoSuggested seconds before polling again, paced to this run's recent tool-completion rate; absent for a terminal result.
continuation_run_idNoThe exact continuation created for an answered input; poll this run next.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description is exceptionally detailed: it discloses the wait hold contract, terminal vs non-terminal states, error objects, retryability, file URL auth behavior, and the input_status lifecycle. Annotations signal destructive/open-world behavior, and the description doesn't contradict them, though it doesn't elaborate on what destructive side effect might exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long but dense and well-structured: core result fields come first, then wait behavior, then state-specific outputs, then polling guidance. Every sentence carries operational value with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex polling tool with an output schema, the description is complete: it covers success, failure, cancellation, awaiting input, authentication, file URLs, retryability, and polling cadence. An agent can correctly invoke and interpret results without needing additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds real meaning by explaining the wait hold contract, wait_seconds bound, and how agent_id/run_id relate to invoke_agent. It also clarifies the polling semantics of wait=true and the 'cannot wake an idle client' limitation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Get') and enumerates exactly what is returned: status, timing, credits, tokens, worklog, tool steps, activity, and progress. It clearly focuses on a single run's result, distinguishing it from sibling tools like list_runs, invoke_agent, and cancel_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit polling instructions ('Keep polling a non-terminal run at poll_after_seconds') and explains when to stop polling ('cancelled' or 'expired' means never resume). It also explains wait=true vs the client-held window, and implies that answer_pending_input is the path for 'awaiting_input', though it doesn't explicitly name the alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_usageGet usageA
Read-only
Inspect

Get the authenticated account's usage rollup (US-dollar spend by role, meter, and agent, with recent runs). Use this to answer where the money went; for the current balance use get_credits.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
toolsYes
agentsYes
totalsYes
by_kindYes
by_roleYes
workflowsYes
recent_runsYes
workflow_executionsYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, and the description adds useful behavior beyond that: the data is scoped to the authenticated account, aggregated as a rollup, and includes spend dimensions plus recent runs. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with no filler. The core purpose and included breakdown are front-loaded, and the sibling distinction is delivered in the second sentence without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with an output schema, the description provides all essential context: account scope, aggregation type, spend dimensions, and when to choose a different tool. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing for the description to clarify. Per the rubric, a zero-parameter tool gets a baseline of 4; the description correctly focuses on the output semantics instead.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') with a clear resource: the authenticated account's usage rollup. It further specifies the breakdown ('US-dollar spend by role, meter, and agent') and 'recent runs', making its purpose distinct from the sibling get_credits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use this tool: 'Use this to answer where the money went.' It also names the alternative for a different need: 'for the current balance use get_credits.' This is clear routing with no inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workflowGet workflowA
Read-only
Inspect

Get one workflow's metadata and step projection. The projection is the version pinned for execution (active_version), falling back to current_version for a draft that has not been activated.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflow_idYesThe workflow's UUID (from list_workflows or create_workflow).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
engineYes
statusYes
user_idYes
agent_idYes
hook_keyYes
cron_exprYes
created_atYes
projectionYesArbitrary JSON owned by the producing engine.
updated_atYes
descriptionYes
notify_prefYes
next_fire_atYes
trigger_kindYes
paused_reasonNo
template_slugNo
active_versionYes
current_versionYes
spend_cap_monthYes
agent_deleted_atNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the agent knows it is a safe read operation. The description adds valuable behavioral context: it explains the projection selection logic (active_version pinned for execution, with current_version fallback for drafts), which goes beyond the annotation and helps the agent understand what data will be returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero redundancy. The core purpose is front-loaded, followed by a clarifying explanation of the projection behavior. Every word earns its place, making it exceptionally concise and structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a single parameter, full schema coverage, presence of an output schema, and annotations covering the read-only safety profile, the description covers all essential aspects. The fallback logic for projections is explained, and nothing an agent needs to call the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameter 'workflow_id' is fully documented in the schema, including its source (list_workflows or create_workflow). The tool description adds no additional parameter guidance beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('one workflow's metadata and step projection'), and the projection is clearly defined. It distinguishes itself from siblings like list_workflows (which lists all) and get_workflow_version (which fetches a specific version) by focusing on the active execution projection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly indicates when to use this tool (to retrieve metadata and the projection used for execution) and provides context on the projection fallback behavior. It does not explicitly name alternatives or exclusions, but the sibling list and context imply use cases, so it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workflow_executionGet workflow executionA
Read-only
Inspect

Get one workflow execution's status, billing, timing, credits, and full persisted per-step input/output payloads. fault explains why a non-succeeded execution ended. user means the workflow's own steps or limits. A platform fault is never billed. fault is null when the execution succeeded. billed is the billing flag. Use this tool to poll a run or inspect each step. list_workflow_executions omits step payloads.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflow_idYesThe workflow's UUID.
execution_idYesThe execution's UUID (from run_workflow).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
errorNoArbitrary JSON owned by the producing engine.
faultYesWhy a non-succeeded execution ended. User means the workflow's own steps or limits. A platform fault is never billed. This field is null when the execution succeeded.
stepsNoArbitrary JSON owned by the producing engine.
billedYesThe billing flag. True only for a user-fault succeeded, failed, or timed-out execution.
statusYes
creditsYes
ended_atYes
created_atYes
started_atYes
step_statsNoArbitrary JSON owned by the producing engine.
duration_msYes
workflow_idYes
trigger_sourceYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint=true, and the description aligns with that. It adds valuable behavioral context beyond the annotations: fault semantics (user vs platform), billing implications (platform fault is never billed), and that fault is null on success. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main purpose is front-loaded in the first sentence, and subsequent sentences efficiently explain fault and billing semantics. The only slight redundancy is 'billed is the billing flag,' which adds marginal value, but overall the description is tight and information-dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description does not need to document return fields. It covers fault behavior, billing semantics, usage scenarios, and how it differs from a sibling tool. Nothing an agent needs to invoke the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters clearly. The description confirms the tool targets a single execution and references run_workflow, but it adds no new parameter-level syntax or format details. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the action 'Get' and the specific resource 'one workflow execution', enumerating the returned dimensions (status, billing, timing, credits, per-step payloads). It also distinguishes the tool from list_workflow_executions by noting that the sibling omits step payloads, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage guidance: 'Use this tool to poll a run or inspect each step.' It also names the relevant alternative, list_workflow_executions, and explains the key difference (omits step payloads), effectively telling the agent when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workflow_versionGet workflow versionA
Read-only
Inspect

Get one exact workflow version, including its full builder definition with step parameter values and its value-light projection. Use current_version from get_workflow unless you intentionally need an older version.

ParametersJSON Schema
NameRequiredDescriptionDefault
versionYesThe positive version number to retrieve.
workflow_idYesThe workflow's UUID.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
authorYes
versionYes
created_atYes
definitionNoArbitrary JSON owned by the producing engine.
projectionNoArbitrary JSON owned by the producing engine.
chat_run_idYes
workflow_idYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safe read behavior is covered. The description adds useful behavioral context by specifying exactly what the response includes—the full builder definition with step parameter values and the value-light projection—which goes beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The first states the core behavior and returned content, and the second gives routing guidance. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, two-parameter tool with complete schema descriptions and an output schema present, the description provides all needed calling context plus explicit guidance on when not to use it. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema fully documents both workflow_id and version. The description does not add new parameter-level detail beyond the schema, which matches the baseline expectation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Get one exact workflow version' and explains what is included ('full builder definition with step parameter values and its value-light projection'). It also distinguishes itself from get_workflow by referencing 'current_version', so an agent can disambiguate the sibling tools without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool versus the alternative: 'Use current_version from get_workflow unless you intentionally need an older version.' This gives a clear condition and names the alternative tool directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

invoke_agentInvoke agentA
Destructive
Inspect

Send a message to an agent and return its reply, or a "running" run_id to poll with get_run_result. Use it for work that should outlive a single request: files written now and read later, software installed once and reused, a repo kept checked out, or a long job handed off. The hold and polling contract is in the server instructions: wait=false returns the run_id at once, wait_seconds bounds the hold, and agent turns can take minutes. A running result reports last_worklog, last_tool_step and last_activity_at; a completed one carries the reply text, files, credits (micro-US-dollars) and tokens; every result carries session_id (pass it back to continue the conversation) and a url a human can open. An account's plan caps how many runs it may have in flight at once across all its agents: over the cap returns 429, so wait for a run to finish and retry; turns on one agent are not queued for you. Pass idempotency_key when you might retry, or the retry starts and bills a second run. A run that pauses for a human returns status "awaiting_input" with the request inline; answer it with answer_pending_input. Cost scales with how much the agent has to explore: name the exact resources, fields and output format you want, and set max_turn_tokens for a bounded lookup.

ParametersJSON Schema
NameRequiredDescriptionDefault
waitNoWait for the turn and return the reply (default true); the hold lasts as long as your client keeps the call open, or wait_seconds. Set false to return a run_id immediately and poll get_run_result — prefer this for long or tool-heavy turns so the call doesn't block your own turn.
messageYesThe message to send to the agent.
agent_idYesThe agent's UUID.
session_idNoOptional thread/session id to continue an existing conversation (a previous invoke_agent or get_run_result result carries it as "session_id"); omit to start a new one.
callback_urlNoOptional callback URL for this run. Must use http or https and resolve only to public addresses.
wait_secondsNoOptional: how many seconds to wait for the turn before returning a "running" run_id (maximum 1800). Omit to use the window your MCP client can hold. Ignored when wait=false.
callback_secretNoOptional secret used to sign callback deliveries with HMAC-SHA256.
idempotency_keyNoOptional retry guard: a string you generate for this attempt. Re-sending the same key with the same agent and message within 24h returns the ORIGINAL run instead of starting a second one. Reusing a key with a different message is an error.
max_turn_tokensNoOptional cumulative cache-weighted token ceiling for this turn. 0 or omitted uses the agent's default of 2,000,000; the maximum is 5,000,000. The agent reserves its final 2% for a tool-free wrap-up.
max_turn_secondsNoOptional soft wall-clock budget for this turn in seconds, maximum 14,400. 0 or omitted uses the deployment's configured default, and where none is configured a turn has no wall-clock budget at all. It schedules an in-loop checkpoint and does not cancel the run.
max_advisor_spend_micro_usdNoOptional maximum advisor-completion spend for this turn in micro-US-dollars. 0 disables advisor completions. Omit it to use the agent setting; when neither is set, at most two advisor calls can run. The maximum is 5,000,000.

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNoA deep link to this run's session in the plori web app.
hintNoWhat to do next with this run, in one sentence. Present only while the run is non-terminal.
textNoThe assistant's reply once the run has finished. While a run is still going this is the run's own status message, not an answer, and is often absent — read last_worklog and last_tool_step instead.
causeNoMachine-readable cause for a non-normal terminal state.
errorNoWhy a terminal error or cancelled run failed, whether it was charged and what to do about it. Absent for a run that is still going or that finished normally.
filesNoFiles on the agent's disk that this reply linked, in the order they appear. Each url is fetchable with the bearer token you called this tool with. Absent when the reply linked none.
run_idYesThe public run identifier.
statusYesThe current run status.
tokensNoAttributed token count; null when attribution is unavailable.
advisorNoAdvisor calls used and allowed, spend this turn, and its optional spend cap in micro-US-dollars.
creditsNoAttributed spend in micro-US-dollars; null when attribution is unavailable.
ended_atNoWhen the run reached a terminal state.
retryableNoWhether sending the same message again could plausibly succeed. False for a cause the same request would hit again, including time_limit — split the work or raise max_turn_seconds instead of retrying it unchanged.
session_idYesThe durable conversation/session identifier.
started_atNoWhen the run started.
stop_reasonNoController-selected stop reason, when present.
input_statusNoThe durable status of this run's human-input request, when it has one: pending, answered, cancelled or expired. cancelled and expired are terminal — that run will never resume, so stop polling it.
last_worklogNoThe agent's most recent one-sentence note about what it is doing, from the run's durable event log. Absent for a terminal result and for a run that has written none.
input_expiredNoTrue when this run is parked on a question its session has already moved past: a later run in the same conversation has completed. Do not answer it; start a new run instead.
poll_after_msNoLegacy spelling of poll_after_seconds in milliseconds; the two always agree. Prefer poll_after_seconds.
resume_run_idNoThe exact auto-resume successor for an interrupted run; poll this run next.
resume_statusNoAuto-resume disposition for an interrupted run: pending, resumed, failed, or unknown.
tool_progressNoDurable tool execution progress; absent when this run has no tool-progress telemetry.
usage_by_roleNoAttributed spend, tokens, and model-call counts split into executor, advisor, and reviewer roles.
last_tool_stepNoWhat this run last did with a tool: "running <tool>" while a call is in flight, otherwise "completed <tool>" for the most recent finished call. Absent for a terminal result and for a run with no tool-progress telemetry.
pending_inputsNoHuman inputs blocking an awaiting_input run.
elapsed_secondsNoSeconds since the run started; absent for a terminal result.
upstream_statusNoThe model provider's HTTP status when this run died on an upstream fault; absent otherwise.
last_activity_atNoWhen the run last wrote a note or finished a tool call. Absent for a terminal result and for a run that has done neither.
last_heartbeat_atNoMost recent durable executor heartbeat.
poll_after_secondsNoSuggested seconds before polling again, paced to this run's recent tool-completion rate; absent for a terminal result.
continuation_run_idNoThe exact continuation created for an answered input; poll this run next.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only indicate safety hints; the description adds extensive behavioral detail: async return modes, rate cap semantics, idempotency with cost implications, human-pause status, and cost scaling. This goes far beyond the annotations and gives the agent a realistic model of how the tool behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but this is an 11-parameter, complex tool with async semantics; nearly every sentence carries unique guidance. It is front-loaded with the core action and use cases, though the 'server instructions' mention and some redundancy with schema details keep it from a perfect conciseness score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a rich output schema and this description, nothing essential is missing: the agent knows the full workflow (invoke, poll, resume, handle human input), the result shape (running vs. completed), rate limits, idempotency, and cost factors. The addition of a human-readable URL and session continuity further completes the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds strategic context beyond the schema for wait, wait_seconds, idempotency_key, session_id, and max_turn_tokens (e.g., 'the retry starts and bills a second run', 'set max_turn_tokens for a bounded lookup'). This elevates parameter understanding beyond mere field definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource: 'Send a message to an agent and return its reply, or a "running" run_id to poll with get_run_result.' It clearly identifies the tool's core action and scope, and the mention of get_run_result and answer_pending_input helps distinguish it from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to use this tool: 'Use it for work that should outlive a single request' with concrete examples. It also names alternatives for follow-up actions (get_run_result for polling, answer_pending_input for human pauses) and warns about rate limiting and retry behavior, leaving no ambiguity about when to choose this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_agentsList agentsA
Read-only
Inspect

List the agents owned by the authenticated account, newest first, with each one's model, live session status, web page url and when it last ran. An agent whose model is empty is not unconfigured: effective_model says what a run will use, and plori-auto means the hosted router chooses per turn.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
itemsYesThe returned items, in the endpoint's documented order.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds meaningful behavioral detail: results are returned newest first, include a live session status and web page URL, and there is a non-obvious semantic distinction between an empty model and effective_model, including what plori-auto means. This is genuinely useful interpretive context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, each earning its place. The first sentence front-loads the action, scope, ordering, and output fields; the second adds an important caveat about interpreting the model field. No fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless read-only listing operation with an output schema available, the description is complete: it covers the scope, ordering, returned fields, and a key edge-case nuance. Nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters and schema coverage is 100%, so there is no parameter documentation burden. The description appropriately focuses on output semantics rather than parameters, earning the baseline 4 for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List'), names the resource ('agents'), and scopes it to the authenticated account. It also reveals the ordering ('newest first') and the returned fields, which clearly distinguishes it from sibling tools like get_agent, list_runs, and list_workflows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is implied: call this when you need to list the account's agents. It does not explicitly contrast itself with get_agent or mention when not to use it, but the simple resource-oriented phrasing makes the primary use case reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_connectionsList connectionsA
Read-only
Inspect

List the authenticated account's third-party OAuth connections, including each provider's status, authorization and expiry times, and configured scopes. Read needs_reauth for whether a human has to go and reconnect one; status is the same fact spelled out (authorized needs no action, reconnect_needed and unauthorized do). Never derive it from expires_at: tokens refresh lazily when used, so an authorized row may have a past expires_at, and authorized with expires_at=null means the grant never expires. Token and client-secret material is never returned.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
connectionsYesThird-party OAuth connection status records; never secret material.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds vital behavioral nuance: it explains how to interpret needs_reauth vs status, warns against deriving status from expires_at due to lazy token refresh, and explicitly states that token/client-secret material is never returned. This is exactly the kind of context an agent needs to use the response correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, then adds concise but important behavioral caveats. Every sentence earns its place, and the warning about expires_at is structured as actionable guidance rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the zero parameters, the readOnlyHint annotation, and the presence of an output schema, the description covers all relevant aspects an agent needs: what is returned, how to interpret ambiguous fields, and what is never returned. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema documents all of them (100% coverage), so there is no gap to compensate for. The baseline for a zero-parameter tool is 4, and the description has no need to add parameter-specific meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and a precise resource ('the authenticated account's third-party OAuth connections'), and enumerates the returned fields. This clearly distinguishes it from sibling tools like list_agents or list_runs, even though no sibling is named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The first sentence provides clear context for when to call the tool: when you need a read-only view of the account's OAuth connections. It does not explicitly contrast with alternatives, but the resource is unambiguous and no closely related sibling exists, so the usage context is clear without formal exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pending_inputsList pending questionsA
Read-only
Inspect

List the agent's runs that are paused awaiting a human approval or input (the HITL queue). A row with a "consent_tool" is a write-consent approval: answering it with always_allow=true also stops the agent asking for that tool, and scope="thread" allows only the rest of this conversation's calls to the same connection, method and host. A request whose session has already moved on is not listed: a later run in that conversation has completed, so answering it would resume a superseded turn.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYesThe agent's UUID.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pending_inputsYesRuns currently parked on a human approval or input request. A request whose session has already moved on is left out: answering it would resume a superseded turn.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description explains significant behaviors: it lists only paused runs, it includes consent_tool approval semantics with always_allow=true and scope='thread', and it explicitly notes that stale/superseded requests are omitted. This provides actionable detail that annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and information-dense, with the core purpose stated first and important behavioral caveats following. Every sentence adds meaningful value, and the length is appropriate for the complexity of the HITL semantics being explained.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single parameter, the presence of an output schema, and the readOnlyHint annotation, the description covers the essential context for correct use: what is listed, what the consent_tool rows mean, and how stale requests are handled. No critical operational questions remain unanswered for an agent invoking this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, agent_id, is fully described in the schema as 'The agent's UUID.' The description adds minimal interpretive value beyond implying the tool lists runs for a given agent, so it meets the baseline for high schema coverage without adding much new semantic insight.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and a well-defined resource ('the agent's runs that are paused awaiting a human approval or input'), clearly identifying this as the HITL queue listing tool. This distinguishes it from related tools like answer_pending_input by focusing on listing pending items rather than resolving them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context about what the tool returns and even explains when requests are excluded (if the session has moved on). It does not explicitly name sibling alternatives or state 'use this instead of X', but the domain is straightforward enough that an agent can infer when listing pending inputs is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_runsList runsA
Read-only
Inspect

List an agent's run history, most recently STARTED first, with each run's status, timing and attributed cost. Returns the newest 20 runs unless you pass limit (maximum 100). When more history exists the result carries next_cursor; pass it back as cursor for the next page, and stop when it is absent. Each row's session_id (the same value as thread_id) continues that conversation through invoke_agent. tool_progress is null for a terminal run and for a run with no telemetry; a non-terminal row reports the same progress get_run_result does. A row with input_expired is parked on a question its session has already moved past — start a new run rather than answering it.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many runs to return, newest first (default 20, maximum 100).
cursorNoThe next_cursor from a previous list_runs result, to continue where it stopped. Omit for the newest page.
agent_idYesThe agent's UUID.

Output Schema

ParametersJSON Schema
NameRequiredDescription
itemsYesOne page of the agent's runs, most recently started first.
next_cursorNoPass this back as cursor to read the next page. Absent when this page is the end of the history.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnly=true, but the description richly discloses additional behavior: newest-first ordering, default/maximum limit, cursor pagination, null tool_progress semantics, the session_id/thread_id equivalence, and input_expired handling. This goes well beyond what annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficient and front-loaded with the core purpose. Each subsequent sentence covers a distinct operational concern such as pagination, session continuation, progress reporting, or terminal-state edge cases—no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering read-only behavior, the description still supplies all practical details needed to use the tool correctly: ordering, limits, cursor flow, session continuation, null fields, and a caution about input_expired rows. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds meaningful context beyond the schema: the default page size, the instruction to pass next_cursor back as cursor, when to stop paginating, and the semantic meaning of row fields like session_id and input_expired. These details materially help an agent call the tool correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource ('an agent's run history'), the action ('List'), and the ordering ('most recently STARTED first'). It also distinguishes this from sibling list tools by specifying run-level details like status, timing, cost, and pagination.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear procedural guidance for pagination ('pass it back as cursor... stop when it is absent') and explains when to continue a session via invoke_agent. It references get_run_result for progress semantics but does not explicitly state when to prefer list_runs over that sibling, so it falls just short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_workflow_executionsList workflow executionsA
Read-only
Inspect

List a workflow's recent executions, most recent first. Each record includes status, fault, billing, trigger source, timing, credits, and timestamps. fault explains why a non-succeeded execution ended. user means the workflow's own steps or limits. A platform fault is never billed. fault is null when the execution succeeded. billed is the billing flag.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflow_idYesThe workflow's UUID (from list_workflows or create_workflow).

Output Schema

ParametersJSON Schema
NameRequiredDescription
executionsYesRecent workflow executions, most recent first.

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, and the description does not contradict this. It adds valuable behavioral context by explaining fault semantics (null on success, platform faults never billed) and the billed flag, which goes beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, front-loads the core purpose, and then adds useful field semantics without unnecessary verbosity. It is well-structured and easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values. It covers key field meanings and ordering, which is sufficient for a simple list tool. Minor gaps like pagination limits are not addressed but are not critical here.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The sole parameter workflow_id is fully described in the schema with a clear source hint. The description adds no further parameter-specific meaning, so it stays at the baseline of 3 given the high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists a workflow's recent executions, most recent first. It specifies the resource (workflow executions) and the action (list). It does not explicitly differentiate from the sibling get_workflow_execution, but the purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as get_workflow_execution. It does not mention any conditions for choosing this over other listing or retrieval tools, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_workflowsList workflowsA
Read-only
Inspect

List the workflows owned by the authenticated account, with each one's status, trigger, current version, and the agent that holds it (agent_id). Each workflow belongs to one agent — the one that built it — and that agent is the only one that can edit or run it from a chat. Pass agent_id to list just that agent's workflows, or agent_id="none" for the unassigned ones (created here or in the web app with no agent).

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idNoOptional: a UUID of one of your agents to list only its workflows, or "none" for the unassigned ones.

Output Schema

ParametersJSON Schema
NameRequiredDescription
workflowsYesWorkflows visible to the authenticated account and optional agent filter.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description doesn't need to restate that. It adds valuable behavioral context: each workflow is bound to a single agent who is the only one that can edit or run it from chat, and explains the 'none' semantics. This goes beyond the schema and annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is reasonably concise and front-loads the primary purpose and return fields. The ownership explanation is valuable and not excessive. It could be trimmed slightly, but it is well-structured and every sentence contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values are already covered. The description covers key aspects: what is listed, the ownership constraint, and parameter usage. It does not mention pagination or ordering, but for a list tool with an output schema, that is a minor gap. Overall, it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents agent_id. The description enriches the parameter by explaining the ownership model and the special 'none' case, giving an agent deeper understanding of the parameter's purpose beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the exact action ('list the workflows owned by the authenticated account') and enumerates the returned fields (status, trigger, current version, agent_id). It clearly distinguishes from sibling tools like list_runs and get_workflow by focusing on workflow ownership and listing behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains when to pass agent_id and the special 'none' value for unassigned workflows, and it mentions that each workflow belongs to one agent. It does not explicitly contrast with alternatives like get_workflow or list_workflow_executions, but the context is clear enough for an agent to decide when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_workflowRun workflowA
Destructive
Inspect

Run a workflow now — a real execution with real side effects, billed like any run (a flat per-execution fee plus model usage). Waits briefly and returns the execution: terminal if it finished, else status "running" to poll with get_workflow_execution. The workflow must already have steps.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflow_idYesThe workflow's UUID (from list_workflows or create_workflow).
trigger_payloadNoOptional sample input to hand the trigger (useful for a webhook workflow: run it with a sample body).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
errorNoArbitrary JSON owned by the producing engine.
faultYesWhy a non-succeeded execution ended. User means the workflow's own steps or limits. A platform fault is never billed. This field is null when the execution succeeded.
stepsNoArbitrary JSON owned by the producing engine.
billedYesThe billing flag. True only for a user-fault succeeded, failed, or timed-out execution.
statusYes
creditsYes
ended_atYes
created_atYes
started_atYes
step_statsNoArbitrary JSON owned by the producing engine.
duration_msYes
workflow_idYes
trigger_sourceYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable context beyond the annotations: it discloses billing ('billed like any run...'), the wait-and-return behavior, and the terminal vs 'running' status distinction. It does not contradict the annotations (destructiveHint=true, readOnlyHint=false), and the added details meaningfully inform an agent of side effects and polling needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two dense sentences that front-load purpose and billing, then explain behavior and precondition. Every sentence earns its place; there is no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, side effects, billing, wait behavior, polling alternative, and a precondition. With an output schema present and full schema coverage, nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (workflow_id and trigger_payload) are fully documented in the schema. The description does not add new parameter-level detail, but it does set a precondition ('must already have steps') that is a prerequisite rather than a parameter attribute. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action ('Run a workflow now') and distinguishes it from a mere preview by emphasizing 'real execution with real side effects.' It also differentiates from polling via get_workflow_execution, making the tool's unique purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says to poll with get_workflow_execution if the execution is still running, and it states the prerequisite that the workflow must already have steps. However, it does not contrast with schedule_run or other run-related alternatives, so the 'when-not' guidance is incomplete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schedule_runSchedule agent runA
Destructive
Inspect

Schedule a ONE-SHOT deferred run of an agent: it will be invoked once, later, with the given prompt, billed like any run, and appears in list_runs when it fires. Provide either delay_seconds (relative) or fire_at (an RFC3339 timestamp). For a recurring schedule, use create_workflow with a cron trigger instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
promptYesThe message to send the agent when the schedule fires.
fire_atNoFire at this RFC3339 timestamp (mutually exclusive with delay_seconds).
agent_idYesThe agent's UUID.
session_idNoOptional thread/session id to deliver the scheduled run into.
delay_secondsNoFire this many seconds from now (mutually exclusive with fire_at).

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
kindYes
promptYes
statusYes
fire_atNo
agent_idYes
attemptsYes
metadataNoArbitrary JSON owned by the producing engine.
thread_idNo
created_atYes
last_errorNo
last_fired_atNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the run is invoked once, later, billed like any run, and appears in list_runs when it fires. These side effects go beyond the annotations, though the destructiveHint=true annotation is not clarified; this is a minor gap, not a contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the tool's core purpose, and every sentence adds useful information: one-shot semantics, side effects, timing options, and the sibling alternative. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 100% schema coverage, an output schema, and annotations, the description covers the remaining operational context: what kind of run it schedules, how it is billed/visible, how to express the time, and when to use an alternative.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all five parameters and their mutual exclusivity, so the description adds little parameter-specific meaning beyond reinforcing 'either delay_seconds or fire_at.' This is the appropriate baseline for a 100% schema-coverage tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Schedule a ONE-SHOT deferred run of an agent.' It also differentiates from recurring schedules by explicitly naming create_workflow with a cron trigger as the alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent when to use this tool (one-shot deferred run) and when not to (recurring schedules: 'use create_workflow with a cron trigger instead'). It also clarifies the two timing options, delay_seconds or fire_at.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_workflow_agentSet workflow agentA
Idempotent
Inspect

Assign one of your agents to a workflow. Use this after delete_agent reports paused workflows, or when run_workflow returns workflow_agentless. If base_version is omitted, this tool reads the workflow's current version before it assigns the agent. A supplied stale base_version is rejected with the current version.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idYesThe UUID of one of your agents to assign.
workflow_idYesThe workflow's UUID.
base_versionNoOptional workflow current_version to compare before assignment. Omit it to use the current version.

Output Schema

ParametersJSON Schema
NameRequiredDescription
statusYesA short confirmation of the assignment.
versionYesThe workflow current_version checked for this assignment.
agent_idYesThe account-owned agent assigned to the workflow.
workflow_idYesThe workflow whose agent changed.
agent_deleted_atYesAlways null after assigning an agent: the workflow is no longer marked agentless.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description explains important behavior: when base_version is omitted, the tool reads the workflow's current version, and a stale base_version is rejected with the current version. This adds meaningful concurrency semantics not captured by readOnlyHint or idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences cover purpose, usage triggers, and the key concurrency nuance with no wasted words. The most actionable information is front-loaded in the first sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that annotations convey idempotency and non-destructiveness, and an output schema exists, the description adequately covers when to use the tool, how the version check behaves, and what to expect on stale versions. No critical information for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds extra semantic value by explaining the stale base_version rejection behavior and clarifying what happens when base_version is omitted, which goes beyond the schema's brief parameter text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Assign one of your agents to a workflow.' It also provides concrete trigger scenarios, making the tool's purpose unmistakable and distinct from sibling operations like create_workflow or edit_workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage triggers: 'Use this after delete_agent reports paused workflows, or when run_workflow returns workflow_agentless.' It clearly indicates when to use the tool, though it does not mention when not to use it or suggest an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.16.2
    • Changedcreate_agent2 fields changed
      • addedOutput schema / properties / advisor_max_spend_micro_usd
        Added value: +{
        +  "description": "Optional maximum advisor-completion spend per turn in micro-US-dollars. Zero disables advisor completions; null leaves no spend cap.",
        +  "type": [
        +    "null",
        +    "integer"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "user_id",
        -  "name",
        -  "backend",
        -  "model",
        -  "effective_model",
        -  "config",
        -  "created_at"
        -]New value: +[
        +  "id",
        +  "user_id",
        +  "name",
        +  "backend",
        +  "model",
        +  "advisor_max_spend_micro_usd",
        +  "effective_model",
        +  "config",
        +  "created_at"
        +]
    • Changedget_agent2 fields changed
      • addedOutput schema / properties / advisor_max_spend_micro_usd
        Added value: +{
        +  "description": "Optional maximum advisor-completion spend per turn in micro-US-dollars. Zero disables advisor completions; null leaves no spend cap.",
        +  "type": [
        +    "null",
        +    "integer"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "user_id",
        -  "name",
        -  "backend",
        -  "model",
        -  "effective_model",
        -  "config",
        -  "created_at",
        -  "mailbox"
        -]New value: +[
        +  "id",
        +  "user_id",
        +  "name",
        +  "backend",
        +  "model",
        +  "advisor_max_spend_micro_usd",
        +  "effective_model",
        +  "config",
        +  "created_at",
        +  "mailbox"
        +]
    • Changedget_run_result3 fields changed
      • addedOutput schema / properties / advisor
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Advisor calls used and allowed, spend this turn, and its optional spend cap in micro-US-dollars.",
        +  "properties": {
        +    "calls_allowed": {
        +      "type": "integer"
        +    },
        +    "calls_used": {
        +      "type": "integer"
        +    },
        +    "spend_cap_micro_usd": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "spend_micro_usd": {
        +      "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "calls_used",
        +    "calls_allowed",
        +    "spend_micro_usd"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / error / properties / upgrade
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Which plan lifts the limit this run ended at, when it ended at one.",
        +  "properties": {
        +    "anonymous": {
        +      "type": "boolean"
        +    },
        +    "limit": {
        +      "type": "string"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "offer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "discount_code": {
        +          "type": "string"
        +        },
        +        "first_period_price_micro_usd": {
        +          "type": "integer"
        +        },
        +        "message": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "discount_code",
        +        "first_period_price_micro_usd",
        +        "message"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "plan": {
        +      "type": "string"
        +    },
        +    "remedies": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "kind": {
        +            "type": "string"
        +          },
        +          "limits": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "disk_gb": {
        +                "type": "integer"
        +              },
        +              "max_active_workflows": {
        +                "type": "integer"
        +              },
        +              "max_agents": {
        +                "type": "integer"
        +              },
        +              "max_concurrent_runs": {
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "max_concurrent_runs",
        +              "max_agents",
        +              "max_active_workflows",
        +              "disk_gb"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "offer": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "discount_code": {
        +                "type": "string"
        +              },
        +              "first_period_price_micro_usd": {
        +                "type": "integer"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "discount_code",
        +              "first_period_price_micro_usd",
        +              "message"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "plan": {
        +            "type": "string"
        +          },
        +          "url": {
        +            "type": "string"
        +          },
        +          "usd_cents_per_month": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "limit",
        +    "plan",
        +    "message",
        +    "remedies"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / usage_by_role
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Attributed spend, tokens, and model-call counts split into executor, advisor, and reviewer roles.",
        +  "properties": {
        +    "advisor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "executor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "reviewer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "executor",
        +    "advisor",
        +    "reviewer"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
    • Changedget_usage11 fields changed
      • addedOutput schema / properties / by_role
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "advisor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "executor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "reviewer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "executor",
        +    "advisor",
        +    "reviewer"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / advisor
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +  "properties": {
        +    "calls_allowed": {
        +      "type": "integer"
        +    },
        +    "calls_used": {
        +      "type": "integer"
        +    },
        +    "spend_cap_micro_usd": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "spend_micro_usd": {
        +      "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "calls_used",
        +    "calls_allowed",
        +    "spend_micro_usd"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / credits / description
        Added value: +"The net charge after any refund."
      • addedOutput schema / properties / recent_runs / items / properties / error / properties / upgrade
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Which plan lifts the limit this run ended at, when it ended at one.",
        +  "properties": {
        +    "anonymous": {
        +      "type": "boolean"
        +    },
        +    "limit": {
        +      "type": "string"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "offer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "discount_code": {
        +          "type": "string"
        +        },
        +        "first_period_price_micro_usd": {
        +          "type": "integer"
        +        },
        +        "message": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "discount_code",
        +        "first_period_price_micro_usd",
        +        "message"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "plan": {
        +      "type": "string"
        +    },
        +    "remedies": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "kind": {
        +            "type": "string"
        +          },
        +          "limits": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "disk_gb": {
        +                "type": "integer"
        +              },
        +              "max_active_workflows": {
        +                "type": "integer"
        +              },
        +              "max_agents": {
        +                "type": "integer"
        +              },
        +              "max_concurrent_runs": {
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "max_concurrent_runs",
        +              "max_agents",
        +              "max_active_workflows",
        +              "disk_gb"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "offer": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "discount_code": {
        +                "type": "string"
        +              },
        +              "first_period_price_micro_usd": {
        +                "type": "integer"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "discount_code",
        +              "first_period_price_micro_usd",
        +              "message"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "plan": {
        +            "type": "string"
        +          },
        +          "url": {
        +            "type": "string"
        +          },
        +          "usd_cents_per_month": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "limit",
        +    "plan",
        +    "message",
        +    "remedies"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / recent_runs / items / properties / gross_micro_usd
        Added value: +{
        +  "description": "Gross consumption before any refund.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / refund_reason
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / refund_withheld_reason
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / refunded_micro_usd
        Added value: +{
        +  "description": "The refund reported once for this run.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / recent_runs / items / properties / usage_by_role
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Gross consumption by role; credits sum to gross_micro_usd and refunds appear only in refunded_micro_usd.",
        +  "properties": {
        +    "advisor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "executor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "reviewer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "executor",
        +    "advisor",
        +    "reviewer"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • changedOutput schema / properties / recent_runs / items / required
        Previous value: -[
        -  "id",
        -  "agent_id",
        -  "thread_id",
        -  "session_id",
        -  "status",
        -  "origin",
        -  "started_at",
        -  "credits",
        -  "tokens",
        -  "tool_progress"
        -]New value: +[
        +  "id",
        +  "agent_id",
        +  "thread_id",
        +  "session_id",
        +  "status",
        +  "origin",
        +  "started_at",
        +  "credits",
        +  "tokens",
        +  "advisor",
        +  "tool_progress"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "totals",
        -  "by_kind",
        -  "tools",
        -  "agents",
        -  "workflows",
        -  "workflow_executions",
        -  "recent_runs"
        -]New value: +[
        +  "totals",
        +  "by_role",
        +  "by_kind",
        +  "tools",
        +  "agents",
        +  "workflows",
        +  "workflow_executions",
        +  "recent_runs"
        +]
    • Changedinvoke_agent4 fields changed
      • addedInput schema / properties / max_advisor_spend_micro_usd
        Added value: +{
        +  "description": "Optional maximum advisor-completion spend for this turn in micro-US-dollars. 0 disables advisor completions. Omit it to use the agent setting; when neither is set, at most two advisor calls can run. The maximum is 5,000,000.",
        +  "maximum": 5000000,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / advisor
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Advisor calls used and allowed, spend this turn, and its optional spend cap in micro-US-dollars.",
        +  "properties": {
        +    "calls_allowed": {
        +      "type": "integer"
        +    },
        +    "calls_used": {
        +      "type": "integer"
        +    },
        +    "spend_cap_micro_usd": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "spend_micro_usd": {
        +      "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "calls_used",
        +    "calls_allowed",
        +    "spend_micro_usd"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / error / properties / upgrade
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Which plan lifts the limit this run ended at, when it ended at one.",
        +  "properties": {
        +    "anonymous": {
        +      "type": "boolean"
        +    },
        +    "limit": {
        +      "type": "string"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "offer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "discount_code": {
        +          "type": "string"
        +        },
        +        "first_period_price_micro_usd": {
        +          "type": "integer"
        +        },
        +        "message": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "discount_code",
        +        "first_period_price_micro_usd",
        +        "message"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "plan": {
        +      "type": "string"
        +    },
        +    "remedies": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "kind": {
        +            "type": "string"
        +          },
        +          "limits": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "disk_gb": {
        +                "type": "integer"
        +              },
        +              "max_active_workflows": {
        +                "type": "integer"
        +              },
        +              "max_agents": {
        +                "type": "integer"
        +              },
        +              "max_concurrent_runs": {
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "max_concurrent_runs",
        +              "max_agents",
        +              "max_active_workflows",
        +              "disk_gb"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "offer": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "discount_code": {
        +                "type": "string"
        +              },
        +              "first_period_price_micro_usd": {
        +                "type": "integer"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "discount_code",
        +              "first_period_price_micro_usd",
        +              "message"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "plan": {
        +            "type": "string"
        +          },
        +          "url": {
        +            "type": "string"
        +          },
        +          "usd_cents_per_month": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "limit",
        +    "plan",
        +    "message",
        +    "remedies"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / usage_by_role
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Attributed spend, tokens, and model-call counts split into executor, advisor, and reviewer roles.",
        +  "properties": {
        +    "advisor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "executor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "reviewer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "executor",
        +    "advisor",
        +    "reviewer"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
    • Changedlist_agents2 fields changed
      • addedOutput schema / properties / items / items / properties / advisor_max_spend_micro_usd
        Added value: +{
        +  "description": "Optional maximum advisor-completion spend per turn in micro-US-dollars. Zero disables advisor completions; null leaves no spend cap.",
        +  "type": [
        +    "null",
        +    "integer"
        +  ]
        +}
      • changedOutput schema / properties / items / items / required
        Previous value: -[
        -  "id",
        -  "user_id",
        -  "name",
        -  "backend",
        -  "model",
        -  "effective_model",
        -  "config",
        -  "created_at"
        -]New value: +[
        +  "id",
        +  "user_id",
        +  "name",
        +  "backend",
        +  "model",
        +  "advisor_max_spend_micro_usd",
        +  "effective_model",
        +  "config",
        +  "created_at"
        +]
    • Changedlist_runs9 fields changed
      • addedOutput schema / properties / items / items / properties / advisor
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +  "properties": {
        +    "calls_allowed": {
        +      "type": "integer"
        +    },
        +    "calls_used": {
        +      "type": "integer"
        +    },
        +    "spend_cap_micro_usd": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "spend_micro_usd": {
        +      "description": "Gross advisor consumption for the turn; the cap compares against this amount.",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "calls_used",
        +    "calls_allowed",
        +    "spend_micro_usd"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / items / items / properties / credits / description
        Added value: +"The net charge after any refund."
      • addedOutput schema / properties / items / items / properties / error / properties / upgrade
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Which plan lifts the limit this run ended at, when it ended at one.",
        +  "properties": {
        +    "anonymous": {
        +      "type": "boolean"
        +    },
        +    "limit": {
        +      "type": "string"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "offer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "discount_code": {
        +          "type": "string"
        +        },
        +        "first_period_price_micro_usd": {
        +          "type": "integer"
        +        },
        +        "message": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "discount_code",
        +        "first_period_price_micro_usd",
        +        "message"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "plan": {
        +      "type": "string"
        +    },
        +    "remedies": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "kind": {
        +            "type": "string"
        +          },
        +          "limits": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "disk_gb": {
        +                "type": "integer"
        +              },
        +              "max_active_workflows": {
        +                "type": "integer"
        +              },
        +              "max_agents": {
        +                "type": "integer"
        +              },
        +              "max_concurrent_runs": {
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "max_concurrent_runs",
        +              "max_agents",
        +              "max_active_workflows",
        +              "disk_gb"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "message": {
        +            "type": "string"
        +          },
        +          "offer": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "discount_code": {
        +                "type": "string"
        +              },
        +              "first_period_price_micro_usd": {
        +                "type": "integer"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "discount_code",
        +              "first_period_price_micro_usd",
        +              "message"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "plan": {
        +            "type": "string"
        +          },
        +          "url": {
        +            "type": "string"
        +          },
        +          "usd_cents_per_month": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "message"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "limit",
        +    "plan",
        +    "message",
        +    "remedies"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / items / items / properties / gross_micro_usd
        Added value: +{
        +  "description": "Gross consumption before any refund.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / items / items / properties / refund_reason
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / items / items / properties / refund_withheld_reason
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / items / items / properties / refunded_micro_usd
        Added value: +{
        +  "description": "The refund reported once for this run.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / items / items / properties / usage_by_role
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Gross consumption by role; credits sum to gross_micro_usd and refunds appear only in refunded_micro_usd.",
        +  "properties": {
        +    "advisor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "executor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    },
        +    "reviewer": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "calls": {
        +          "type": "integer"
        +        },
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "calls"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "executor",
        +    "advisor",
        +    "reviewer"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • changedOutput schema / properties / items / items / required
        Previous value: -[
        -  "id",
        -  "agent_id",
        -  "thread_id",
        -  "session_id",
        -  "status",
        -  "origin",
        -  "started_at",
        -  "credits",
        -  "tokens",
        -  "tool_progress"
        -]New value: +[
        +  "id",
        +  "agent_id",
        +  "thread_id",
        +  "session_id",
        +  "status",
        +  "origin",
        +  "started_at",
        +  "credits",
        +  "tokens",
        +  "advisor",
        +  "tool_progress"
        +]
  2. 26 tool updatesv0.16.0
    • Changedanswer_pending_input2 fields changed
      • addedInput schema / properties / scope
        Added value: +{
        +  "description": "Set to \"thread\" to approve AND allow the rest of this conversation's writes to the same connection, method and host, instead of a standing grant. It expires after 24 hours and covers no other host, method or conversation. Only set it when the human said to stop being asked for the rest of this task; ignored without approved=true, and on a card that has no such scope. Cannot be combined with always_allow.",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "already": {
        +      "description": "Whether this request had already been answered.",
        +      "type": "boolean"
        +    },
        +    "run_id": {
        +      "description": "The continuation run created by the answer.",
        +      "type": "string"
        +    },
        +    "session_id": {
        +      "description": "The continuation run's session.",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Answer status.",
        +      "type": "string"
        +    },
        +    "tool_call_id": {
        +      "description": "The pending tool call that was answered.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "status",
        +    "tool_call_id"
        +  ],
        +  "type": "object"
        +}
    • Changedcancel_run1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "runId": {
        +      "description": "The run whose cancellation was requested.",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Cancellation request status.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "runId",
        +    "status"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_agent2 fields changed
      • removedInput schema / properties / model
        Removed value: -{
        -  "description": "Optional model slug; omitted uses the Plori Router, which picks the cheapest model that fits each task from the pool the account's plan unlocks. An explicit frontier model still requires a paid plan.",
        -  "type": "string"
        -}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "backend": {
        +      "description": "The compute backend this Agent runs on.",
        +      "type": "string"
        +    },
        +    "config": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "created_at": {
        +      "description": "When the Agent was created.",
        +      "type": "string"
        +    },
        +    "deleting": {
        +      "description": "True while this Agent's disk is still being erased; offer no action on it besides retrying the deletion itself.",
        +      "type": "boolean"
        +    },
        +    "deleting_since": {
        +      "description": "When the deletion was first requested; present only while deleting is true.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "effective_model": {
        +      "description": "The model a run on this Agent will actually use. plori-auto means the hosted router chooses per turn.",
        +      "type": "string"
        +    },
        +    "existing": {
        +      "description": "Whether create_agent returned an existing same-name agent instead of creating one.",
        +      "type": "boolean"
        +    },
        +    "id": {
        +      "description": "The Agent's unique identifier; pass it to other tools as agent_id.",
        +      "type": "string"
        +    },
        +    "last_run_at": {
        +      "description": "When this Agent last started a run; absent when it has never run.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "model": {
        +      "description": "The model slug this Agent is configured to use. Empty means no explicit choice, which is not the same as no model — read effective_model for what a run will actually use.",
        +      "type": "string"
        +    },
        +    "moving": {
        +      "description": "True while this Agent's files are being copied to a new disk; check storage_notice rather than a separate route for the outcome.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "The Agent's name, chosen by its owner and unique within the account.",
        +      "type": "string"
        +    },
        +    "queued_at": {
        +      "description": "When a still-warming attach was accepted; present only while it is queued for node capacity.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "description": "The live warm-session state: warming, ready, or sleeping; empty when no session is active.",
        +      "type": "string"
        +    },
        +    "storage_notice": {
        +      "description": "The one sentence, if any, telling the owner about a storage move that stopped; show it verbatim, not paraphrased.",
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "This Agent's page in the plori web app.",
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "description": "The identifier of the account that owns this Agent.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "backend",
        +    "model",
        +    "effective_model",
        +    "config",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_workflow4 fields changed
      • changedInput schema / properties / cron_expr / description
        Previous value: -"Cron schedule (required when trigger_kind is \"cron\"), e.g. \"0 9 * * *\"."New value: +"Cron schedule (required when trigger_kind is \"cron\"), e.g. \"0 9 * * *\". A 5-field cron or an @daily/@hourly descriptor, evaluated in UTC."
      • changedInput schema / properties / description / description
        Previous value: -"Optional description of what the workflow does."New value: +"Optional description of what the workflow does. It is prose for the reader; no field is derived from it."
      • changedInput schema / properties / trigger_kind / description
        Previous value: -"Optional trigger: \"manual\" (default), \"cron\", or \"webhook\"."New value: +"Optional trigger: \"manual\" (default), \"cron\", or \"webhook\". The build can change it later: a schedule or webhook trigger step sets it."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "active_version": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "agent_deleted_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "agent_id": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "cron_expr": {
        +      "type": "string"
        +    },
        +    "current_version": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": "integer"
        +    },
        +    "description": {
        +      "type": "string"
        +    },
        +    "engine": {
        +      "type": "string"
        +    },
        +    "hook_key": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_fire_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "notify_pref": {
        +      "type": "string"
        +    },
        +    "paused_reason": {
        +      "type": "string"
        +    },
        +    "spend_cap_month": {
        +      "type": "integer"
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "template_slug": {
        +      "type": "string"
        +    },
        +    "trigger_kind": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "agent_id",
        +    "name",
        +    "description",
        +    "engine",
        +    "status",
        +    "current_version",
        +    "active_version",
        +    "trigger_kind",
        +    "cron_expr",
        +    "next_fire_at",
        +    "hook_key",
        +    "spend_cap_month",
        +    "notify_pref",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_agent1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "status": {
        +      "description": "The successful HTTP status code from the underlying operation.",
        +      "type": "integer"
        +    },
        +    "workflows_paused": {
        +      "description": "How many workflows this agent had built and had running were paused by the deletion. They are not deleted: assign them to another agent to run them again.",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "status"
        +  ],
        +  "type": "object"
        +}
    • Changededit_workflow1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "projection": {
        +      "description": "The value-light projection of the edited workflow definition."
        +    },
        +    "resolved": {
        +      "description": "External identifiers resolved while binding the edit.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "id": {
        +            "type": "string"
        +          },
        +          "note": {
        +            "type": "string"
        +          },
        +          "prop": {
        +            "type": "string"
        +          },
        +          "step": {
        +            "type": "string"
        +          },
        +          "title": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "step",
        +          "prop",
        +          "id"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "version": {
        +      "description": "The new draft version created by the edit.",
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": "integer"
        +    },
        +    "workflow_id": {
        +      "description": "The edited workflow.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "workflow_id",
        +    "version",
        +    "projection"
        +  ],
        +  "type": "object"
        +}
    • Addedempty_trash
    • Changedget_agent1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "backend": {
        +      "description": "The compute backend this Agent runs on.",
        +      "type": "string"
        +    },
        +    "config": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "created_at": {
        +      "description": "When the Agent was created.",
        +      "type": "string"
        +    },
        +    "deleting": {
        +      "description": "True while this Agent's disk is still being erased; offer no action on it besides retrying the deletion itself.",
        +      "type": "boolean"
        +    },
        +    "deleting_since": {
        +      "description": "When the deletion was first requested; present only while deleting is true.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "effective_model": {
        +      "description": "The model a run on this Agent will actually use. plori-auto means the hosted router chooses per turn.",
        +      "type": "string"
        +    },
        +    "id": {
        +      "description": "The Agent's unique identifier; pass it to other tools as agent_id.",
        +      "type": "string"
        +    },
        +    "last_run_at": {
        +      "description": "When this Agent last started a run; absent when it has never run.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "mailbox": {
        +      "description": "This agent's mailbox letters, open ones (accepted, delivering, blocked) first, then applied or undeliverable ones, newest within each group, at most 20.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "accepted_at": {
        +            "type": "string"
        +          },
        +          "block_reason": {
        +            "type": "string"
        +          },
        +          "consumed_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "correlation_id": {
        +            "type": "string"
        +          },
        +          "from_agent": {
        +            "type": "string"
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "in_reply_to": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "kind": {
        +            "type": "string"
        +          },
        +          "run_id": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "status": {
        +            "type": "string"
        +          },
        +          "summary": {
        +            "type": "string"
        +          },
        +          "to_agent": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "kind",
        +          "from_agent",
        +          "to_agent",
        +          "status",
        +          "in_reply_to",
        +          "correlation_id",
        +          "run_id",
        +          "summary",
        +          "accepted_at",
        +          "consumed_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "model": {
        +      "description": "The model slug this Agent is configured to use. Empty means no explicit choice, which is not the same as no model — read effective_model for what a run will actually use.",
        +      "type": "string"
        +    },
        +    "moving": {
        +      "description": "True while this Agent's files are being copied to a new disk; check storage_notice rather than a separate route for the outcome.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "The Agent's name, chosen by its owner and unique within the account.",
        +      "type": "string"
        +    },
        +    "queued_at": {
        +      "description": "When a still-warming attach was accepted; present only while it is queued for node capacity.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "description": "The live warm-session state: warming, ready, or sleeping; empty when no session is active.",
        +      "type": "string"
        +    },
        +    "storage_notice": {
        +      "description": "The one sentence, if any, telling the owner about a storage move that stopped; show it verbatim, not paraphrased.",
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "This Agent's page in the plori web app.",
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "description": "The identifier of the account that owns this Agent.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "backend",
        +    "model",
        +    "effective_model",
        +    "config",
        +    "created_at",
        +    "mailbox"
        +  ],
        +  "type": "object"
        +}
    • Changedget_credits1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "account_email": {
        +      "description": "The email address of the account this balance belongs to.",
        +      "type": "string"
        +    },
        +    "active_plan": {
        +      "additionalProperties": false,
        +      "description": "The account's current subscription, or null when it has none and is on the free tier.",
        +      "properties": {
        +        "cancel_at_period_end": {
        +          "type": "boolean"
        +        },
        +        "current_period_end": {
        +          "type": [
        +            "null",
        +            "string"
        +          ]
        +        },
        +        "monthly_credits": {
        +          "description": "Credits this plan adds each month, in the same credits as balance.",
        +          "type": "integer"
        +        },
        +        "sku": {
        +          "type": "string"
        +        },
        +        "status": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "sku",
        +        "monthly_credits",
        +        "status",
        +        "current_period_end",
        +        "cancel_at_period_end"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "audience": {
        +      "type": "string"
        +    },
        +    "balance": {
        +      "description": "The account's remaining prepaid balance, in credits. 1,000,000 credits = 1 US dollar.",
        +      "type": "integer"
        +    },
        +    "balance_usd": {
        +      "description": "The account balance formatted in US dollars, without a currency symbol.",
        +      "type": "string"
        +    },
        +    "can_manage_billing": {
        +      "type": "boolean"
        +    },
        +    "limits": {
        +      "additionalProperties": false,
        +      "description": "The caps this account's plan tier enforces.",
        +      "properties": {
        +        "max_active_workflows": {
        +          "description": "How many active workflows this plan tier may have. 0 means unlimited. An anonymous trial cannot activate a workflow at all.",
        +          "type": "integer"
        +        },
        +        "max_agents": {
        +          "description": "How many agents this plan tier may own. 0 means unlimited. An anonymous trial is capped at one agent whatever this says.",
        +          "type": "integer"
        +        },
        +        "max_concurrent_runs": {
        +          "description": "How many agent runs this plan tier may have in flight at once. 0 means unlimited.",
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "max_agents",
        +        "max_concurrent_runs",
        +        "max_active_workflows"
        +      ],
        +      "type": "object"
        +    },
        +    "low_credit_threshold": {
        +      "description": "The balance, in the same credits, below which this account is warned it is running low.",
        +      "type": "integer"
        +    },
        +    "packs": {
        +      "description": "Credit packs this account can buy. Each pack's usd_cents is its price in US cents and its credits are what the purchase adds to balance.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "usd_cents": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "usd_cents",
        +          "credits"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "plan_tier": {
        +      "description": "The plan tier this account resolves to: free, pro or power. An account with no active plan is free.",
        +      "type": "string"
        +    },
        +    "plans": {
        +      "description": "Subscription plans on offer, with their monthly credit grant.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "id": {
        +            "type": "string"
        +          },
        +          "monthly_credits": {
        +            "type": "integer"
        +          },
        +          "usd_cents": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "usd_cents",
        +          "monthly_credits"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "user_id": {
        +      "description": "The identifier of the account this balance belongs to.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "balance",
        +    "low_credit_threshold",
        +    "packs",
        +    "plans",
        +    "active_plan",
        +    "can_manage_billing",
        +    "audience",
        +    "user_id",
        +    "account_email",
        +    "plan_tier",
        +    "limits",
        +    "balance_usd"
        +  ],
        +  "type": "object"
        +}
    • Changedget_disk1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "included_bytes": {
        +      "type": "integer"
        +    },
        +    "monthly_credits": {
        +      "type": "integer"
        +    },
        +    "purchased_bytes": {
        +      "type": "integer"
        +    },
        +    "storage_credits_per_gb": {
        +      "type": "integer"
        +    },
        +    "total_bytes": {
        +      "type": "integer"
        +    },
        +    "trash_bytes": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "usage_observed_at": {
        +      "description": "When a mount last reported the used figure. Present only while a mount is holding one of the account's disks; when none is, nothing can be changing the figure and there is no reporting clock to quote.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "usage_stale": {
        +      "description": "True when a mount is holding one of the account's disks but has not reported its usage within the writer-lease lifetime. used_bytes is then the last figure that mount reported, not the current one — treat it as a floor and say so rather than quoting it as the account's usage.",
        +      "type": "boolean"
        +    },
        +    "used_bytes": {
        +      "type": "integer"
        +    },
        +    "warning_level": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "included_bytes",
        +    "purchased_bytes",
        +    "total_bytes",
        +    "used_bytes",
        +    "warning_level",
        +    "storage_credits_per_gb",
        +    "monthly_credits"
        +  ],
        +  "type": "object"
        +}
    • Changedget_run_result3 fields changed
      • addedInput schema / properties / wait
        Added value: +{
        +  "description": "When true, wait for a terminal result or human input (see this tool's description for how long the hold lasts). After this tool returns, continue polling while status is non-terminal; it cannot wake an idle client.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / wait_seconds
        Added value: +{
        +  "description": "Optional: how many seconds to wait when wait=true (maximum 1800). Omit to use the window your MCP client can hold.",
        +  "maximum": 1800,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "cause": {
        +      "description": "Machine-readable cause for a non-normal terminal state.",
        +      "type": "string"
        +    },
        +    "continuation_run_id": {
        +      "description": "The exact continuation created for an answered input; poll this run next.",
        +      "type": "string"
        +    },
        +    "credits": {
        +      "description": "Attributed spend in micro-US-dollars; null when attribution is unavailable.",
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "elapsed_seconds": {
        +      "description": "Seconds since the run started; absent for a terminal result.",
        +      "type": "integer"
        +    },
        +    "ended_at": {
        +      "description": "When the run reached a terminal state.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "description": "Why a terminal error or cancelled run failed, whether it was charged and what to do about it. Absent for a run that is still going or that finished normally.",
        +      "properties": {
        +        "class": {
        +          "description": "The failure class: the run's terminal cause, or \"unknown\" when none was recorded.",
        +          "type": "string"
        +        },
        +        "message": {
        +          "description": "What happened, and whether the work was charged.",
        +          "type": "string"
        +        },
        +        "next_step": {
        +          "description": "What to do about it.",
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "description": "Whether sending the same message again could plausibly succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "class",
        +        "message",
        +        "retryable",
        +        "next_step"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "files": {
        +      "description": "Files on the agent's disk that this reply linked, in the order they appear. Each url is fetchable with the bearer token you called this tool with. Absent when the reply linked none.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "path": {
        +            "description": "The file's path on the agent's disk, rooted at the disk root.",
        +            "type": "string"
        +          },
        +          "url": {
        +            "description": "An absolute URL that streams the file's bytes, text or binary and of any size, with its own content type. Fetch it with the same bearer token you called this tool with.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "path",
        +          "url"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "hint": {
        +      "description": "What to do next with this run, in one sentence. Present only while the run is non-terminal.",
        +      "type": "string"
        +    },
        +    "input_expired": {
        +      "description": "True when this run is parked on a question its session has already moved past: a later run in the same conversation has completed. Do not answer it; start a new run instead.",
        +      "type": "boolean"
        +    },
        +    "input_status": {
        +      "description": "The durable status of this run's human-input request, when it has one: pending, answered, cancelled or expired. cancelled and expired are terminal — that run will never resume, so stop polling it.",
        +      "type": "string"
        +    },
        +    "last_activity_at": {
        +      "description": "When the run last wrote a note or finished a tool call. Absent for a terminal result and for a run that has done neither.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "last_heartbeat_at": {
        +      "description": "Most recent durable executor heartbeat.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "last_tool_step": {
        +      "description": "What this run last did with a tool: \"running <tool>\" while a call is in flight, otherwise \"completed <tool>\" for the most recent finished call. Absent for a terminal result and for a run with no tool-progress telemetry.",
        +      "type": "string"
        +    },
        +    "last_worklog": {
        +      "description": "The agent's most recent one-sentence note about what it is doing, from the run's durable event log. Absent for a terminal result and for a run that has written none.",
        +      "type": "string"
        +    },
        +    "pending_inputs": {
        +      "description": "Human inputs blocking an awaiting_input run.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "consent_tool": {
        +            "type": "string"
        +          },
        +          "kind": {
        +            "type": "string"
        +          },
        +          "prompt": {
        +            "type": "string"
        +          },
        +          "risk": {
        +            "type": "string"
        +          },
        +          "tool_call_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "tool_call_id",
        +          "kind",
        +          "prompt"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "poll_after_ms": {
        +      "description": "Legacy spelling of poll_after_seconds in milliseconds; the two always agree. Prefer poll_after_seconds.",
        +      "type": "integer"
        +    },
        +    "poll_after_seconds": {
        +      "description": "Suggested seconds before polling again, paced to this run's recent tool-completion rate; absent for a terminal result.",
        +      "type": "integer"
        +    },
        +    "resume_run_id": {
        +      "description": "The exact auto-resume successor for an interrupted run; poll this run next.",
        +      "type": "string"
        +    },
        +    "resume_status": {
        +      "description": "Auto-resume disposition for an interrupted run: pending, resumed, failed, or unknown.",
        +      "type": "string"
        +    },
        +    "retryable": {
        +      "description": "Whether sending the same message again could plausibly succeed. False for a cause the same request would hit again, including time_limit — split the work or raise max_turn_seconds instead of retrying it unchanged.",
        +      "type": [
        +        "null",
        +        "boolean"
        +      ]
        +    },
        +    "run_id": {
        +      "description": "The public run identifier.",
        +      "type": "string"
        +    },
        +    "session_id": {
        +      "description": "The durable conversation/session identifier.",
        +      "type": "string"
        +    },
        +    "started_at": {
        +      "description": "When the run started.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "description": "The current run status.",
        +      "type": "string"
        +    },
        +    "stop_reason": {
        +      "description": "Controller-selected stop reason, when present.",
        +      "type": "string"
        +    },
        +    "text": {
        +      "description": "The assistant's reply once the run has finished. While a run is still going this is the run's own status message, not an answer, and is often absent — read last_worklog and last_tool_step instead.",
        +      "type": "string"
        +    },
        +    "tokens": {
        +      "description": "Attributed token count; null when attribution is unavailable.",
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "tool_progress": {
        +      "additionalProperties": false,
        +      "description": "Durable tool execution progress; absent when this run has no tool-progress telemetry.",
        +      "properties": {
        +        "active_tools": {
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "id": {
        +                "type": "string"
        +              },
        +              "name": {
        +                "type": "string"
        +              },
        +              "started_at": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "id",
        +              "name",
        +              "started_at"
        +            ],
        +            "type": "object"
        +          },
        +          "type": [
        +            "null",
        +            "array"
        +          ]
        +        },
        +        "completed_count": {
        +          "type": "integer"
        +        },
        +        "last_completed_at": {
        +          "type": [
        +            "null",
        +            "string"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "active_tools",
        +        "completed_count"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "upstream_status": {
        +      "description": "The model provider's HTTP status when this run died on an upstream fault; absent otherwise.",
        +      "type": "integer"
        +    },
        +    "url": {
        +      "description": "A deep link to this run's session in the plori web app.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "run_id",
        +    "session_id",
        +    "status"
        +  ],
        +  "type": "object"
        +}
    • Changedget_usage1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "agents": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "agent_id": {
        +            "type": "string"
        +          },
        +          "backend": {
        +            "type": "string"
        +          },
        +          "breakdown": {
        +            "items": {
        +              "additionalProperties": false,
        +              "properties": {
        +                "credits": {
        +                  "type": "integer"
        +                },
        +                "events": {
        +                  "type": "integer"
        +                },
        +                "kind": {
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "type": "string"
        +                },
        +                "tokens": {
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "kind",
        +                "events",
        +                "tokens",
        +                "credits"
        +              ],
        +              "type": "object"
        +            },
        +            "type": [
        +              "null",
        +              "array"
        +            ]
        +          },
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "events": {
        +            "type": "integer"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "tokens": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "agent_id",
        +          "name",
        +          "backend",
        +          "credits",
        +          "tokens",
        +          "events"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "by_kind": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "events": {
        +            "type": "integer"
        +          },
        +          "kind": {
        +            "type": "string"
        +          },
        +          "tokens": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "credits",
        +          "tokens",
        +          "events"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "recent_runs": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "agent_id": {
        +            "description": "The agent that ran it.",
        +            "type": "string"
        +          },
        +          "cause": {
        +            "type": "string"
        +          },
        +          "command_error": {
        +            "type": "string"
        +          },
        +          "command_state": {
        +            "type": "string"
        +          },
        +          "continuation_run_id": {
        +            "type": "string"
        +          },
        +          "credits": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "ended_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "error": {
        +            "additionalProperties": false,
        +            "description": "Why a terminal error or cancelled run failed, and what to do about it. Absent for a run that is still going or that finished normally.",
        +            "properties": {
        +              "class": {
        +                "description": "The failure class: the run's terminal cause, or \"unknown\" when none was recorded.",
        +                "type": "string"
        +              },
        +              "message": {
        +                "description": "What happened, and whether the work was charged.",
        +                "type": "string"
        +              },
        +              "next_step": {
        +                "description": "What to do about it.",
        +                "type": "string"
        +              },
        +              "retryable": {
        +                "description": "Whether sending the same message again could plausibly succeed.",
        +                "type": "boolean"
        +              }
        +            },
        +            "required": [
        +              "class",
        +              "message",
        +              "retryable",
        +              "next_step"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "id": {
        +            "description": "The run's public identifier; pass it to get_run_result as run_id.",
        +            "type": "string"
        +          },
        +          "input_expired": {
        +            "description": "True when this run is parked on a question its session has moved past: a later run in the same conversation has completed, so answering it would resume a superseded turn. Do not answer it; start a new run instead.",
        +            "type": "boolean"
        +          },
        +          "input_status": {
        +            "type": "string"
        +          },
        +          "input_updated_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "last_heartbeat_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "origin": {
        +            "description": "What started this run: user, schedule, email, background, agent or agent_result.",
        +            "type": "string"
        +          },
        +          "parent_run_id": {
        +            "type": "string"
        +          },
        +          "resume_run_id": {
        +            "type": "string"
        +          },
        +          "resume_status": {
        +            "type": "string"
        +          },
        +          "retryable": {
        +            "type": "boolean"
        +          },
        +          "session_id": {
        +            "description": "The conversation this run belongs to; pass it to invoke_agent as session_id to continue it. Identical to thread_id.",
        +            "type": "string"
        +          },
        +          "started_at": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "The run's status: queued, running, awaiting_input, completed, error or cancelled.",
        +            "type": "string"
        +          },
        +          "stop_reason": {
        +            "type": "string"
        +          },
        +          "thread_id": {
        +            "description": "The conversation this run belongs to. Identical to session_id.",
        +            "type": "string"
        +          },
        +          "tokens": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "tool_progress": {
        +            "additionalProperties": false,
        +            "description": "Durable tool execution progress, from the same telemetry get_run_result reads. Null for a run with no telemetry, and for a terminal run, which has no call in flight to report.",
        +            "properties": {
        +              "active_tools": {
        +                "items": {
        +                  "additionalProperties": false,
        +                  "properties": {
        +                    "id": {
        +                      "type": "string"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "started_at": {
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "id",
        +                    "name",
        +                    "started_at"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": [
        +                  "null",
        +                  "array"
        +                ]
        +              },
        +              "completed_count": {
        +                "type": "integer"
        +              },
        +              "last_completed_at": {
        +                "type": [
        +                  "null",
        +                  "string"
        +                ]
        +              }
        +            },
        +            "required": [
        +              "active_tools",
        +              "completed_count"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "upstream_status": {
        +            "description": "The model provider's HTTP status when this run died on an upstream fault; absent otherwise.",
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "agent_id",
        +          "thread_id",
        +          "session_id",
        +          "status",
        +          "origin",
        +          "started_at",
        +          "credits",
        +          "tokens",
        +          "tool_progress"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "tools": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "calls": {
        +            "type": "integer"
        +          },
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "free_calls": {
        +            "type": "integer"
        +          },
        +          "tool": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "tool",
        +          "calls",
        +          "free_calls",
        +          "credits"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "totals": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "credits": {
        +          "type": "integer"
        +        },
        +        "runs": {
        +          "type": "integer"
        +        },
        +        "tokens": {
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "credits",
        +        "tokens",
        +        "runs"
        +      ],
        +      "type": "object"
        +    },
        +    "workflow_executions": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "duration_ms": {
        +            "type": "integer"
        +          },
        +          "ended_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "fault": {
        +            "type": "string"
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "type": "string"
        +          },
        +          "trigger_source": {
        +            "type": "string"
        +          },
        +          "workflow_id": {
        +            "type": "string"
        +          },
        +          "workflow_name": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "workflow_id",
        +          "workflow_name",
        +          "status",
        +          "trigger_source",
        +          "duration_ms",
        +          "credits",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "workflows": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "billed_runs": {
        +            "type": "integer"
        +          },
        +          "credits": {
        +            "type": "integer"
        +          },
        +          "exec_credits": {
        +            "type": "integer"
        +          },
        +          "model_credits": {
        +            "type": "integer"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "tokens": {
        +            "type": "integer"
        +          },
        +          "workflow_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "workflow_id",
        +          "name",
        +          "billed_runs",
        +          "exec_credits",
        +          "model_credits",
        +          "credits",
        +          "tokens"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "totals",
        +    "by_kind",
        +    "tools",
        +    "agents",
        +    "workflows",
        +    "workflow_executions",
        +    "recent_runs"
        +  ],
        +  "type": "object"
        +}
    • Changedget_workflow1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "active_version": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "agent_deleted_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "agent_id": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "cron_expr": {
        +      "type": "string"
        +    },
        +    "current_version": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": "integer"
        +    },
        +    "description": {
        +      "type": "string"
        +    },
        +    "engine": {
        +      "type": "string"
        +    },
        +    "hook_key": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_fire_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "notify_pref": {
        +      "type": "string"
        +    },
        +    "paused_reason": {
        +      "type": "string"
        +    },
        +    "projection": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "spend_cap_month": {
        +      "type": "integer"
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "template_slug": {
        +      "type": "string"
        +    },
        +    "trigger_kind": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "agent_id",
        +    "name",
        +    "description",
        +    "engine",
        +    "status",
        +    "current_version",
        +    "active_version",
        +    "trigger_kind",
        +    "cron_expr",
        +    "next_fire_at",
        +    "hook_key",
        +    "spend_cap_month",
        +    "notify_pref",
        +    "created_at",
        +    "updated_at",
        +    "projection"
        +  ],
        +  "type": "object"
        +}
    • Changedget_workflow_execution1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "billed": {
        +      "description": "The billing flag. True only for a user-fault succeeded, failed, or timed-out execution.",
        +      "type": "boolean"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "credits": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "duration_ms": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "ended_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "error": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "fault": {
        +      "description": "Why a non-succeeded execution ended. User means the workflow's own steps or limits. A platform fault is never billed. This field is null when the execution succeeded.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "started_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "step_stats": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "steps": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "trigger_source": {
        +      "type": "string"
        +    },
        +    "workflow_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "workflow_id",
        +    "status",
        +    "fault",
        +    "billed",
        +    "trigger_source",
        +    "started_at",
        +    "ended_at",
        +    "duration_ms",
        +    "credits",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedget_workflow_version1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "author": {
        +      "type": "string"
        +    },
        +    "chat_run_id": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "definition": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "projection": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "version": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": "integer"
        +    },
        +    "workflow_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "workflow_id",
        +    "version",
        +    "author",
        +    "chat_run_id",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedinvoke_agent7 fields changed
      • addedInput schema / properties / callback_secret
        Added value: +{
        +  "description": "Optional secret used to sign callback deliveries with HMAC-SHA256.",
        +  "type": "string"
        +}
      • addedInput schema / properties / callback_url
        Added value: +{
        +  "description": "Optional callback URL for this run. Must use http or https and resolve only to public addresses.",
        +  "type": "string"
        +}
      • changedInput schema / properties / max_turn_seconds / description
        Previous value: -"Optional soft wall-clock budget for this turn in seconds (0 or omitted uses forge's deployment default; maximum 14,400). It schedules an in-loop checkpoint and does not cancel the run."New value: +"Optional soft wall-clock budget for this turn in seconds, maximum 14,400. 0 or omitted uses the deployment's configured default, and where none is configured a turn has no wall-clock budget at all. It schedules an in-loop checkpoint and does not cancel the run."
      • changedInput schema / properties / max_turn_tokens / description
        Previous value: -"Optional cumulative cache-weighted token ceiling for this turn (0 or omitted uses forge's default; maximum 5,000,000). The agent reserves its final 2% for a tool-free wrap-up."New value: +"Optional cumulative cache-weighted token ceiling for this turn. 0 or omitted uses the agent's default of 2,000,000; the maximum is 5,000,000. The agent reserves its final 2% for a tool-free wrap-up."
      • changedInput schema / properties / wait / description
        Previous value: -"Wait (up to ~25s) for the turn and return the reply (default true). Set false to return a run_id immediately and poll get_run_result — prefer this for long or tool-heavy turns so the call doesn't block your own turn."New value: +"Wait for the turn and return the reply (default true); the hold lasts as long as your client keeps the call open, or wait_seconds. Set false to return a run_id immediately and poll get_run_result — prefer this for long or tool-heavy turns so the call doesn't block your own turn."
      • addedInput schema / properties / wait_seconds
        Added value: +{
        +  "description": "Optional: how many seconds to wait for the turn before returning a \"running\" run_id (maximum 1800). Omit to use the window your MCP client can hold. Ignored when wait=false.",
        +  "maximum": 1800,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "cause": {
        +      "description": "Machine-readable cause for a non-normal terminal state.",
        +      "type": "string"
        +    },
        +    "continuation_run_id": {
        +      "description": "The exact continuation created for an answered input; poll this run next.",
        +      "type": "string"
        +    },
        +    "credits": {
        +      "description": "Attributed spend in micro-US-dollars; null when attribution is unavailable.",
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "elapsed_seconds": {
        +      "description": "Seconds since the run started; absent for a terminal result.",
        +      "type": "integer"
        +    },
        +    "ended_at": {
        +      "description": "When the run reached a terminal state.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "description": "Why a terminal error or cancelled run failed, whether it was charged and what to do about it. Absent for a run that is still going or that finished normally.",
        +      "properties": {
        +        "class": {
        +          "description": "The failure class: the run's terminal cause, or \"unknown\" when none was recorded.",
        +          "type": "string"
        +        },
        +        "message": {
        +          "description": "What happened, and whether the work was charged.",
        +          "type": "string"
        +        },
        +        "next_step": {
        +          "description": "What to do about it.",
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "description": "Whether sending the same message again could plausibly succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "class",
        +        "message",
        +        "retryable",
        +        "next_step"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "files": {
        +      "description": "Files on the agent's disk that this reply linked, in the order they appear. Each url is fetchable with the bearer token you called this tool with. Absent when the reply linked none.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "path": {
        +            "description": "The file's path on the agent's disk, rooted at the disk root.",
        +            "type": "string"
        +          },
        +          "url": {
        +            "description": "An absolute URL that streams the file's bytes, text or binary and of any size, with its own content type. Fetch it with the same bearer token you called this tool with.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "path",
        +          "url"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "hint": {
        +      "description": "What to do next with this run, in one sentence. Present only while the run is non-terminal.",
        +      "type": "string"
        +    },
        +    "input_expired": {
        +      "description": "True when this run is parked on a question its session has already moved past: a later run in the same conversation has completed. Do not answer it; start a new run instead.",
        +      "type": "boolean"
        +    },
        +    "input_status": {
        +      "description": "The durable status of this run's human-input request, when it has one: pending, answered, cancelled or expired. cancelled and expired are terminal — that run will never resume, so stop polling it.",
        +      "type": "string"
        +    },
        +    "last_activity_at": {
        +      "description": "When the run last wrote a note or finished a tool call. Absent for a terminal result and for a run that has done neither.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "last_heartbeat_at": {
        +      "description": "Most recent durable executor heartbeat.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "last_tool_step": {
        +      "description": "What this run last did with a tool: \"running <tool>\" while a call is in flight, otherwise \"completed <tool>\" for the most recent finished call. Absent for a terminal result and for a run with no tool-progress telemetry.",
        +      "type": "string"
        +    },
        +    "last_worklog": {
        +      "description": "The agent's most recent one-sentence note about what it is doing, from the run's durable event log. Absent for a terminal result and for a run that has written none.",
        +      "type": "string"
        +    },
        +    "pending_inputs": {
        +      "description": "Human inputs blocking an awaiting_input run.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "consent_tool": {
        +            "type": "string"
        +          },
        +          "kind": {
        +            "type": "string"
        +          },
        +          "prompt": {
        +            "type": "string"
        +          },
        +          "risk": {
        +            "type": "string"
        +          },
        +          "tool_call_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "tool_call_id",
        +          "kind",
        +          "prompt"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "poll_after_ms": {
        +      "description": "Legacy spelling of poll_after_seconds in milliseconds; the two always agree. Prefer poll_after_seconds.",
        +      "type": "integer"
        +    },
        +    "poll_after_seconds": {
        +      "description": "Suggested seconds before polling again, paced to this run's recent tool-completion rate; absent for a terminal result.",
        +      "type": "integer"
        +    },
        +    "resume_run_id": {
        +      "description": "The exact auto-resume successor for an interrupted run; poll this run next.",
        +      "type": "string"
        +    },
        +    "resume_status": {
        +      "description": "Auto-resume disposition for an interrupted run: pending, resumed, failed, or unknown.",
        +      "type": "string"
        +    },
        +    "retryable": {
        +      "description": "Whether sending the same message again could plausibly succeed. False for a cause the same request would hit again, including time_limit — split the work or raise max_turn_seconds instead of retrying it unchanged.",
        +      "type": [
        +        "null",
        +        "boolean"
        +      ]
        +    },
        +    "run_id": {
        +      "description": "The public run identifier.",
        +      "type": "string"
        +    },
        +    "session_id": {
        +      "description": "The durable conversation/session identifier.",
        +      "type": "string"
        +    },
        +    "started_at": {
        +      "description": "When the run started.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "description": "The current run status.",
        +      "type": "string"
        +    },
        +    "stop_reason": {
        +      "description": "Controller-selected stop reason, when present.",
        +      "type": "string"
        +    },
        +    "text": {
        +      "description": "The assistant's reply once the run has finished. While a run is still going this is the run's own status message, not an answer, and is often absent — read last_worklog and last_tool_step instead.",
        +      "type": "string"
        +    },
        +    "tokens": {
        +      "description": "Attributed token count; null when attribution is unavailable.",
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "tool_progress": {
        +      "additionalProperties": false,
        +      "description": "Durable tool execution progress; absent when this run has no tool-progress telemetry.",
        +      "properties": {
        +        "active_tools": {
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "id": {
        +                "type": "string"
        +              },
        +              "name": {
        +                "type": "string"
        +              },
        +              "started_at": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "id",
        +              "name",
        +              "started_at"
        +            ],
        +            "type": "object"
        +          },
        +          "type": [
        +            "null",
        +            "array"
        +          ]
        +        },
        +        "completed_count": {
        +          "type": "integer"
        +        },
        +        "last_completed_at": {
        +          "type": [
        +            "null",
        +            "string"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "active_tools",
        +        "completed_count"
        +      ],
        +      "type": [
        +        "null",
        +        "object"
        +      ]
        +    },
        +    "upstream_status": {
        +      "description": "The model provider's HTTP status when this run died on an upstream fault; absent otherwise.",
        +      "type": "integer"
        +    },
        +    "url": {
        +      "description": "A deep link to this run's session in the plori web app.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "run_id",
        +    "session_id",
        +    "status"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_agents1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "description": "The returned items, in the endpoint's documented order.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "backend": {
        +            "description": "The compute backend this Agent runs on.",
        +            "type": "string"
        +          },
        +          "config": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "created_at": {
        +            "description": "When the Agent was created.",
        +            "type": "string"
        +          },
        +          "deleting": {
        +            "description": "True while this Agent's disk is still being erased; offer no action on it besides retrying the deletion itself.",
        +            "type": "boolean"
        +          },
        +          "deleting_since": {
        +            "description": "When the deletion was first requested; present only while deleting is true.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "effective_model": {
        +            "description": "The model a run on this Agent will actually use. plori-auto means the hosted router chooses per turn.",
        +            "type": "string"
        +          },
        +          "id": {
        +            "description": "The Agent's unique identifier; pass it to other tools as agent_id.",
        +            "type": "string"
        +          },
        +          "last_run_at": {
        +            "description": "When this Agent last started a run; absent when it has never run.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "model": {
        +            "description": "The model slug this Agent is configured to use. Empty means no explicit choice, which is not the same as no model — read effective_model for what a run will actually use.",
        +            "type": "string"
        +          },
        +          "moving": {
        +            "description": "True while this Agent's files are being copied to a new disk; check storage_notice rather than a separate route for the outcome.",
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "description": "The Agent's name, chosen by its owner and unique within the account.",
        +            "type": "string"
        +          },
        +          "queued_at": {
        +            "description": "When a still-warming attach was accepted; present only while it is queued for node capacity.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "status": {
        +            "description": "The live warm-session state: warming, ready, or sleeping; empty when no session is active.",
        +            "type": "string"
        +          },
        +          "storage_notice": {
        +            "description": "The one sentence, if any, telling the owner about a storage move that stopped; show it verbatim, not paraphrased.",
        +            "type": "string"
        +          },
        +          "url": {
        +            "description": "This Agent's page in the plori web app.",
        +            "type": "string"
        +          },
        +          "user_id": {
        +            "description": "The identifier of the account that owns this Agent.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "user_id",
        +          "name",
        +          "backend",
        +          "model",
        +          "effective_model",
        +          "config",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "items"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_connections1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "connections": {
        +      "description": "Third-party OAuth connection status records; never secret material.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "authorized_at": {
        +            "description": "When the grant was last authorized; null when there has never been one.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "expires_at": {
        +            "description": "When the current access token expires; null when the grant does not expire. A past value on an authorized row is normal — tokens refresh lazily when used.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "needs_reauth": {
        +            "description": "True when a human must reconnect this provider before it can be used. Read this rather than comparing expires_at to the clock.",
        +            "type": "boolean"
        +          },
        +          "provider": {
        +            "description": "The third-party provider this row is about.",
        +            "type": "string"
        +          },
        +          "scopes": {
        +            "description": "The scopes this provider is configured to request.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": [
        +              "null",
        +              "array"
        +            ]
        +          },
        +          "status": {
        +            "description": "authorized, reconnect_needed, or unauthorized.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "provider",
        +          "status",
        +          "authorized_at",
        +          "expires_at",
        +          "scopes",
        +          "needs_reauth"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "connections"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_pending_inputs1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "pending_inputs": {
        +      "description": "Runs currently parked on a human approval or input request. A request whose session has already moved on is left out: answering it would resume a superseded turn.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "agent_id": {
        +            "type": "string"
        +          },
        +          "args": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "connect": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "provider": {
        +                "type": "string"
        +              },
        +              "workflow_id": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "workflow_id",
        +              "provider"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "consent_tool": {
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "expires_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "kind": {
        +            "type": "string"
        +          },
        +          "prompt": {
        +            "type": "string"
        +          },
        +          "risk": {
        +            "type": "string"
        +          },
        +          "run_id": {
        +            "type": "string"
        +          },
        +          "schema": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "secret": {
        +            "type": "boolean"
        +          },
        +          "status": {
        +            "type": "string"
        +          },
        +          "tool_call_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "run_id",
        +          "agent_id",
        +          "tool_call_id",
        +          "kind",
        +          "prompt",
        +          "status",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "pending_inputs"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_runs3 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "The next_cursor from a previous list_runs result, to continue where it stopped. Omit for the newest page.",
        +  "type": "string"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "How many runs to return, newest first (default 20, maximum 100).",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "description": "One page of the agent's runs, most recently started first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "agent_id": {
        +            "description": "The agent that ran it.",
        +            "type": "string"
        +          },
        +          "cause": {
        +            "type": "string"
        +          },
        +          "command_error": {
        +            "type": "string"
        +          },
        +          "command_state": {
        +            "type": "string"
        +          },
        +          "continuation_run_id": {
        +            "type": "string"
        +          },
        +          "credits": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "ended_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "error": {
        +            "additionalProperties": false,
        +            "description": "Why a terminal error or cancelled run failed, and what to do about it. Absent for a run that is still going or that finished normally.",
        +            "properties": {
        +              "class": {
        +                "description": "The failure class: the run's terminal cause, or \"unknown\" when none was recorded.",
        +                "type": "string"
        +              },
        +              "message": {
        +                "description": "What happened, and whether the work was charged.",
        +                "type": "string"
        +              },
        +              "next_step": {
        +                "description": "What to do about it.",
        +                "type": "string"
        +              },
        +              "retryable": {
        +                "description": "Whether sending the same message again could plausibly succeed.",
        +                "type": "boolean"
        +              }
        +            },
        +            "required": [
        +              "class",
        +              "message",
        +              "retryable",
        +              "next_step"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "id": {
        +            "description": "The run's public identifier; pass it to get_run_result as run_id.",
        +            "type": "string"
        +          },
        +          "input_expired": {
        +            "description": "True when this run is parked on a question its session has moved past: a later run in the same conversation has completed, so answering it would resume a superseded turn. Do not answer it; start a new run instead.",
        +            "type": "boolean"
        +          },
        +          "input_status": {
        +            "type": "string"
        +          },
        +          "input_updated_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "last_heartbeat_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "origin": {
        +            "description": "What started this run: user, schedule, email, background, agent or agent_result.",
        +            "type": "string"
        +          },
        +          "parent_run_id": {
        +            "type": "string"
        +          },
        +          "resume_run_id": {
        +            "type": "string"
        +          },
        +          "resume_status": {
        +            "type": "string"
        +          },
        +          "retryable": {
        +            "type": "boolean"
        +          },
        +          "session_id": {
        +            "description": "The conversation this run belongs to; pass it to invoke_agent as session_id to continue it. Identical to thread_id.",
        +            "type": "string"
        +          },
        +          "started_at": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "The run's status: queued, running, awaiting_input, completed, error or cancelled.",
        +            "type": "string"
        +          },
        +          "stop_reason": {
        +            "type": "string"
        +          },
        +          "thread_id": {
        +            "description": "The conversation this run belongs to. Identical to session_id.",
        +            "type": "string"
        +          },
        +          "tokens": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "tool_progress": {
        +            "additionalProperties": false,
        +            "description": "Durable tool execution progress, from the same telemetry get_run_result reads. Null for a run with no telemetry, and for a terminal run, which has no call in flight to report.",
        +            "properties": {
        +              "active_tools": {
        +                "items": {
        +                  "additionalProperties": false,
        +                  "properties": {
        +                    "id": {
        +                      "type": "string"
        +                    },
        +                    "name": {
        +                      "type": "string"
        +                    },
        +                    "started_at": {
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "id",
        +                    "name",
        +                    "started_at"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": [
        +                  "null",
        +                  "array"
        +                ]
        +              },
        +              "completed_count": {
        +                "type": "integer"
        +              },
        +              "last_completed_at": {
        +                "type": [
        +                  "null",
        +                  "string"
        +                ]
        +              }
        +            },
        +            "required": [
        +              "active_tools",
        +              "completed_count"
        +            ],
        +            "type": [
        +              "null",
        +              "object"
        +            ]
        +          },
        +          "upstream_status": {
        +            "description": "The model provider's HTTP status when this run died on an upstream fault; absent otherwise.",
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "agent_id",
        +          "thread_id",
        +          "session_id",
        +          "status",
        +          "origin",
        +          "started_at",
        +          "credits",
        +          "tokens",
        +          "tool_progress"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    },
        +    "next_cursor": {
        +      "description": "Pass this back as cursor to read the next page. Absent when this page is the end of the history.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "items"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_workflow_executions1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "executions": {
        +      "description": "Recent workflow executions, most recent first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "billed": {
        +            "description": "The billing flag. True only for a user-fault succeeded, failed, or timed-out execution.",
        +            "type": "boolean"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "credits": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "duration_ms": {
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "ended_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "error": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "fault": {
        +            "description": "Why a non-succeeded execution ended. User means the workflow's own steps or limits. A platform fault is never billed. This field is null when the execution succeeded.",
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "started_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "status": {
        +            "type": "string"
        +          },
        +          "step_stats": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "steps": {
        +            "description": "Arbitrary JSON owned by the producing engine."
        +          },
        +          "trigger_source": {
        +            "type": "string"
        +          },
        +          "workflow_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "workflow_id",
        +          "status",
        +          "fault",
        +          "billed",
        +          "trigger_source",
        +          "started_at",
        +          "ended_at",
        +          "duration_ms",
        +          "credits",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "executions"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_workflows1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "workflows": {
        +      "description": "Workflows visible to the authenticated account and optional agent filter.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "active_version": {
        +            "maximum": 2147483647,
        +            "minimum": -2147483648,
        +            "type": [
        +              "null",
        +              "integer"
        +            ]
        +          },
        +          "agent_deleted_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "agent_id": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "cron_expr": {
        +            "type": "string"
        +          },
        +          "current_version": {
        +            "maximum": 2147483647,
        +            "minimum": -2147483648,
        +            "type": "integer"
        +          },
        +          "description": {
        +            "type": "string"
        +          },
        +          "engine": {
        +            "type": "string"
        +          },
        +          "hook_key": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "next_fire_at": {
        +            "type": [
        +              "null",
        +              "string"
        +            ]
        +          },
        +          "notify_pref": {
        +            "type": "string"
        +          },
        +          "paused_reason": {
        +            "type": "string"
        +          },
        +          "spend_cap_month": {
        +            "type": "integer"
        +          },
        +          "status": {
        +            "type": "string"
        +          },
        +          "template_slug": {
        +            "type": "string"
        +          },
        +          "trigger_kind": {
        +            "type": "string"
        +          },
        +          "updated_at": {
        +            "type": "string"
        +          },
        +          "user_id": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "user_id",
        +          "agent_id",
        +          "name",
        +          "description",
        +          "engine",
        +          "status",
        +          "current_version",
        +          "active_version",
        +          "trigger_kind",
        +          "cron_expr",
        +          "next_fire_at",
        +          "hook_key",
        +          "spend_cap_month",
        +          "notify_pref",
        +          "created_at",
        +          "updated_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": [
        +        "null",
        +        "array"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "workflows"
        +  ],
        +  "type": "object"
        +}
    • Changedrun_workflow1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "billed": {
        +      "description": "The billing flag. True only for a user-fault succeeded, failed, or timed-out execution.",
        +      "type": "boolean"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "credits": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "duration_ms": {
        +      "type": [
        +        "null",
        +        "integer"
        +      ]
        +    },
        +    "ended_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "error": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "fault": {
        +      "description": "Why a non-succeeded execution ended. User means the workflow's own steps or limits. A platform fault is never billed. This field is null when the execution succeeded.",
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "started_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "step_stats": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "steps": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "trigger_source": {
        +      "type": "string"
        +    },
        +    "workflow_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "workflow_id",
        +    "status",
        +    "fault",
        +    "billed",
        +    "trigger_source",
        +    "started_at",
        +    "ended_at",
        +    "duration_ms",
        +    "credits",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedschedule_run1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "agent_id": {
        +      "type": "string"
        +    },
        +    "attempts": {
        +      "maximum": 2147483647,
        +      "minimum": -2147483648,
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "fire_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "kind": {
        +      "type": "string"
        +    },
        +    "last_error": {
        +      "type": "string"
        +    },
        +    "last_fired_at": {
        +      "type": [
        +        "null",
        +        "string"
        +      ]
        +    },
        +    "metadata": {
        +      "description": "Arbitrary JSON owned by the producing engine."
        +    },
        +    "prompt": {
        +      "type": "string"
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "thread_id": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "agent_id",
        +    "kind",
        +    "status",
        +    "prompt",
        +    "attempts",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Removedset_agent_model
    • Addedset_workflow_agent
  3. 2 tool updatesv0.9.1
    • Changedanswer_pending_input1 field changed
      • addedInput schema / properties / max_turn_seconds
        Added value: +{
        +  "description": "Optional soft wall-clock budget to preserve on the continuation run; it does not change the parked run or impose a hard deadline.",
        +  "maximum": 14400,
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • Changedinvoke_agent1 field changed
      • addedInput schema / properties / max_turn_seconds
        Added value: +{
        +  "description": "Optional soft wall-clock budget for this turn in seconds (0 or omitted uses forge's deployment default; maximum 14,400). It schedules an in-loop checkpoint and does not cancel the run.",
        +  "maximum": 14400,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  4. 4 tool updatesv0.9.0
    • Addedcancel_run
    • Addededit_workflow
    • Addedget_workflow_version
    • Changedinvoke_agent1 field changed
      • addedInput schema / properties / max_turn_tokens
        Added value: +{
        +  "description": "Optional cumulative cache-weighted token ceiling for this turn (0 or omitted uses forge's default; maximum 5,000,000). The agent reserves its final 2% for a tool-free wrap-up.",
        +  "maximum": 5000000,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  5. 14 tool updatesv0.7.0
    • Changedanswer_pending_input1 field changed
      • addedInput schema / properties / always_allow
        Added value: +{
        +  "description": "Approve AND stop asking for this tool on this agent (a standing grant). Only set it when the human explicitly said to stop being asked, and only on a row whose consent_tool is set; ignored without approved=true. Revoke via DELETE /v1/agents/{agent_id}/tool-consents/{tool}.",
        +  "type": "boolean"
        +}
    • Changedcreate_agent1 field changed
      • changedInput schema / properties / model / description
        Previous value: -"Optional model slug; omitted uses Auto, the plan-scaled default whose quality follows the account's plan. An explicit frontier model requires a paid plan."New value: +"Optional model slug; omitted uses the Plori Router, which picks the cheapest model that fits each task from the pool the account's plan unlocks. An explicit frontier model still requires a paid plan."
    • Changedcreate_workflow1 field changed
      • changedInput schema / properties / agent_id / description
        Previous value: -"Optional UUID of one of your agents to record as the workflow's creator."New value: +"Optional UUID of one of your agents to own the workflow. That agent is then the one that can build, edit, and run it from a chat; leave it out and the workflow stays unassigned until you set an owner."
    • Addedget_agent
    • Addedget_usage
    • Addedget_workflow
    • Changedinvoke_agent1 field changed
      • changedInput schema / properties / session_id / description
        Previous value: -"Optional thread/session id to continue an existing conversation; omit to start a new one."New value: +"Optional thread/session id to continue an existing conversation (a previous invoke_agent or get_run_result result carries it as \"session_id\"); omit to start a new one."
    • Addedlist_connections
    • Addedlist_runs
    • Addedlist_workflow_executions
    • Changedlist_workflows1 field changed
      • addedInput schema / properties / agent_id
        Added value: +{
        +  "description": "Optional: a UUID of one of your agents to list only its workflows, or \"none\" for the unassigned ones.",
        +  "type": "string"
        +}
    • Addedrun_workflow
    • Addedschedule_run
    • Addedset_agent_model
  6. 13 tool updatesv0.3.0
    • Changedcreate_agent1 field changed
      • changedInput schema / properties / model / description
        Previous value: -"Optional model slug; omitted uses the account's tier default. Frontier models require a paid plan."New value: +"Optional model slug; omitted uses Auto, the plan-scaled default whose quality follows the account's plan. An explicit frontier model requires a paid plan."
    • Removedget_agent
    • Changedget_credits1 field changed
      • addedInput schema / properties
        Added value: +{}
    • Changedget_disk1 field changed
      • addedInput schema / properties
        Added value: +{}
    • Removedget_usage
    • Changedinvoke_agent1 field changed
      • addedInput schema / properties / idempotency_key
        Added value: +{
        +  "description": "Optional retry guard: a string you generate for this attempt. Re-sending the same key with the same agent and message within 24h returns the ORIGINAL run instead of starting a second one. Reusing a key with a different message is an error.",
        +  "type": "string"
        +}
    • Changedlist_agents1 field changed
      • addedInput schema / properties
        Added value: +{}
    • Removedlist_brains
    • Removedlist_runs
    • Changedlist_workflows1 field changed
      • addedInput schema / properties
        Added value: +{}
    • Removedrun_workflow
    • Removedschedule_run
    • Removedset_agent_model
  7. 6 tool updatesv0.1.1
    • Changedcreate_agent1 field changed
      • changedInput schema / properties / name / description
        Previous value: -"A human-readable name for the agent."New value: +"The agent's name. Reusing a previous name returns that existing agent."
    • Addedcreate_workflow
    • Addedget_workflow_execution
    • Changedinvoke_agent1 field changed
      • changedInput schema / properties / wait / description
        Previous value: -"Wait for the turn to complete and return the reply (default true). If false, returns a run_id to poll."New value: +"Wait (up to ~25s) for the turn and return the reply (default true). Set false to return a run_id immediately and poll get_run_result — prefer this for long or tool-heavy turns so the call doesn't block your own turn."
    • Addedlist_workflows
    • Addedrun_workflow
  8. 15 tool updatesv0.1.0
    • First observedanswer_pending_input
    • First observedcreate_agent
    • First observeddelete_agent
    • First observedget_agent
    • First observedget_credits
    • First observedget_disk
    • First observedget_run_result
    • First observedget_usage
    • First observedinvoke_agent
    • First observedlist_agents
    • First observedlist_brains
    • First observedlist_pending_inputs
    • First observedlist_runs
    • First observedschedule_run
    • First observedset_agent_model

TDQS

A4/5.0

Scored across 25 tools

Disambiguation4/5

Tools are organized into clear resource domains — agents, workflows, runs, billing/disk, and OAuth — so most choices are obvious. The main ambiguity is get_workflow vs get_workflow_version, and to a lesser extent get_agent vs create_agent's get-or-create behavior, which an agent could misselect despite helpful cross-references.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern: create_agent, list_workflows, cancel_run, empty_trash, answer_pending_input. The get/list split is applied uniformly across agents, workflows, and executions, making the naming predictable.

Tool Count3/5

At 25 tools, the server sits at the heavy end of the scale. Each tool is individually justified by the broad scope — agents, workflows, runs, billing, disk, and connections — but the total surface feels more like several subdomain APIs bundled together than a tightly scoped set.

Completeness3/5

Agent and run lifecycle coverage is strong, but the workflow lifecycle has notable gaps: there is no delete_workflow, and no explicit activate/publish tool even though edit_workflow warns that edits do not activate the draft. Billing, disk, and connection surfaces are read-mostly, which is acceptable but leaves workflow management incomplete.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Agent-native hosting: your agent deploys any folder to a live URL in one command — no account, no dashboard, no CAPTCHA — and hands the human a link plus a plain-language summary. Full deploy lifecycle as MCP tools (deploy, verify, logs, inspect, rollback), production approval human-only; static sites and full Node.js apps, open source (Apache-2.0).
    13
    Apache 2.0