Manage tools as code
Keep your Tool definitions in your repository, review them with your code, and apply them at deploy time with ensure. ensure compares your definition with the saved Tool and creates or updates the Tool only when they differ. For related guides, see Manage Agents as code and Manage Flows as code.
To run ensure, including a dry run, your API key needs the Tools (Write) or Tools (Full) permission. To run pull, it needs Tools (Read) or Tools (Full). Tools (Write) alone doesn’t allow pull. Without the required permission, the API returns status code 403. To change a key’s permissions, see Managing API keys.
Define the tool
defineTool is a local constructor that doesn’t make network requests. It checks the top-level definition shape and returns a canonical definition object with the Tool’s name, description, toolType, parametersSchema, and config fields.
Use the following code to define a weather lookup Tool:
Set toolType to one of external, custom, graphql, mcp, local, flow, or subagent. For credentials in an external Tool’s config, use a secret reference such as {{secret:API_KEY}}, where API_KEY is the secret name. Other Tool types can’t reference secrets. A definition with secret references also needs the Secrets (Read) or Secrets (Full) permission on your API key. See Managing secrets.
ensure matches a Tool by its name within your organization or personal account. The API key
you configure selects the account and environment. If you rename a definition, ensure creates a
new Tool and leaves the old one in place, because ensure never deletes or renames Tools. If
several Tools share a name, ensure and pull act on the oldest one, so rename or delete
duplicates before you manage that name as code.
flow and subagent Tools reference saved Flows and Agents through config.flowId and
config.agentId. Raw flow_ and agent_ IDs belong to one account and environment. For portable
definitions, use name references such as flow:Order Lookup and agent:Billing Specialist.
Runtype resolves these by exact, case-sensitive name each time the Tool runs, not during ensure,
so create the Flow or Agent in each environment before the Tool runs. If several share a name,
the oldest one is used.
Apply the definition at deploy time
Configure the SDK and apply the Tool definition with the following code:
The response includes result, toolId, and contentHash. The result value is unchanged, created, or updated. When the saved Tool already matches and is managed in code, ensure sends only a content hash and writes nothing. Otherwise it sends the full definition and creates or updates the Tool, unless the Tool was edited outside code. For that case, see Resolve conflicts with dashboard edits.
The content hash covers toolType, description, parametersSchema, and config. The name isn’t part of the hash.
A created Tool is active immediately. An update takes effect right away for every Agent and Flow step that uses the Tool. Tools don’t have versions, so there’s no draft or publish step, no release: 'publish' option, and no versionId in the result. To stage a change, apply it in a separate environment or account first.
ensure doesn’t change which Agents or Flow steps use the Tool.
Troubleshoot validation errors
The API returns status code 400 when the definition fails validation for any of the following reasons:
nameis longer than 100 characters.descriptionis longer than 500 characters.- The definition has a field other than
name,description,toolType,parametersSchema, orconfig. With the SDK,defineToolrejects an unknown field before any request is sent. - The code in a
customTool fails validation. The response includeserrorsandwarningsarrays. See Creating custom tools. - A
{{secret:...}}reference is mistyped, names a secret that isn’t configured or was revoked, or appears in a Tool type other thanexternal.
Adopt an existing Tool
To bring a Tool that you created in the dashboard under code management, pull its definition first:
- Call
Runtype.tools.pull('Weather Lookup')and commit the returneddefinitionto your repository. - Run
ensure. Because the content matches,ensurereturnsunchangedand marks the Tool as managed in code.
If you skip the pull and your definition differs from a Tool that was last saved outside code, the first ensure fails with a conflict. See Resolve conflicts with dashboard edits.
Detect drift in CI
A dry run sends the full definition, writes nothing, and returns a plan. Run a dry run with the following code:
The plan includes result: 'plan', a changes value of none, create, or update, changedKeys, contentHash, and an optional remoteHash. The changedKeys array names the changed fields, such as description, parametersSchema, or config.url for a changed key within config.
To fail a CI check when the plan isn’t none, pass expectNoChanges: true. This option runs a dry run and never writes:
A dry run compares content only, so it never reports an external_modification conflict. A Tool edited in the dashboard shows as update, the same as a change in your code. To tell the two apart, call pull and check lastModifiedSource. The values sdk and terraform mean the Tool is managed in code. A value such as dashboard, api, or mcp means someone edited it outside code, and a later apply fails with a conflict.
Apply a reviewed plan
To make sure the apply step writes over the same state that the dry run inspected, pass the plan’s remoteHash as expectedRemoteHash:
If the saved Tool changed after the dry run, the SDK throws a ToolEnsureConflictError with code: 'remote_changed'. Run the dry run again and review the new plan.
Resolve conflicts with dashboard edits
Runtype records where each Tool write came from. Writes from ensure (sdk) and from the Terraform provider (terraform) count as managed in code and don’t conflict with each other. The dashboard shows a Managed in code badge on these Tools and warns you before you save an edit.
When an edit outside code, from the dashboard, the API, or the MCP server, changes a managed Tool so that it no longer matches your definition, the next ensure returns status code 409. The SDK throws a ToolEnsureConflictError with code: 'external_modification'. Its lastModifiedSource and modifiedAt fields identify the edit. If the edit left the Tool identical to your definition, ensure returns unchanged instead.
Choose one of these resolutions:
- Keep the dashboard edit: Call
pull, review the returned definition as a git diff, and commit it. The nextensurereturnsunchangedand marks the Tool as managed in code. - Keep the repository definition: Pass
onConflict: 'overwrite'to replace the dashboard edit.
An overwrite can’t be undone. Tools keep no version history, so the dashboard edit is lost. If
you might need it, run pull and save the output before you overwrite.
Pull the saved definition with the following code:
If no Tool has that name, pull fails with status code 404.
Call the API directly
If you don’t use the TypeScript SDK, send the same requests yourself. Authenticate each request with Authorization: Bearer YOUR_API_KEY, where YOUR_API_KEY is your Runtype API key.
- Send
POST /v1/tools/ensurewithnameand the fulldefinition, and omitcontentHash. The response includesresultand thecontentHashthat the server computed. Store thatcontentHash. - On later runs, send a hash-only request with
nameand the storedcontentHash:{ "name": "Weather Lookup", "contentHash": "STORED_HASH" }. ReplaceSTORED_HASHwith the value from step 1. A match returns{ "result": "unchanged" }. A miss returns{ "result": "definitionRequired" }, and you repeat step 1. - Handle status code
409forexternal_modificationandremote_changedthe same way as the SDK conflicts. Status code422withcontent_hash_mismatchmeans you sent bothdefinitionand acontentHashthat doesn’t match it.
To pull a definition, send GET /v1/tools/pull with the name query parameter. The response includes toolId, definition, contentHash, lastModifiedSource, and updatedAt.
Next steps
Continue with these guides:
- Manage Agents as code: apply Agent definitions from your repository
- Manage Flows as code: apply Flow definitions from your repository
- Creating custom tools: write the code for
customTools - Creating external tools: configure saved HTTP tools in the dashboard
- Managing secrets: store credentials for
{{secret:...}}references