Skip to main content

Documentation Index

Fetch the complete documentation index at: https://redop.useagents.site/docs/llms.txt

Use this file to discover all available pages before exploring further.

Shape

app.tool("tool_name", {
  title: "Optional UI title",
  description: "What the tool does",
  inputSchema: z.object({
    query: z.string(),
  }),
  outputSchema: z.object({
    query: z.string(),
  }),
  taskSupport: "optional",
  annotations: {
    readOnlyHint: true,
    idempotentHint: true,
  },
  middleware: [myToolMiddleware],
  before: async ({ input, ctx }) => {},
  after: async ({ result }) => result,
  afterResponse: async ({ result, error }) => {},
  handler: async ({ input, ctx, request, tool, emit, signal }) => {
    return { query: input.query };
  },
});

Fields

FieldRequiredPurpose
descriptionNoHuman-readable description shown to clients.
inputSchemaNoSchema used for runtime parsing and tool discovery.
outputSchemaNoStructured output schema surfaced to clients when the result is an object. Accepts the same supported schema styles as inputSchema.
titleNoUI-friendly display title.
iconsNoTool icons for clients that support them.
annotationsNoBehavioral hints forwarded to clients. Redop does not enforce them automatically.
middlewareNoMiddleware scoped to this tool only.
beforeNoTool-local hook that runs before middleware and the handler.
afterNoTool-local hook that runs after a successful result and may replace it.
afterResponseNoTool-local hook that runs after the response is written. Receives either result or error and cannot replace the response.
taskSupportNoTask support hint: "forbidden", "optional", or "required".
handlerYesTool implementation.

Handler event

The handler receives:
  • input for parsed tool input
  • ctx for mutable per-request context
  • request for transport metadata
  • tool for the resolved tool name
  • emit.progress(...) for progress updates
  • signal for cancellation support

annotations

annotations help clients reason about tool behavior before they call it.
FieldMeaningTypical use
readOnlyHintThe tool reads data and does not mutate state.Search, list, inspect, preview, validate.
destructiveHintThe tool may make hard-to-undo or high-impact changes.Delete, cancel, revoke, overwrite, charge.
idempotentHintRepeating the same call should have the same effect without compounding side effects.Sync, replace, ensure-state, upsert.
openWorldHintThe tool depends on external or live information beyond the server’s local state.Web search, external APIs, live SaaS lookups.
Notes:
  • annotations are hints for clients and agents, not runtime enforcement
  • tools can combine multiple hints when they describe different aspects of behavior
  • avoid contradictory hints such as readOnlyHint: true and destructiveHint: true

Notes

  • If you omit inputSchema, the handler receives the raw params object.
  • outputSchema is exported to clients as JSON Schema, but Redop does not validate returned values against it at runtime.
  • Prefer explicit names such as notes.list or billing.invoice.create when a tool belongs to a feature area.
  • afterResponse is the right place for per-tool analytics, impressions, and logging that should happen after the client response.
  • Tool-local hooks are the right place for per-tool post-processing.
  • Shared concerns belong in global hooks or plugins instead.

See also