Chat tools
The os.* tools the CEO chat offers a member: the company's directory, its tasks, and starting and checking runs.
Generated from the built-in tools registry. Do not edit by hand.
When the CEO talks to a member in the portal, the member can use these tools, and the member's own connected tools beside them. Chat has no gates of its own; spend still applies.
A conversation opened for one job, such as creating a task, also gets the tools kept for that job. A member’s everyday thread never does.
A run never answers a chat-only tool, so a task that declares one is refused when it is saved (tool_not_run_callable).
| Tool | What it does | Effect |
|---|---|---|
os.list_tasks |
The tasks of the roles the chatting member holds, plus OS-owned tasks. | read |
os.start_task |
Queue a run of a task of a role you hold, an OS task, or a colleague's task. | write |
os.get_run |
A run's status, why it stopped, and its recent events. | read |
os.hand_off_task_brief |
Hand the brief a person agreed to over to the OS, which designs the task from it. | write |
os.list_runs |
The enterprise's runs, newest first, a page at a time. | read |
os.kpi_board |
The enterprise's KPI board: every signed-off company KPI and each team's key KPI, with its light. | read |
os.list_enterprise_kpis |
Every KPI of the enterprise, with its owner, target, cadence, light and last reading. | read |
Also offered here: os.directory, which a run can call too.
os.list_tasks
The tasks of the roles the chatting member holds, plus OS-owned tasks.
What the model reads:
List the tasks of the roles you hold on each task’s team, plus OS-owned tasks. OS tasks are not a person.
No declared fields: the schema accepts any object.
- Effect: read.
- Retry: Safe: repeating the call changes nothing.
- Called by: the CEO chat, the API.
- API:
GET /v1/tasks/held-by/:memberId(tasks:read)
os.start_task
Queue a run of a task of a role you hold, an OS task, or a colleague's task.
What the model reads:
Start a run of a task of a role you hold, an OS task, or a colleague’s task. Pass taskId or slug, and input matching the task’s fields; a field you leave out takes the task’s default. The run goes to a free member holding the task’s role, who may not be you; when every holder is busy it queues as pending. This only queues the run: check it with os.get_run before reporting on it.
| Field | Type | Required | Description |
|---|---|---|---|
taskId |
string | no | |
slug |
string | no | |
input |
object | no |
- Effect: write.
- Retry: Idempotent: a repeat of the same call acts once, or leaves the same state. Keyed on the chat session and the tool call: the same call sent twice starts one run.
- Called by: the CEO chat, the API.
- Returns:
{ runId, status, taskId, slug, origin }. - API:
POST /v1/tasks/:taskId/runs(tasks:write)
| Error | When | What happens |
|---|---|---|
task_not_found |
No task in this enterprise has that id or slug. | Tool error |
Example:
{
"slug": "weekly-report",
"input": {
"week": "2026-W39"
}
}
os.get_run
A run's status, why it stopped, and its recent events.
What the model reads:
One run's status, why it stopped (blockedReason, when it is blocked), task id and input, and its last eight events. Not found for another enterprise's run.
| Field | Type | Required | Description |
|---|---|---|---|
runId |
string | yes | The run id. |
No other fields are accepted.
- Effect: read.
- Retry: Safe: repeating the call changes nothing.
- Called by: the CEO chat, the API, the OS MCP server.
- Returns: Status,
blockedReason(why ablockedrun stopped, otherwise null), task id, input and the last eight events. - API:
GET /v1/runs/:runId/os-tool(runs:read)
| Error | When | What happens |
|---|---|---|
runId_required |
runId is missing. |
Tool error |
run_not_found |
No run in this enterprise has that id. | Tool error |
Example:
{
"runId": "5f0c1d2e-0000-4000-8000-000000000004"
}
os.hand_off_task_brief
Hand the brief a person agreed to over to the OS, which designs the task from it.
What the model reads:
Hand the brief the person agreed to over to the OS, which designs the new task from it and asks the CEO to sign off on its definition before anything is created. Call it once, only after they have said yes to your read-back summary, with every part of the brief in their own words. It starts the design and returns its run; it does not create the task.
| Field | Type | Required | Description |
|---|---|---|---|
brief |
object | yes | What the person agreed to, each part in plain language. |
brief.goal |
string | yes | What the job is. |
brief.success |
string | yes | How to tell it was done well. |
brief.owner |
string | yes | The existing team and role that should own it. |
brief.trigger |
string | yes | When it runs: on demand, on a schedule said in words, or after another task. |
brief.inputs |
string | yes | What it needs each time it runs. |
brief.tools |
string | yes | The connected tools it needs, naming any that is not connected. |
brief.limits |
string | yes | What it must never do, what needs approval, and its budget. |
No other fields are accepted.
- Effect: write.
- Retry: Idempotent: a repeat of the same call acts once, or leaves the same state. Keyed on the conversation and the tool call: the same call sent twice starts one run.
- Called by: the CEO chat, the API.
- Offered in: a conversation opened for
create_taskonly, never in a member's everyday thread. - Returns:
{ runId, status, taskId }: the run designing the task. - API:
POST /v1/tasks/from-brief(tasks:write)
| Error | When | What happens |
|---|---|---|
brief_required |
brief is missing, or says nothing about what the job is. |
Tool error |
task_designer_not_found |
The enterprise has no task-designing task to hand the brief to. | Tool error |
Example:
{
"brief": {
"goal": "Chase unpaid invoices",
"success": "Every invoice over 30 days old gets one polite reminder",
"owner": "Finance team, accounts role",
"trigger": "Every Monday morning",
"inputs": "The list of overdue invoices",
"tools": "Email, which is connected",
"limits": "Never contact a customer twice in a week; refunds need approval; two dollars a run"
}
}
os.list_runs
The enterprise's runs, newest first, a page at a time.
What the model reads:
List the enterprise's runs, newest first, one page at a time. Each run carries its status, task (id, name, slug), the member it runs as, its input, and when it was created, started and finished. The response is { data, total, page, limit, pages }.
| Field | Type | Required | Description |
|---|---|---|---|
status |
string, one of pending, queued, running, waiting_on_gate, waiting_on_run, paused_spend, succeeded, failed, cancelled, skipped_overlap, blocked |
no | Only runs in this status. |
taskId |
string | no | Only runs of this task. |
live |
boolean | no | true for only runs still in progress: not finished, and not blocked or paused on spend. |
page |
integer, at least 1 | no | The page to read, from 1. Defaults to 1. |
limit |
integer, 1 to 200 | no | Runs per page, up to 200. Defaults to 25. |
No other fields are accepted.
- Effect: read.
- Retry: Safe: repeating the call changes nothing.
- Called by: the API, the OS MCP server.
- Returns:
{ data, total, page, limit, pages }, each run with its status, task, member, input and times. - API:
GET /v1/runs(runs:read)
Example:
{
"status": "failed",
"limit": 5
}
os.kpi_board
The enterprise's KPI board: every signed-off company KPI and each team's key KPI, with its light.
What the model reads:
The enterprise's KPI board, as HQ shows it: every company KPI the owner has signed off and each team's key KPI with its light (red off target, amber at risk, green on target), its trend (up, down, flat), when it was last read, the cadence it is read on, and whether that reading is overdue. A KPI nobody has read yet has no light (`rag` is null): it is never read and overdue, not green. A KPI still waiting for sign-off is not on the board. A team that has set no key KPI is named with none rather than left out. The response is { enterprise, teams }. Read-only: recording a reading is not a tool here.
Takes no arguments: no fields are accepted.
- Effect: read.
- Retry: Safe: repeating the call changes nothing.
- Called by: the API, the OS MCP server.
- Returns:
{ enterprise, teams }: each signed-off company KPI, and each team with its key KPI orkey: nullwhen it has none. Every KPI carries its light, trend,lastReadAt,cadenceDaysand whether it isoverdue— derived from the readings themselves, so it matches HQ's board KPI for KPI. - API:
GET /v1/enterprise/kpis(enterprise:read)
os.list_enterprise_kpis
Every KPI of the enterprise, with its owner, target, cadence, light and last reading.
What the model reads:
List every KPI of the enterprise, whatever layer owns it and whether or not it has been signed off, ordered by name then id. Each row carries its id (the kpiId the readings tools take), name, owner (layer and id), source (kind and ref), target (value, direction, AMBER band, on-target-worsening rule), cadence, current light, whether it is overdue, when it was signed off (null while it waits for sign-off, when it takes no reading), and its latest reading. The light is null when the KPI has no target or no reading yet. No arguments. Never another enterprise's KPIs.
Takes no arguments: no fields are accepted.
- Effect: read.
- Retry: Safe: repeating the call changes nothing.
- Called by: the API, the OS MCP server.
- Returns: One row per KPI, each with
id,name,ownerLayer(company,team,role,task, or null for a company KPI set before layers),ownerId,sourceKind(taskorperson),sourceRef,target,cadenceMinutes,light,overdue,signedOffAt(ISO 8601, or null) andlastReading(id,value,takenAt,recordedBy,runId), or null before the first reading. - API:
GET /v1/kpis(kpis:read)
Example:
{}