agntz
RuntimeHostedSelf-hostDocsChangelog
Sign inQuickstart
Documentation
View .mdOptimized for LLMs — paste directly into ChatGPT, Claude, or Cursor.

Local tools

Local tools are functions registered at runtime and referenced by name in YAML. They are the simplest and fastest tool kind — no network and no auth — but they only work in embedded mode because hosted workers cannot execute arbitrary user code.

agents/calculator.yaml
id: calculator
kind: llm
model: { provider: openai, name: gpt-5.4-mini }
instruction: |
  Use the `add` tool to answer math questions.

  {{userQuery}}
tools:
  - kind: local
    tools: [add]
index.ts
import { agntz, tool, z } from "@agntz/sdk";

const client = await agntz({
  agents: "./agents",
  tools: [
    tool({
      name: "add",
      description: "Add two numbers and return the sum",
      input: z.object({
        a: z.number().describe("First operand"),
        b: z.number().describe("Second operand"),
      }),
      execute: async ({ a, b }) => a + b,
    }),
  ],
});

Names referenced in YAML but missing from the local tool registry fail before a successful run. This keeps misconfigurations out of production traffic.

Tool shape

Each tool is self-describing. The model sees the name, description, and JSON Schema derived from your validation schema.

TypeScript fieldPython fieldPurpose
namenameIdentifier referenced from YAML tools: [name]
descriptiondescriptionWhat the tool does; read by the model
inputinput_schemaZod or Pydantic schema used for validation and JSON Schema
executeexecuteFunction called with parsed args
import { tool, z } from "@agntz/sdk";

const tools = [
  tool({
    name: "fetchInvoice",
    description: "Look up an invoice record by its id",
    input: z.object({
      id: z.string().describe("Invoice id, e.g. inv_abc123"),
    }),
    execute: async ({ id }) => {
      return await db.invoices.findById(id);
    },
  }),
];

TypeScript uses Zod because @agntz/sdk already depends on it. Python uses Pydantic because it is the native validation and schema path for Python applications.

Selective exposure

By default, listing tools: [foo, bar] exposes exactly those tools. To expose all configured tools, drop the inner array:

tools:
  - kind: local            # all tools in the registry

Errors

If a tool throws, the model receives the error message and can decide whether to retry with different args, reply to the user, or give up. The error is captured in the tool span and appears in traces.

Validation errors are returned to the model the same way, so a model that calls add({ a: "two", b: 3 }) sees a structured complaint and can correct itself on the next step.

Why embedded-only?

Note: Local tools are an embedded-mode primitive. The hosted edition has no way to run arbitrary user code in a sandbox, so promote local tools to HTTP endpoints or MCP servers when you graduate. The YAML can switch between local and HTTP/MCP without touching the agent's instruction — only the tools: block changes.

If you want a single manifest that runs in both local and hosted modes, prefer HTTP or MCP tools from the start.

← Previous
Skills, spawnable, reply
Next →
HTTP tools