Declare Custom tools in the Agent create or update request, or let the SDK’s
checkfu.tools.sync(agentId, tools) helper do it. The helper reads the current Agent, keeps its non-custom tools, replaces its Custom-tool declarations through the ordinary Agent update, and reconciles the ActionPolicies that needsActionApproval requires. If you also apply the Agent from a checked-in project with checkfu agent apply, keep the declarations in that project so the next apply does not remove them. A configuration-changing update creates the next AgentVersion. Use tools.serve only for Sessions admitted from a version that contains the same declarations.acted_as Principal when serving Custom tools. That Principal needs an effective act_as PermissionAssignment on the Agent at Session admission. This admission check is separate from ActionPolicy evaluation for each Tool call. The SDK derives context.actedAs from validated admission evidence for the served Session; an API key alone does not identify the acting Principal.
The examples use the TypeScript SDK in a Node.js
worker. Start with a Session created from the AgentVersion containing these
Tools and an explicit acting Principal. See Start a Session.
supportDesk, authorizeTicketAccess, and waitForTurnSettlement below are
your application’s adapters, not SDK methods. The authorization helper must
check current access for context.actedAs against the original tenant, provider
account, ticket, and requested action. It must refuse before provider contact
when access cannot be established. Keep that account binding stable on replay.
Define handlers in your application
Keep one source of truth for each logical name, JSON Schema, and handler.
defineTool validates the recorded arguments before calling the handler and requires a JSON-representable result. New declarations use an object-root JSON Schema and stay within the SDK’s published size, depth, and value-count bounds. A Standard Schema V1 adapter can replace the explicit TypeScript cast when it also exposes the JSON Schema Checkfu should advertise.A toolUseId is unique only within its Run. The provider key therefore hashes
the original Session, Run, and Tool-use IDs. Reuse that key, account, and
exact arguments for the same effect. Never mint a fresh identity to work
around an uncertain result or refusal. This example requires a provider
whose idempotency facility prevents duplicate effects and lets you recover
or query the first result; a correlation field alone is insufficient.Declare the Tools on the Agent
Put the same logical names, descriptions, and schemas in the current Agent create or update request. Review the configuration-changing update that creates the next immutable AgentVersion.A live Session keeps the AgentVersion admitted at creation. Editing the mutable Agent later cannot add, remove, or change a Tool in that Session.
Configure ActionPolicy
Custom-tool invocation is ActionPolicy-only:
- no restricting policy means the call proceeds to its application-result wait;
denymeans the handler must not run; andrequire_approvalcreates an ActionApproval before customer execution.
close_ticket. Do not create a PermissionAssignment and describe it as part of this Tool-call path; there is no Connection or ToolSource to grant.Your application must still enforce its own tenant, account, and row-level authorization immediately before the handler effect. Checkfu policy does not replace your product’s access checks.Serve only the Sessions your worker owns
tools.serve rebuilds each named Session from its durable log and then tails from the cursor.caused_by request correlation through the helper; it does not supply authored_by.waitForTurnSettlement is your own event-driven helper. Correlate the
request to its Run and wait for that Run’s terminal outcome. A Tool wait or
approval is not completion. The race also surfaces a serving-worker failure.
Retain request-inc-42 for retries of this request; use a new request identity
only for new work.Keep credentials out of Tool data
Custodied Connection Credentials are stored separately from Tool declarations and arguments. For credentialed execution, the trusted adapter attaches them to authorized provider requests. Custody forwarding returns bounded provider response bodies, which can reflect values sent to the provider. Discovery and credential-validation HTTP requests suppress request tracing and trace propagation, and credential-validation diagnostics omit provider response bodies. Credential exclusion from Tool results, errors, logs, and traces requires qualification of the specific execution path. Your application can still leak its own secrets if it places them in arbitrary data. Never put application database passwords, provider tokens, API keys, session cookies, or private signing material into:- a Tool declaration or Agent instruction;
- Tool arguments;
user.custom_tool_result;- Session events or logs;
- Files, Git content, or Memory; or
- a sandbox environment variable.
Remote effects are not local transactions
A database transaction around this sequence is not atomic:- Provider idempotency. Pass an exact provider-supported idempotency key derived from the original Session, Run, and Tool-use IDs, as the
close_tickethandler does above. Exact replay must return or reconcile the first operation rather than perform it twice. - Durable reservation. Commit an effect intent before provider contact, move it to
dispatched, and reconciledispatchedrecords after a crash before deciding whether another request is safe. - Outbox or effect ledger. Store pre-effect intent and post-effect settlement under one local owner, and let a reconciler—not the Session-serving loop—resolve ambiguous provider outcomes.
Result posting and replay
tools.serve skips a handler when the Session log already records its result.
It correlates the Tool-use ID with the Run that opened the call. Within a live
serving loop, a prepared result is retained across supported retryable posting
failures, so the handler need not run again just to resend it.
If a result POST loses its response, retry the same payload with the same
idempotency key. The first POST may already have succeeded. For a conflict or
rejected response, the SDK accepts reconciliation only when the log contains
the exact same result for that call; a different or missing result stays
unresolved. Do not invent a new Tool-use ID or rerun the handler to settle a
result-delivery conflict.
Prepared results in worker memory do not survive a process crash. Before a
restarted worker repeats a call whose result is absent, your handler must
reconcile the original provider key or durable effect record. An absent
Session result is not proof that the provider did nothing.
Result delivery records an outcome; it neither undoes a completed external
effect nor grants permission to release its data. The example’s final access
check applies at handler return only. tools.serve can retain those result bytes
and retry the POST without calling the handler or an application authorization
callback. Revocation after handler return is not covered by that check.
If your application requires fresh downstream authorization at delivery or
retry, own the result-posting boundary and recheck release access there. Retain
the original effect identity, Tool-use ID, result payload, and posting idempotency
key; do not rerun the effect to authorize delivery. This application check is
separate from Checkfu’s current policy and Session acceptance checks. Neither
makes revocation atomic with a network POST already in flight.
If an effect completed but its result cannot be released, retain the effect’s
actual status in your authorized ledger; do not turn it into a failed effect
or repeat it.
Worker ownership and shutdown
Pass only Sessions your application owns. Keep one live worker or coordination lease per Session so two processes cannot both perform the same non-idempotent action. A failure in one Session is isolated from healthy sibling loops; the serving group reports per-Session causes when it settles. Propagatecontext.signal to downstream clients. Cancellation can stop work before dispatch, but it cannot undo an effect the provider already accepted.
Handle an approval
Build the review path for Custom tools that require a person.
Tools
Compare Custom tools with built-in and connected execution paths.