Agent API reference
The surfaces an AI agent uses to interact with the Fabric platform.
An agent reaches the platform through one of three surfaces. All three end up calling the same invokeAction core.
Surfaces
| Surface | Where | Best for |
|---|---|---|
| MCP server | apps/mcp | LLMs speaking Model Context Protocol (Claude, etc.). |
| TypeScript SDK | packages/sdk-typescript | Agents written as TypeScript services. |
| Python SDK | packages/sdk-python | Agents written in Python. |
Each is a thin client over the same oRPC procedures. There is no agent-specific data path.
What an agent actually does
1. Authenticate with a credential.
2. Discover the actions in the credential's scope.
3. (Optionally) preview an action — see what would happen without writing.
4. Invoke an action — actually run it.
5. Read events / projections to observe results.Discovery
The MCP server publishes actions in the credential's scope as MCP tools. Each tool's input schema is the action's Zod schema; each tool's description includes the action ID, namespace, summary of side effects, and the policies it gates against.
For SDK callers, the action registry exposes:
import { getRegisteredActionIds, resolveAction } from "@fabricorg/platform/actions";
const ids = getRegisteredActionIds();
const def = resolveAction("lending.accept_offer");
// def.schema, def.policies, def.emitsEvents, def.idempotent, ...Preview vs invoke
The platform distinguishes preview from invoke at the mode field on PolicyContext:
interface PolicyContext<TDb> {
...
mode?: "preview" | "execute";
}A preview runs the policy stage with mode: "preview", returning the would-be outcome without running the handler. A code policy can mark itself previewSafe: true to opt into preview evaluation. Preview is the right surface for an agent that wants to ask "would this be allowed?" before committing.
Calling an action
Conceptually:
await fabric.actions.invoke({
actionId: "lending.send_offer",
parameters: { borrowerId, vehicleId, rateApr, termMonths, amount },
});The MCP server / SDK wraps this with credential auth. Internally:
- The middleware verifies the credential and confirms the action ID is in scope.
invokeActionis called withactorType: "agent"andactorId: <credential subject>.- The pipeline runs through policies, state-machine validation, handler, events, adapters.
- The result returns once the action completes.
Reading the results
An agent observes outcomes by reading events. Two query shapes:
By correlation ID
const events = await fabric.events.list({
tenantId,
correlationId,
});Returns every event tied to the action chain (including child sagas).
By subject
const events = await fabric.events.list({
tenantId,
subjectType: "Offer",
subjectId: offerId,
});Returns the offer's full event history in per-subject sequence order.
AgentRun — binding a session
A multi-turn agent conversation typically opens an AgentRun and stamps every action with its ID:
const run = await fabric.agentRuns.start({ purpose: "borrower_assist", openedBy: agentId });
await fabric.actions.invoke({
actionId: "lending.summarize_offer",
parameters: { offerId },
agentRunId: run.id,
});
await fabric.agentRuns.close(run.id);The agentRunId is propagated as causationId (or stored alongside) so audit queries by AgentRun return every downstream invocation.
Scope design
A credential's scope is a list of allowed action IDs:
read scope:
lending.list_offers
lending.summarize_offer
lending.get_party
write scope:
lending.send_offer (gated by agent-specific policy)
lending.request_consent (gated by rate-limit policy)Wide scopes are technically possible (lending.*) but discouraged. Audit queries become more useful when scopes are narrow.
Anti-patterns
- Treating action IDs as URLs. They are stable identifiers in audit logs forever. Renames are not free.
- Bundling multiple actions into one "agent action." If the agent needs to do three things, each is a separate action with its own audit row.
- Using one credential for many agents. Credentials are revocation units. Per-agent or per-deployment.
See also
- Architecture → agent-native — the design.
- Patterns → agents within policy — designing agent-callable actions.
- Examples — runnable snippets.