<!-- Generated by `just docs` from catalog/toolkits/atmon.yaml, catalog/expansions/atmon.yaml, catalog/evals/scorecard.json. Edit the source, not this file. -->

# atmon

This project's own atmon node. Read its connections, its call ledger, its jobs, its approvals, and its spend.

| Property | Value |
| --- | --- |
| Slug | `atmon` |
| Definition version | `0.1.0` |
| Base URL | `https://api.atmon.ai` |
| Auth schemes | `api_key` |
| Action tools | 9 |
| By class | 8 read, 1 write |
| Triggers | 0 |
| Provider rate limit | not declared, so outbound calls are unpaced |

## Measured routing accuracy

29 golden cases replayed through the router over the whole index: measured over corpus `ea4f12ad2948` (65 toolkits, 2283 tools indexed and 13 declared uncallable), 9 cases written by hand and 18 cases from the paraphrase pass, plus 2 context cases whose intent names no app and is decided by the session. A case counts as top-1 when its gold tool ranked first and top-8 when it reached the slate at all.

| Measure | Cases | Share |
| --- | --- | --- |
| top-1 | 24/29 | 82.8% |
| top-8 | 28/29 | 96.6% |

The sweep is offline: the reranker is a deterministic identity fake that returns candidates in the order retrieval produced them, so top-1 measures retrieval order rather than a reranked slate. `just eval-live` measures the same cases through the live reranker.

## Authentication

Connect an entity with `ConnectionsService.InitiateConnection`, naming this toolkit's slug. Credentials stay in the connections vault; callers hold connected-account ids only.

### `api_key`

| Property | Value |
| --- | --- |
| Placement | `header` |
| Name | `Authorization` |
| Rendered as | `Bearer {key}` |

Submit the key with `ConnectionsService` rather than putting it in a request; it is sealed at rest and never returned.

## Tools

9 action tools. The catalog-wide slug is `atmon.<tool>`, which is what `search_tools` returns and `call_tool` takes.

### `atmon.list_connected_apps`

List which apps this atmon project holds connected accounts for, with each account's status, its owner, and the scopes granted. Use to see which integrations a person has already authorized and can act through, and to spot a vendor account that expired. Narrow to one person or one app.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.ConnectionsService/ListConnectedAccounts`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `entity_id` | string | no | Only this person's accounts. Omit for every account in the project. |
| `toolkit_slug` | string | no | Only accounts for this app, e.g. "slack". Omit for every app. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `connectedAccounts` | array of object |  |
| `connectedAccounts[].accountVariables` | object |  |
| `connectedAccounts[].authScheme` | string |  |
| `connectedAccounts[].createdAt` | string (date-time) |  |
| `connectedAccounts[].credentialKind` | string |  |
| `connectedAccounts[].entityId` | string |  |
| `connectedAccounts[].grantedScopes` | array of string |  |
| `connectedAccounts[].id` | string |  |
| `connectedAccounts[].status` | string | CONNECTION_STATUS_ACTIVE, _PENDING, _EXPIRED, or _REVOKED. |
| `connectedAccounts[].toolkitSlug` | string |  |

Also retrieved by: "which services do we already have hooked up", "is there a live account for this vendor yet", "what integrations does this customer hold", "did anyone authorize github for us", "has this user's token gone stale", "who has signed in to which provider", "do we hold a working login for that tool".

### `atmon.request_connection`

Start connecting an app for one person in this atmon project and hand back the sign-in link that authorizes it. It creates a pending connection only: a human finishes by granting consent or pasting a key, so nothing is authorized here. Use when an action failed because the integration was never hooked up.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.ConnectionsService/InitiateConnection`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `account_variables` | object | no | The per-customer parts of the app's address, keyed by the name the app declares, e.g. {"subdomain": "acme"}. Omit for an app whose host is the same for every customer. |
| `auth_scheme` | string | no | Which declared scheme to connect under: "oauth2", "api_key", or "basic". Omit for the app's default. |
| `entity_id` | string | **yes** | The person this connection is for, as your product names them. |
| `redirect_uri` | string | no | Where the person lands once the provider redirects back. |
| `requested_scopes` | array of string | no | Provider scopes to ask for. Omit to take the app's defaults. |
| `toolkit_slug` | string | **yes** | The app to connect, e.g. "github". Read it from get_app. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `authorizationUrl` | string | Where to send the person. Empty for a scheme that takes a pasted credential instead. |
| `connectedAccountId` | string |  |

Also retrieved by: "get me a url to authorize slack", "how do I hook a vendor up for this customer", "start the oauth handshake for notion", "send the user somewhere to sign in to the provider", "kick off account setup for an integration", "this person needs to grant us access first", "nothing is hooked up yet, begin the sign-in".

### `atmon.get_app`

Look up one app in this atmon project's catalog by slug: what it is, which credential schemes the vendor entry accepts, which category it sits in, and whether it is shared or private to this project. Use to check a slug before asking anybody to connect it. It reports the entry, never an account; list_connected_apps answers that.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.CatalogService/GetToolkit`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `slug` | string | **yes** | The app's slug, e.g. "notion". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `toolkit` | object |  |
| `toolkit.authSchemes` | array of string |  |
| `toolkit.category` | string |  |
| `toolkit.description` | string |  |
| `toolkit.name` | string |  |
| `toolkit.ownerProjectId` | string | Empty for an app in the shared catalog, set for one this project registered. |
| `toolkit.slug` | string |  |
| `toolkit.version` | string |  |

