<!-- Generated by `just docs` from proto/automaton/v1/catalog.proto. Edit the source, not this file. -->

# CatalogService

Read what exists: the apps atmon can reach, the tools each one brings, and one tool's full definition. Most callers reach this through search rather than by browsing, and use it to draw their own connect screen.

Every call is a POST to `https://api.atmon.ai/automaton.v1.CatalogService/<Call>` with a JSON body, and authenticates with `Authorization: Bearer <your project key>`. Field names in JSON are lowerCamelCase, so the field written `tool_slug` below is `toolSlug` on the wire. [How to call the API](./index.md) has the whole convention.

## Calls

| Call | Request | Response | Summary |
| --- | --- | --- | --- |
| `ListToolkits` | `ListToolkitsRequest` | `ListToolkitsResponse` | Lists the toolkits the caller can see: the shared catalog, plus the caller's own private toolkits when a project is named. |
| `GetToolkit` | `GetToolkitRequest` | `GetToolkitResponse` | Reads one toolkit by slug. |
| `ListTools` | `ListToolsRequest` | `ListToolsResponse` | Lists tools, optionally narrowed to one toolkit or one kind. |
| `GetTool` | `GetToolRequest` | `GetToolResponse` | Reads one tool's full definition by its catalog-wide slug: description, both JSON Schemas, required scopes, and access class. |
| `GetToolkitConnectSpec` | `GetToolkitConnectSpecRequest` | `GetToolkitConnectSpecResponse` | Reads what a connect form for one toolkit needs: the templated base URL, the account variables the address is built from, and the schemes a connection can be made under. |

### ListToolkits

Lists the toolkits the caller can see: the shared catalog, plus the
caller's own private toolkits when a project is named.

Request `ListToolkitsRequest`, response `ListToolkitsResponse`.

```http
POST /automaton.v1.CatalogService/ListToolkits HTTP/1.1
Host: api.atmon.ai
Authorization: Bearer amk_your_project_key
Content-Type: application/json

{
  "projectId": "..."
}
```

The response:

```json
{
  "toolkits": [{
    "slug": "...",
    "name": "...",
    "description": "...",
    "version": "...",
    "authSchemes": ["..."],
    "ownerProjectId": "...",
    "category": "...",
    "connectable": true,
    "connectability": "TOOLKIT_CONNECTABILITY_READY"
  }]
}
```

### GetToolkit

Reads one toolkit by slug. A project-owned entry wins over a shared entry
with the same slug.

Request `GetToolkitRequest`, response `GetToolkitResponse`.

```http
POST /automaton.v1.CatalogService/GetToolkit HTTP/1.1
Host: api.atmon.ai
Authorization: Bearer amk_your_project_key
Content-Type: application/json

{
  "slug": "...",
  "projectId": "..."
}
```

The response:

```json
{
  "toolkit": {
    "slug": "...",
    "name": "...",
    "description": "...",
    "version": "...",
    "authSchemes": ["..."],
    "ownerProjectId": "...",
    "category": "...",
    "connectable": true,
    "connectability": "TOOLKIT_CONNECTABILITY_READY"
  }
}
```

### ListTools

Lists tools, optionally narrowed to one toolkit or one kind. An agent
should resolve an intent through the router rather than enumerate this.

Request `ListToolsRequest`, response `ListToolsResponse`.

```http
POST /automaton.v1.CatalogService/ListTools HTTP/1.1
Host: api.atmon.ai
Authorization: Bearer amk_your_project_key
Content-Type: application/json

{
  "toolkitSlug": "...",
  "kind": "TOOL_KIND_ACTION",
  "projectId": "..."
}
```

The response:

```json
{
  "tools": [{
    "slug": "...",
    "toolkitSlug": "...",
    "kind": "TOOL_KIND_ACTION",
    "description": "...",
    "inputSchemaJson": "{}",
    "outputSchemaJson": "{}",
    "requiredScopes": ["..."],
    "ownerProjectId": "...",
    "accessClass": "..."
  }]
}
```

### GetTool

Reads one tool's full definition by its catalog-wide slug: description,
both JSON Schemas, required scopes, and access class. This is what the MCP
describe_tool meta-tool answers with.

