> ## Documentation Index
> Fetch the complete documentation index at: https://actelos.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> How tools are modeled, listed, gated, and invoked

A **tool** is a single callable operation provided by a service. The OpenAPI
adapter, for example, generates one tool per operation in the source
document.

## Tool Shape

The canonical shape is `ToolDefinition` from `@cyrnel/sdk`:

```ts theme={null}
interface ToolDefinition {
  id: string;
  name: string;
  description: string;
  inputSchema: JSONSchema;
  outputSchema: JSONSchema;
  adapterDomain: Record<string, unknown>;
}
```

On disk:

* `(serviceId, id)` is the composite primary key. Tool `id` must be a valid
  TypeScript identifier.
* `name` is human-friendly; `id` is what code addresses.
* `enabled` is per-tool, a service can be enabled with some of its tools
  disabled.

## Endpoints

| Method | Path                                | Notes                           |
| ------ | ----------------------------------- | ------------------------------- |
| `GET`  | `/tools`                            | List & filter                   |
| `GET`  | `/tools/:serviceId/:toolId`         | Single tool (with schemas)      |
| `GET`  | `/tools/:serviceId/:toolId/docs`    | Markdown reference for the tool |
| `POST` | `/tools/:serviceId/:toolId/enabled` | `{ enabled: boolean }`          |

### Filtering `/tools`

Query parameters (all optional):

* `serviceId`: Restrict to one service
* `query`: Case-insensitive substring match against `name` and `description`
* `enabled`: `true` / `false`
* `limit`: Positive integer

The list response includes a derived `effectivelyEnabled` flag:
`tool.enabled && service.enabled`. Use it when deciding what to surface to
clients.

### Tool docs

`GET /tools/:serviceId/:toolId/docs` returns `text/markdown` generated by
the active environment module's `generateToolDocs`. The bundled
`typescript-ivm` renders a usage page including:

* the tool description
* a typed parameter list derived from `inputSchema`
* the return shape derived from `outputSchema`
* a copy-pasteable `cyrnel.services[...].tools[...].invoke(...)` snippet

If the environment is the bundled one, the docs are stable. If you write a
custom environment that exposes a different runtime surface (e.g. Python),
its `generateToolDocs` should render an example in that runtime.

## Invocation From Code

The environment bindings expose tools for direct invocation:

```ts theme={null}
const result = await cyrnel.services.weather.tools.forecast.invoke({ city: "..." });
cyrnel.output({ result });
```

See [`EnvironmentBindings`](/cyrnel/specs/environment-bindings).

## Invocation Gating

`cyrnel.invoke` rejects with a structured error when:

| Condition                          | Status |
| ---------------------------------- | ------ |
| Service does not exist             | `404`  |
| Tool does not exist on the service | `404`  |
| Service is disabled                | `409`  |
| Tool is disabled                   | `409`  |

These checks happen *before* the adapter is called, so a disabled tool
cannot incur an outbound request.
