api reference

defineAction

API reference for defineAction() and defineActions().

defineAction() creates a typed, AI-callable action. It is the primary API of the Capability Plane.

Import

ts
import { defineAction, defineActions } from "@next-ai-ready/actions"

`defineAction<I, O>(def)`

Creates a single action definition. Returns the same object (identity function).

ts
const search = defineAction({
  name: "search_products",
  description: "Search the product catalogue.",
  whenToUse: "When the user wants to find products.",
  public: true,
  input: z.object({ query: z.string() }),
  output: z.object({ items: z.array(z.object({ id: z.string(), title: z.string() })) }),
  handler: async ({ query }) => {
    return { items: await db.search(query) }
  },
})

Parameters

FieldTypeRequiredDescription
namestringyesUnique identifier. Must match ^[a-z][a-z0-9_]*$ (snake_case).
descriptionstringyesHuman-readable description. Shown in OpenAPI and MCP tool lists.
whenToUsestringrecommendedGuidance for AI agents on when to call this action.
whenNotToUsestringnoNegative guidance — when NOT to call this action.
inputZodSchemayesZod schema for the input. Converted to JSON Schema at build time.
outputZodSchemanoZod schema for the output. Included in OpenAPI spec.
tagsstring[]noCategorization tags. Appear in OpenAPI tags field.
examples{ input, output? }[]noExample invocations. Used by AI agents for context.
publicbooleannoDefault false. Must be true for HTTP/MCP exposure.
auth`(req: Request) => boolean \Promise<boolean>`noPer-action auth gate. Runs before handler.
handler`(input, ctx) => Promise<O> \O`yesThe action implementation.

ActionContext

The second argument to handler:

FieldTypeDescription
requestRequestOriginal HTTP request.
headersHeadersRequest headers.
cookiesobjectcookies.get(name) returns { value } or undefined.
callerstring?"http" or "mcp".

`defineActions(actions)`

Registers an array of actions. Returns the same array. Used as the default export of your actions module:

js
import { defineActions } from "@next-ai-ready/actions"
import search from "./search.js"
import getOrder from "./get-order.js"

export default defineActions([search, getOrder])

Calling defineActions() has a side effect: it populates the global action registry. This is intentional — the build CLI and runtime handlers both rely on the registry being populated when the module is imported.

`invokeAction(name, input, ctx)`

Programmatically invoke an action. Returns a discriminated union:

ts
const result = await invokeAction("search_products", { query: "shoes" }, ctx)
if (result.ok) {
  console.log(result.data)      // typed output
} else {
  console.error(result.code)    // "not_found" | "not_public" | "unauthorized" | "invalid_input" | "handler_error"
  console.error(result.message)
}
FieldTypeDescription
okbooleanWhether the invocation succeeded.
dataOOutput (only when ok is true).
actionstringAction name.
latencyMsnumberHandler execution time.
statusnumberHTTP status code (only when ok is false).
codestringError code (only when ok is false).
messagestringError message (only when ok is false).
detailsunknownZod issues (only when code is "invalid_input").