Request `GetToolRequest`, response `GetToolResponse`.

```http
POST /automaton.v1.CatalogService/GetTool HTTP/1.1
Host: api.atmon.ai
Authorization: Bearer amk_your_project_key
Content-Type: application/json

{
  "slug": "...",
  "projectId": "..."
}
```

The response:

```json
{
  "tool": {
    "slug": "...",
    "toolkitSlug": "...",
    "kind": "TOOL_KIND_ACTION",
    "description": "...",
    "inputSchemaJson": "{}",
    "outputSchemaJson": "{}",
    "requiredScopes": ["..."],
    "ownerProjectId": "...",
    "accessClass": "..."
  }
}
```

### GetToolkitConnectSpec

Reads what a connect form for one toolkit needs: the templated base URL,
the account variables the address is built from, and the schemes a
connection can be made under. It carries no credential and no endpoint a
credential is presented to.

Request `GetToolkitConnectSpecRequest`, response `GetToolkitConnectSpecResponse`.

```http
POST /automaton.v1.CatalogService/GetToolkitConnectSpec HTTP/1.1
Host: api.atmon.ai
Authorization: Bearer amk_your_project_key
Content-Type: application/json

{
  "slug": "...",
  "projectId": "..."
}
```

The response:

```json
{
  "spec": {
    "toolkitSlug": "...",
    "baseUrlTemplate": "...",
    "accountVariables": [{ ... }],
    "authSchemes": [{ ... }]
  }
}
```

## Messages

### AccountVariableSpec

AccountVariableSpec is one entry of a toolkit's account_variables: a fact
about the customer's own deployment that the connection captures and the
base URL renders. Description is the sentence the connecting person is asked
for it with, and Example is a well-formed answer.

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `name` | `string` | 1 |  |
| `description` | `string` | 2 |  |
| `example` | `string` | 3 | empty when the toolkit declared none |
| `decides_origin` | `bool` | 4 | Whether this value decides the address the deployment dials: the registrable domain, the host, or the port. False means it fills a label under a host the toolkit itself wrote down. InitiateConnection requires the approver role when a toolkit declares one, so a form that asks for it can say so before anyone fills it in. |

### GetToolRequest

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `slug` | `string` | 1 |  |
| `project_id` | `string` | 2 | Set to a project id to also see that project's private tools. Empty resolves against the shared catalog only. |

### GetToolResponse

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `tool` | `Tool` | 1 |  |

### GetToolkitConnectSpecRequest

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `slug` | `string` | 1 |  |
| `project_id` | `string` | 2 | Set to a project id to also resolve that project's private toolkits. Empty resolves against the shared catalog only. |

### GetToolkitConnectSpecResponse

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `spec` | `ToolkitConnectSpec` | 1 |  |

### GetToolkitRequest

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `slug` | `string` | 1 |  |
| `project_id` | `string` | 2 | Set to a project id to also see that project's private toolkits. Empty resolves against the shared catalog only. |

### GetToolkitResponse

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `toolkit` | `Toolkit` | 1 |  |

### ListToolkitsRequest

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `project_id` | `string` | 1 | Set to a project id to list the shared catalog plus that project's private toolkits. Empty lists the shared catalog only. |

### ListToolkitsResponse

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `toolkits` | repeated `Toolkit` | 1 |  |

### ListToolsRequest

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `toolkit_slug` | `string` | 1 | empty lists across all toolkits |
| `kind` | `ToolKind` | 2 | unspecified lists both kinds |
| `project_id` | `string` | 3 | Set to a project id to list shared tools plus that project's private tools. Empty lists shared tools only. |

### ListToolsResponse

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `tools` | repeated `Tool` | 1 |  |

### Tool

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `slug` | `string` | 1 | "github.create_issue" |
| `toolkit_slug` | `string` | 2 |  |
| `kind` | `ToolKind` | 3 |  |
| `description` | `string` | 4 | LLM-facing, tuned for routing and selection |
| `input_schema_json` | `string` | 5 | JSON Schema for arguments |
| `output_schema_json` | `string` | 6 | JSON Schema for results |
| `required_scopes` | repeated `string` | 7 |  |
| `owner_project_id` | `string` | 8 | empty means the shared catalog |
| `access_class` | `string` | 9 | Blast radius: read \| write \| destructive, from the toolkit definition. Execution's mutation gate keys off it, so a caller can tell before it calls which tools hold until the agent passes confirm. |

