Agent Apps Docs

Implement tools

Register tools, health checks, and handlers with the @agentapps/sdk.

Implement your tools

Use createApp() from @agentapps/sdk to build your app.

Register a tool

app.tool(name, config)

The config object includes:

  • description — what the tool does
  • parameters — JSON Schema describing the input
  • annotations — declarative hints (see below)
  • handler — async function that receives a ToolContext and returns the result

Register a health check

app.health(handler)

Produce an AppFactory

app.toFactory()

Produces an AppFactory for the controller to use when spawning instances.

ToolContext capabilities

The ToolContext (ctx) passed to your handlers provides:

CapabilityDescription
ctx.logStructured logging
ctx.progressProgress reporting
ctx.streamStreaming responses
ctx.signalAbortSignal for cancellation
ctx.secrets.getSystemGet system-level secrets
ctx.secrets.getUserGet user-level secrets
ctx.auth.getStatusCheck auth status
ctx.requestAuthRequest interactive OAuth authentication (returns AuthResult with accessToken)
ctx.storageKey-value storage scoped to installationId (get, set, delete, list)
ctx.volumeVolume file storage — POSIX-style filesystem operations (list, read, write, delete, stat, getTempPath)
ctx.shareSharing layer — create and revoke public URLs for files in the volume (share, revoke)
ctx.intentCross-app tool invocation via intents
ctx.emitEmit an event
ctx.requestAuthRequest interactive auth
ctx.openUrlOpen a URL in the user's browser

ctx.storage — key-value storage

Persistent key-value store scoped to the current installation. Use it for preferences, cached data, and small app state.

// Store and retrieve a value
await ctx.storage.set('user:preferences', { theme: 'dark' });
const prefs = await ctx.storage.get('user:preferences');

// List keys with a prefix
const keys = await ctx.storage.list('user:');

// Delete a key
await ctx.storage.delete('user:preferences');

ctx.volume — volume file storage

POSIX-style filesystem operations against the workspace volume. Paths are relative to the volume root (no leading slash). All installations in a workspace share the same volume.

// Write a file
await ctx.volume.write('output/report.json', new TextEncoder().encode(JSON.stringify(data)));

// Read it back
const bytes = await ctx.volume.read('output/report.json');
const content = bytes ? new TextDecoder().decode(bytes) : null;

// List a directory
const entries = await ctx.volume.list('output');

// Get file metadata
const stat = await ctx.volume.stat('output/report.json');

// Get a temp path (scoped to the current session)
const tmpPath = ctx.volume.getTempPath('scratch.json');

ctx.share — public URL sharing

Create and revoke public URLs for files stored on the volume. Useful when your tool produces a file that the user needs to download or share.

// Create a public URL for a volume file
const result = await ctx.share.share('output/report.json', {
  expiresIn: 3600, // expires in 1 hour
});
console.log(result.url); // https://...

// Revoke the URL when no longer needed
await ctx.share.revoke(result.url);

ctx.intent — cross-app tool invocation

Call a tool on a bound app (declared in your app's requires manifest). The host resolves the binding, opens a session to the target app, calls the tool, and returns the result.

// Call the "send_message" tool on a bound messaging app
const result = await ctx.intent('messenger', 'send_message', {
  channel: '#general',
  text: 'Hello from my app!',
});

Tool annotations

Annotations are declarative hints about the tool's behavior:

  • readOnlyHint — tool does not modify state
  • destructiveHint — tool may destroy data
  • idempotentHint — repeated calls with same args produce same result
  • openWorldHint — tool interacts with external systems

Secrets

Always use SDK callbacks (ctx.secrets.getSystem / ctx.secrets.getUser). Never write .secrets/ files directly.

Next steps