Custom tools let you give your agent new capabilities beyond the built-in set — anything from sending notifications to querying an internal API. Clanka integrates with Effect’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Effectful-Tech/clanka/llms.txt
Use this file to discover all available pages before exploring further.
Tool and Toolkit APIs so that each tool is fully typed, schema-validated, and composable with the rest of your Effect application.
How tools work in Clanka
When the agent executes a script, every tool in the toolkit is injected into the VM sandbox as a plain async JavaScript function:await yourTool(params). The agent sees each function as a TypeScript declare function declaration (generated by ToolkitRenderer) in the system prompt, so it knows the exact parameter shape and return type.
The parameter types are rendered from the Schema you provide to Tool.make. For example, a struct schema produces a typed object literal declaration, while a plain Schema.String produces a string argument named after the schema’s identifier annotation.
Building a custom tool
Declare the tool with Tool.make()
Use The
Tool.make from effect/unstable/ai/Tool to define the tool’s name,
description, parameter schema, success schema, and any context dependencies.dependencies array tells Clanka which context services to inject when
the handler runs. Built-in services you can request are described below.Group tools into a Toolkit with Toolkit.make()
Wrap one or more tools in a If you have several custom tools, pass them all to a single
Toolkit so they can be merged and provided
together.Toolkit.make
call. You can also merge toolkits with Toolkit.merge.Implement handlers with toolkit.toLayer()
Call The handler receives the decoded parameters as its first argument. Yield any
Effect-based logic you need — file system access, HTTP calls, logging — and
return the success value.
.toLayer() on the toolkit to produce an Effect Layer that provides
the handler implementations.Provide the toolkit to Agent.layerLocal()
Pass your toolkit to the The type signature of
tools option of Agent.layerLocal. Clanka
automatically merges it with the built-in tools and makes the handlers
available in the VM sandbox.layerLocal enforces that every handler required by
your toolkit — except the three built-in context services — is provided
before the layer is used.Context services available to handlers
Custom tool handlers run inside the same Effect context as the built-in tools. You can declare any of the following in your tool’sdependencies array and then yield them in your handler.
CurrentDirectory
CurrentDirectory
Type: Use it to resolve relative file paths inside your handler.
stringThe absolute path of the working directory the agent is operating in.
Declared in AgentTools.ts as:SubagentExecutor
SubagentExecutor
Type:
(prompt: string) => Effect.Effect<string>A function that spawns a sub-agent with the given prompt and returns its
final summary. Useful if your tool needs to delegate work to another agent
run.TaskCompleter
TaskCompleter
Type:
(output: string) => Effect.Effect<void>Signals task completion with a final summary string. The built-in
taskComplete tool uses this service. Only declare it as a dependency if
your custom tool should be able to terminate the agent’s current task.How parameter types appear in the system prompt
ToolkitRenderer converts each tool’s Schema into a TypeScript declare function declaration and injects it into the agent’s system prompt. Given the notify tool above, the agent sees:
Tool names must be valid JavaScript identifiers. If a parameter schema has an
identifier annotation (Schema.String.annotate({ identifier: "path" })),
that annotation is used as the argument name in the declaration.