Also retrieved by: "what is this integration and how does it authenticate", "does a slug like hubspot exist in the registry", "which credential styles does that vendor support", "tell me what the linear entry says", "is that a shared app or one we registered ourselves".

### `atmon.list_tool_calls`

List this atmon project's ledger rows for one person, newest first: what each action did, its status, its error code, and how long it took. Use to see the recent activity for a customer, why a provider refused an attempt, or whether something is parked waiting on a human. Narrow by tool or by cause.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.ExecutionService/ListToolCalls`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `entity_id` | string | no | Whose calls to read. Required unless principal_chain_prefix is given. |
| `page_size` | integer | no | Rows per page. |
| `page_token` | string | no | The nextPageToken of the previous page. |
| `principal_chain_prefix` | array of string | no | Only calls whose cause opens with these hops, in order, e.g. ["job:job_123"] for one job's calls. It crosses people, so entity_id may be omitted when this is given. |
| `tool_slug` | string | no | Only calls to this tool, e.g. "slack.post_message". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `nextPageToken` | string |  |
| `toolCalls` | array of object |  |
| `toolCalls[].approvalId` | string |  |
| `toolCalls[].entityId` | string |  |
| `toolCalls[].errorCode` | string |  |
| `toolCalls[].errorDetail` | string |  |
| `toolCalls[].finishedAt` | string (date-time) |  |
| `toolCalls[].id` | string |  |
| `toolCalls[].jobId` | string |  |
| `toolCalls[].startedAt` | string (date-time) |  |
| `toolCalls[].status` | string | TOOL_CALL_STATUS_SUCCEEDED, _FAILED, _DENIED, _PENDING_APPROVAL, or _RUNNING. |
| `toolCalls[].stepId` | string |  |
| `toolCalls[].toolSlug` | string |  |

Also retrieved by: "what has the assistant actually done lately", "show me recent activity for this customer", "why was the last action refused", "history of everything we ran for this user", "which of our requests are stuck on somebody", "audit trail of attempts over the past day".

### `atmon.get_tool_call`

Read one atmon ledger row in full by its id: the arguments sent, the shaped result returned, the error code and detail, the approval it parked on, and the job step behind it. Use to pull up the whole record of one attempt, why that single execution failed, or what payload it answered with.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.ExecutionService/GetToolCall`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string | **yes** | The ledger row's id, as list_tool_calls reports it. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `toolCall` | object |  |
| `toolCall.approvalId` | string |  |
| `toolCall.argumentsJson` | string |  |
| `toolCall.connectedAccountId` | string |  |
| `toolCall.entityId` | string |  |
| `toolCall.errorCode` | string |  |
| `toolCall.errorDetail` | string |  |
| `toolCall.finishedAt` | string (date-time) |  |
| `toolCall.id` | string |  |
| `toolCall.jobId` | string |  |
| `toolCall.principalChain` | array of string |  |
| `toolCall.relayId` | string |  |
| `toolCall.resourceUrn` | string |  |
| `toolCall.resultJson` | string |  |
| `toolCall.resultTruncated` | boolean | True when a shaping cap cut data the tool's output schema declared. |
| `toolCall.startedAt` | string (date-time) |  |
| `toolCall.status` | string |  |
| `toolCall.stepId` | string |  |
| `toolCall.toolSlug` | string |  |

Also retrieved by: "open that ledger row and show its arguments", "what exactly came back from that request", "pull up the record for id tc_123", "why did that one attempt error out", "the whole detail of a single execution by identifier".

### `atmon.list_jobs`

List the bulk jobs this atmon project submitted, newest first, with each run's status, timing, and failure text. Use to see which batches are still going, which stopped for a human decision, and which finished overnight. Narrow by status, by submission mode, or by the skill that submitted it.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.JobsService/ListJobs`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `mode` | string | no | Only this submission mode: "run", "simulate", or "shadow". |
| `page_size` | integer | no | Jobs per page. |
| `page_token` | string | no | The nextPageToken of the previous page. |
| `skill_slug` | string | no | Only the jobs one promoted skill submitted. |
| `status` | string, one of JOB_STATUS_PENDING_PLAN_APPROVAL, JOB_STATUS_RUNNING, JOB_STATUS_PARKED, JOB_STATUS_SUCCEEDED, JOB_STATUS_FAILED, JOB_STATUS_CANCELED | no | Only jobs in this state. Omit for every state. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `jobs` | array of object |  |
| `jobs[].createdAt` | string (date-time) |  |
| `jobs[].finishedAt` | string (date-time) |  |
| `jobs[].id` | string |  |
| `jobs[].lastError` | string |  |
| `jobs[].mode` | string |  |
| `jobs[].planApprovalId` | string |  |
| `jobs[].programHash` | string |  |
| `jobs[].skillSlug` | string |  |
| `jobs[].status` | string |  |
| `jobs[].updatedAt` | string (date-time) |  |
| `nextPageToken` | string |  |