### Toolkit

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `slug` | `string` | 1 | "github", "slack" |
| `name` | `string` | 2 |  |
| `description` | `string` | 3 |  |
| `version` | `string` | 4 | version of the toolkit definition, not the app |
| `auth_schemes` | repeated `string` | 5 | "oauth2", "api_key", "none" |
| `owner_project_id` | `string` | 6 | empty means the shared catalog |
| `category` | `string` | 7 | Browsing taxonomy slug, one of twelve closed-set categories: "communication", "work-tracking", "developer-infrastructure", and so on. Every toolkit carries exactly one; the catalog loader refuses a definition that names none or names one outside the set. |
| `connectable` | `bool` | 8 | Whether an account can be created for this toolkit on this deployment at all. A client reads this rather than deriving it from connectability, so a value it does not recognize leaves the app offered rather than silently disabled. |
| `connectability` | `ToolkitConnectability` | 9 | Why connectable reads the way it does. |

### ToolkitAuthSchemeSpec

ToolkitAuthSchemeSpec is one scheme a connection to the toolkit can be made
under, with the fields that scheme's form needs. The type-specific fields are
empty for the types they do not apply to.

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `type` | `string` | 1 | oauth2 \| api_key \| basic \| none |
| `default_scopes` | repeated `string` | 2 | oauth2: what the consent request asks for |
| `key_placement` | `string` | 3 | api_key: header \| query |
| `key_name` | `string` | 4 | api_key: the header or query-parameter name |

### ToolkitConnectSpec

ToolkitConnectSpec is what a connect form for one toolkit is built from:
where its calls go, the per-customer values the address is built from, and
the schemes a connection can be made under.

The scheme list is narrower than Toolkit.auth_schemes, which reports every
scheme the toolkit declares. A client_credentials scheme is absent here
because no connected account is made under it: the project holds that
credential and InitiateConnection refuses the scheme by name.

| Field | Type | # | Notes |
| --- | --- | --- | --- |
| `toolkit_slug` | `string` | 1 |  |
| `base_url_template` | `string` | 2 | The declared base_url with its {{account.<name>}} placeholders still in it, so a form can render the host it is building as the values are typed. |
| `account_variables` | repeated `AccountVariableSpec` | 3 | in declaration order |
| `auth_schemes` | repeated `ToolkitAuthSchemeSpec` | 4 | in declaration order |

## Enums

### ToolKind

| Value | # | Meaning |
| --- | --- | --- |
| `TOOL_KIND_UNSPECIFIED` | 0 |  |
| `TOOL_KIND_ACTION` | 1 | agent-initiated call into the external app |
| `TOOL_KIND_TRIGGER` | 2 | app-initiated event delivered to the agent |
| `TOOL_KIND_CODE` | 3 | agent-initiated call into code this platform runs: a sandboxed module, or a job program a project promoted from one of its own finished jobs (a project skill). |

### ToolkitConnectability

ToolkitConnectability says what stands between a toolkit and a connected
account on this deployment. It is deployment state, not catalog data: the
same toolkit definition answers differently on a node whose operator has
registered its OAuth app and on a node that has not.

| Value | # | Meaning |
| --- | --- | --- |
| `TOOLKIT_CONNECTABILITY_UNSPECIFIED` | 0 |  |
| `TOOLKIT_CONNECTABILITY_READY` | 1 | Every scheme the toolkit declares can be connected here. |
| `TOOLKIT_CONNECTABILITY_NEEDS_OAUTH_REGISTRATION` | 2 | The toolkit declares only schemes that need an OAuth client id and secret registered on this deployment, and it holds none. Nothing can connect. |
| `TOOLKIT_CONNECTABILITY_OAUTH_PENDING` | 3 | The toolkit also declares a scheme that needs no operator registration (api_key, basic), so it connects today under that one, while its oauth2 path waits on a registration. |
