The tool catalog
Search the tool catalog, read an exact schema, then run a capability.
The tool catalog is the discovery path for work Architect, MCP, the CLI, and REST can perform. Use it when you know the outcome but do not have a current capability contract, and use it again when workspace state or a provider connection may have changed.
The catalog protects a run from stale or invented identifiers: search for candidates, inspect an exact contract, then run only the contract delivered in the current turn. Route a broad outcome through Packs first when its owner is known, and review Credits and billing before a live action can spend credits.
Search, get, then run
Search is the normal entry point. Give it a goal in plain language or explicit query terms, and optionally scope the request to a pack. Search ranks the active workspace catalog and returns candidates, a turn token, and top runnable_contracts. A returned contract marked fetched: true is already available to run in that turn.
Get reads one exact capability contract by id. An exact get does not require a previous search, because a ranking response can omit a valid known capability. Both search and a get with no turn token mint the current tool turn. Architect remembers contracts delivered in the conversation so it can use their schema without treating a previously fetched contract as an invented tool.
Run receives the capability id, its parameter object, a required mode, and the bound tool-turn token. The gateway uses the fetched contract to validate the input, scopes, action policy, cost policy, and asynchronous handling. A caller does not manufacture a token or replace the returned schema with a guessed parameter list.
The response follows the canonical envelope. A successful result carries its result data and metadata. A state-bearing result can carry a web_url for the corresponding app object, while the JSON identifier is the durable reference for another capability, run, or agent turn.
| Control | Arguments | Required | Result |
|---|---|---|---|
tools_search | goal or query_terms, optional pack scope, optional limit | goal or query_terms | Candidates, runnable_contracts, and tool_turn_token. |
tools_get | capability_id | Yes | Exact capability schema and a tool-turn token. |
tools_run | capability_id, params, mode, tool_turn_token; optional max_credits and quote fields | Contract and mode | Capability result or structured refusal with repair. |
Scope discovery without changing authority
A pack scope narrows search, but it does not grant authority or change the thirteen shared door controls. Architect and MCP call the field pack_id. REST and the CLI call the same wire-level filter toolset. The server maps the REST and CLI filter back to the pack identity so a scoped response can explain that discovery was restricted to that pack.
Scope a known domain because an unscoped search ranks the goal against every capability in the catalog. Shared words, a job title, or a city can otherwise rank an unrelated record, inbox, or knowledge feature ahead of the intended workbook or sequence operation. A route followed by a scoped search is therefore a practical way to keep a multi-domain goal aligned with the result that owns it.
Search results can identify a preferred composite operation when one contract builds an entire object. This is discovery guidance, not an instruction to skip schema review. Read the fetched input and output shape, confirm the workspace and pack, and verify the action policy before choosing a composite capability over several smaller writes.
Capability availability is workspace-specific. A public provider profile or a capability name in another workspace is not evidence that the selected workspace can use it. If a task depends on a provider, inspect Integrations and rediscover the operation after a connection changes. The catalog result, not a remembered provider label, is the readiness source.
Find the capability that reads this workspace credit balance. Route the goal first if needed, fetch the exact input and output contract, then show the contract without running it.Read the contract and choose the mode
The exact descriptor is the source for input fields, output fields, required scopes, pack id, action policy, cost policy, and asynchronous policy. It can say whether an operation is read-only, internally reversible, sending, publishing, enrolling, activating, or test-running. Do not infer any of those facts from a capability prefix, a marketing profile, or a superficially similar operation.
Every mutating call must explicitly name a mode. The server does not default a call to live and returns mode_required when a mutation omits one. Some contracts support only dry-run and live, so the fetched schema remains the authority for the allowed choices on a particular operation.
Use smoke_test when a caller needs only static schema and policy inspection. Use dry_run when the caller needs real workspace validation and a preview without business writes, provider spend, or outward action. Use live only for a deliberate execution after the contract, recipient, sender, connection, and cost conditions have been checked. This ordering makes an agent's first action explanatory rather than irreversible.
A tool contract does not replace the owner-action security boundary. Provider credentials, billing, ownership, API keys, webhooks, and related root actions require a signed-in session, fresh approval at the applicable tier, and an idempotency key. An API key cannot perform that signed-in owner flow. See Owner actions for its separate requirements.
| Mode | What it does | Write policy |
|---|---|---|
smoke_test | Static schema and policy inspection. | No business write and no audit entry. |
dry_run | Validation against real workspace state. | No business write, provider spend, or outward action. |
live | Execution of the fetched capability. | The fetched action policy determines the effect. |
Credits, quotes, and run results
The catalog uses the credit classes free, action, and dynamic. Credit class is only one part of the decision: the returned action policy tells the client the consequence, and the cost policy tells it how the exact capability is priced. Fetch both before assuming that a provider-backed or mutation-like name has a particular cost.
A live call that needs pricing returns quote_required with an estimate. Re-run the same live call with unchanged parameters and a max_credits ceiling. The server binds the quote to that tool turn. Architect's adapter explicitly tells the model not to copy a quote hash, because the gateway retains that binding for the returned turn rather than asking the caller to invent it.
The CLI fetches a turn token for tools run when one was not supplied. It caches a token only while a quote is pending, then forgets it after a paid run is admitted. CLI output deliberately omits the tool-turn token, so a terminal transcript does not become a reusable catalog contract. Use --turn-token only when the caller already has the current token for the contract it is running.
A run can return immediately or represent asynchronous work according to its contract. Use the run controls to read state, events, or cancellation status when the result names a run. The CLI waits for a terminal run state by default with a 120-second timeout; --no-wait returns an immediate response instead. This behavior does not alter the capability contract or the state of the underlying run.
When it goes wrong
If a run returns capability_not_fetched, search or get the exact capability in the current turn and run the contract that response supplied. The refusal includes a repair that names the needed get call. Do not retry the same guessed id or attempt to create a tool-turn token locally.
If the gateway returns catalog_changed or tool_turn_expired, the previous tool turn is retired. Architect removes that stale token and starts a fresh search. Follow the same recovery on another surface: rediscover the operation, read the new schema, and then validate the new contract before retrying a mutation.
If input parsing returns invalid_request, read the published schema and correct the parameter object. A malformed tools-run request receives a repair with the instruction to match the published schema. If the mutation lacks a mode, use the supported mode instead of expecting the server to select live.
If live work returns quote_required, preserve the parameters and apply an intended maximum credit ceiling. If a provider is missing or an account is not connected, fix that external readiness in Integrations, then search again. If a recipient is suppressed or a sender is unavailable, investigate the sender policy and sequence state rather than re-running the capability unchanged.
If an exact get says the capability is already fetched, retain the schema it returned earlier in the same conversation. If the model context no longer contains that schema, the adapter can deliberately forget the remembered contract so get delivers it again. This protects a compacted conversation from running a capability whose required fields are no longer visible to the agent.
If a search appears too broad, obtain the pack route and retry with its scope. If it appears too narrow, confirm that the outcome really belongs to the pack instead of removing the scope without explanation.
If a result contains a run identifier, read its current state before issuing a new execution request. This avoids creating a second attempt merely because an asynchronous result was not immediately terminal.
Keep a search result and its descriptor together in the work record. The result records why the capability was selected, while the descriptor records the fields and policy used for the attempted run.
The capability id alone is never enough evidence to reconstruct an earlier contract.
Refresh discovery when contract state is uncertain.
Then inspect the fresh result.