Also retrieved by: "what bulk runs are going right now", "did the batch we submitted finish", "show me everything queued or stopped", "which of our runs failed overnight", "is the work we kicked off last night done".

### `atmon.get_job`

Read one atmon job by id: its status, the receipt with row counts and cost, what it stopped on and which person was asked to decide, and the outcome of every step. Use to follow a submitted bulk run to the end, or to learn how far along it got and what a stalled one waits for.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.JobsService/GetJob`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string | **yes** | The job's id, as list_jobs or a submission reports it. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `job` | object |  |
| `job.createdAt` | string (date-time) |  |
| `job.finishedAt` | string (date-time) |  |
| `job.id` | string |  |
| `job.lastError` | string |  |
| `job.mode` | string |  |
| `job.park` | object |  |
| `job.park.approvalId` | string |  |
| `job.park.at` | string (date-time) |  |
| `job.park.reason` | string |  |
| `job.park.stepId` | string |  |
| `job.planApprovalId` | string |  |
| `job.programHash` | string |  |
| `job.receipt` | object |  |
| `job.receipt.complete` | boolean |  |
| `job.receipt.dropped` | object |  |
| `job.receipt.rowsIn` | integer |  |
| `job.receipt.rowsOut` | integer |  |
| `job.receipt.simulated` | boolean |  |
| `job.skillSlug` | string |  |
| `job.status` | string |  |
| `job.stepReceipts` | array of object |  |
| `job.stepReceipts[].finishedAt` | string (date-time) |  |
| `job.stepReceipts[].outputHandle` | string |  |
| `job.stepReceipts[].stepId` | string |  |

Also retrieved by: "how far along is that batch run", "what does the receipt for this run say", "why is that bulk run stuck", "read back the outcome of every step", "who was asked to decide on this run".

### `atmon.list_pending_approvals`

List the atmon approvals waiting on a person in this project: which action stopped, for whom, with which arguments, and when the wait runs out. Use to see what is blocked until somebody signs off, and to tell that person what needs deciding. It reads the review queue and settles nothing, which stays a console decision.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.PolicyService/ListPendingApprovals`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `page_size` | integer | no | Approvals per page. |
| `page_token` | string | no | The nextPageToken of the previous page. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `approvals` | array of object |  |
| `approvals[].argumentsJson` | string |  |
| `approvals[].createdAt` | string (date-time) |  |
| `approvals[].entityId` | string |  |
| `approvals[].expiresAt` | string (date-time) |  |
| `approvals[].id` | string |  |
| `approvals[].note` | string |  |
| `approvals[].state` | string |  |
| `approvals[].toolSlug` | string |  |
| `nextPageToken` | string |  |

Also retrieved by: "what is sitting in the review queue", "which actions are blocked on a person", "who has to sign off before this goes through", "show me everything held for a decision", "what needs a human before it can move", "is anything waiting on my sign-off right now".

### `atmon.get_spend`

Read what this atmon project has spent against what its budgets allow: model money in micro-dollars, action counts, and provider calls, bucketed by day, by app, or by person. Use before committing expensive work, or to answer how much a customer cost and which ceiling is close.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /automaton.v1.GovernanceService/GetSpend`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `from` | string (date-time) | no | Inclusive start, RFC 3339. Omit for unbounded. |
| `group_by` | string, one of day, toolkit, entity | no | How to bucket the totals. Defaults to day. |
| `to` | string (date-time) | no | Exclusive end, RFC 3339. Omit for unbounded. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `buckets` | array of object |  |
| `buckets[].actions` | string |  |
| `buckets[].key` | string |  |
| `buckets[].modelMicroUsd` | string |  |
| `buckets[].providerCalls` | string |  |
| `budgets` | array of object |  |
| `budgets[].consumedActions` | string |  |
| `budgets[].consumedModelMicroUsd` | string |  |
| `budgets[].consumedProviderCalls` | string |  |
| `budgets[].entityId` | string |  |
| `budgets[].maxActions` | string |  |
| `budgets[].maxModelMicroUsd` | string |  |
| `budgets[].maxProviderCalls` | string |  |
| `budgets[].resetsAt` | string (date-time) |  |
| `budgets[].scope` | string |  |
| `budgets[].toolkitSlug` | string |  |
| `budgets[].window` | string |  |
| `groupBy` | string |  |

Also retrieved by: "how much have we burned this month", "what are we paying for model usage", "are we close to any of our ceilings", "break the cost down by app", "how expensive has this customer been".
