Skip to content

Capabilities

A capability is the unit of domain behavior that an Invokta engine publishes. Its definition contains five required fields:

const capability = defineCapability({
description,
input,
output,
access,
run,
});

The capability ID is not part of this object. The engine assigns it as a key:

const engine = createEngine({
name: "support-engine",
version: "1.0.0",
capabilities: {
"support.classify-ticket": capability,
},
});

This lets a capability library provide a default ID while a consuming engine keeps authority over its final public namespace.

Form Boundary Start here
Local capability Used by one engine package Dependency injection recipe
Atomic export One reusable capability published from a package root or subpath Atomic export recipe
Capability library A related set with stable default IDs Capability library recipe

The consuming engine may combine all three forms with explicit selection and ID remapping. The capability packages guide covers package exports, import variants, collision diagnostics, versioning, and the trusted-code boundary.

Field Responsibility
description Explain the domain outcome to people and tool consumers
input Validate and transform the object received from a caller
output Validate and transform the object returned by run
access Declare public, authenticated, or domain-specific authorization
run Execute the capability with validated input and an execution context

title, timeoutMs, and MCP-compatible annotations are optional.

Input and output schemas must satisfy both Standard Schema v1 and Standard JSON Schema v1. The first contract gives Invokta validation and type inference. The second gives adapters a portable description of the same data.

Both schemas need an object root and must produce values in the lossless JSON data model.

const summarize = defineCapability({
description: "Summarize one support ticket.",
input: z.object({ ticketId: z.string().min(1) }),
output: z.object({ summary: z.string() }),
access: "authenticated",
async run({ input, context }) {
context.signal.throwIfAborted();
return { summary: await summarizeTicket(input.ticketId) };
},
});

public

Accepts a null principal. Use it only when the domain action is intentionally available without identity.

authenticated

Requires a validated principal. Identity is supplied by the composition root or HTTP authentication boundary.

function

Receives the principal, a protected input snapshot, context, and capability ID. It grants access only by returning true.

access: ({ principal, input }) =>
principal?.attributes?.tenantId === input.tenantId,

run receives a minimal context:

interface ExecutionContext {
requestId: string;
source: "direct" | "cli" | "mcp-stdio" | "mcp-http";
principal: Principal | null;
signal: AbortSignal;
logger: EngineLogger;
}

Dependencies such as repositories, model clients, and data providers should be injected through a factory or closure. The context is not a service container.

See the invocation pipeline for the order in which Invokta applies these fields, or the @invokta/core reference for their complete public types.