ZOYYA documentation

Authoring a tool plugin

Authoring a tool plugin

Plugin authoring is available for hand-rolled local tools today. The manifest format and the loader are stable enough to write against; per-org install/enable, runtime permission enforcement, hot-reload in dev, and npm-published plugins aren't wired up yet. See apps/agent/src/tools/plugin.ts for the canonical types.

Minimal example

// apps/agent/src/tools/greet/manifest.json
{
  "name": "greet",
  "version": "0.1.0",
  "description": "Greets a name",
  "parameters": {
    "type": "object",
    "properties": { "name": { "type": "string" } },
    "required": ["name"]
  },
  "permissions": { "network": [], "fs": [], "exec": [] },
  "requiredEnv": [],
  "handlerEntry": "./index.ts"
}

// apps/agent/src/tools/greet/index.ts
import type { Tool } from "../types"

const tool: Tool<{ name: string }, { said: string }> = {
  definition: { /* filled by loader */ } as never,
  handler: async ({ name }) => ({ said: `Hello, ${name}!` }),
}

export default tool

What the loader does

  1. Validates manifest.json against the plugin Zod schema.
  2. Verifies all requiredEnv vars are present; refuses to load if any is missing.
  3. Dynamic-imports handlerEntry, picks the default export, fills in the definition from the manifest.
  4. Returns ready-to-register Tool objects.

Not yet implemented

  • Per-org enable/disable settings (enabling a plugin only for orgs that opted in).
  • Network / filesystem / exec permission enforcement at runtime — the manifest's permissions block parses cleanly but is advisory until enforcement lands.
  • Hot-reload in dev.
  • Loading plugins from an npm-published package.