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
- Validates
manifest.jsonagainst the plugin Zod schema. - Verifies all
requiredEnvvars are present; refuses to load if any is missing. - Dynamic-imports
handlerEntry, picks the default export, fills in thedefinitionfrom the manifest. - Returns ready-to-register
Toolobjects.
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
permissionsblock parses cleanly but is advisory until enforcement lands. - Hot-reload in dev.
- Loading plugins from an npm-published package.