Write a custom tool for your agent in TypeScript or Python.
Tools you write in code come in two languages, TypeScript and Python. This guide covers both. Pick the tab for your language in each step. Both kinds are bundled into the binary at compile time, so there is no runtime installation. For the full field reference, see the tool reference.
TypeScript tools run in an embedded JavaScript runtime. Python tools use RustPython by default,
which supports pure-Python packages and needs no Python installation at runtime. Select the
static interpreter to use CPython 3.14 for packages with C extensions. Both use the agentc tool
development kit (TDK), which gives you typed tool definitions.
Generate a ready-to-use package with agentc tool init, then install its dependencies.
agentc tool init math --language javascript
cd math
pnpm installThis creates a ready-to-use package with the entry point, package metadata, and editor type
support already configured. agentc.d.ts is one line, and it is what tells an editor the shape of
the runtime surface.
The compiler installs dependencies with the package manager configured for the scaffolded package.
A tool has a name, a description, a JSON Schema for its inputs, and an execute function. The name and
descriptions are what the model reads to decide when and how to call it, so write them carefully.
Export a tool object from the package entry point. Import the Tool type from the TDK for full type
coverage.
import type { Tool, ToolInput, ToolOutput } from "@agentc-sh/tdk";
type AddArgs = { a: number; b: number };
export const adder: Tool<AddArgs, number> = {
name: "adder",
description: "Adds two numbers together.",
parameters: {
type: "object",
properties: {
a: { type: "number", description: "The first number." },
b: { type: "number", description: "The second number." }
},
required: ["a", "b"]
},
async execute(input: ToolInput<AddArgs>): Promise<ToolOutput<number>> {
return { output: input.args.a + input.args.b };
}
};A single package can export as many tools as you need.
JavaScript tools do not run in Node. They run in an embedded JavaScript engine, and the environment
they see is assembled by the host, so it is neither Node's nor a browser's. The runtime libraries the
host does provide live under the agentc: prefix and are imported like any other module.
import { fetch } from "agentc:http";
const response = await fetch("https://example.com");agentc:http also installs fetch, Headers, and Response as globals, as the same values it
exports, so the import is optional for those three.
const response = await fetch("https://example.com");The runtime libraries are catalogued at runtime libraries, and the JavaScript surface the host binds is enumerated at standard.
The shapes of all of it come from @agentc-sh/runtime, which the scaffold installs and references for
you, so your editor reports what the host actually provides rather than guessing. The package is
optional. A component that does not depend on it compiles and runs identically.
The scaffold does not depend on @types/node, and its tsconfig.json sets types to an empty array
so nothing pulls it in. The guest is not a Node process, and @types/node describes a great deal that
the host never binds.
The package exists, but the agent does not see it until you declare a tool block pointing source at
the package directory.
tool "adder" {
kind = "javascript"
source = "./math"
}The block name matches the export name by default. If they differ, set export to the export name.
A tool can return a state_update alongside its output: an array of RFC 6902 JSON Patch operations.
For the ReAct graph, target paths under /context/. The patches are persisted and streamed to the
client as state delta events, which is how a tool passes data to a frontend.
async execute(input: ToolInput<AddArgs>): Promise<ToolOutput<number>> {
return {
output: input.args.a + input.args.b,
state_update: [
{ op: "add", path: "/context/last_sum", value: input.args.a + input.args.b }
]
};
}Rebuild so the tool is bundled into the binary:
agentc buildtool block for each kind.© 2026 pogue.dev. All rights reserved.
CC BY 4.0Search the agentc documentation