@voyant-travel/tools
v0.10.0
Published
The transport-neutral agent tool contract for the Voyant framework (voyant#2792).
Downloads
38,426
Readme
@voyant-travel/tools
The transport-neutral agent tool contract for the Voyant framework (voyant#2792).
Capabilities are authored once, headless, and scope-gated; exposure (MCP, remote
agents, HTTP) is a thin adapter over this contract. Tool handlers return typed pure
data validated by an outputSchema — never transport envelopes or presentation.
Shape
defineTool({ capabilityId?, owner?, capabilityVersion?, name, aliases?, description, inputSchema, outputSchema, requiredScopes, audience?, tier, riskPolicy, annotations?, resolveActionTarget?, handler })— a headless tool. Graph-driven hosts bind the stable package Tool id and owner; standalone tools should declare them directly.Ctxwidens by intersection so a domain injects its services (ToolContext & { trips: … }) without this package depending on the domain.ToolContext—{ db, actor, audience, tenantId, resolverScope, waitUntil?, toolActionPolicy? }. The optional gate is supplied by graph hosts and called by transport adapters before selected action dispatch.RiskTier+RiskPolicy— declarative risk data (destructive / reversible / dry-run / side effects) so remote consumers and the MCP layer gate approvals without executing tool code (D1).createToolRegistry()—register/registerAll/get/names/list/prepareAction/dispatchPrepared/dispatch.prepareActionvalidates input once and resolves the package target; only the same registry can dispatch that admitted parsed value.dispatchvalidates input, runs the handler, then validates output.list()returns the discovery manifest with real JSON Schema (zod v4z.toJSONSchema), capability identity/version, owner, aliases/deprecation, audience,requiredScopes, MCP annotations,tier, andriskPolicy. Aliases dispatch to the canonical definition; capability lookup may require an exact supported version.- Graph bindings add an
actionPolicyto discovery. Generic transports pass the command and reserved invocation controls throughToolActionPolicyGate; the action-ledger package owns the implementation.actionPolicyEnforcement: "handler"is reserved for Tools whose existing package handler already performs the same selected-policy approval and ledger workflow. - Generic ledgered actions resolve their target deterministically after domain input validation.
A Tool may define
resolveActionTarget(parsedArgs, ctx)for a complex target. Otherwise an existing-target action declarescommandTargetField, and the registry reads that field from the already parsed input. Ledgered read collections without such a field use an authenticated${targetType}:${tenantId}collection anchor. Migrated actions advertise their exacttargetResolution; for those actions MCP clients supply an opaque UUIDrequestId, explicitconfirmedwhen required, and an optional server-issuedapprovalId, never the target or command fingerprint. During the staged rollout only, generic executes without either package contract retain the previous invocation fields. This compatibility branch is discoverable by the absence oftargetResolutionand is removed after their package migrations land. - Actions whose canonical
targetIdis generated by the handler declaretargetLifecycle: "created"plus acreatedTargetcommand identity, result-reference type, andhandler-command-claim-v1durability contract. They must use handler enforcement: the handler claims a stable command key before mutation, returns the prior typed reference on exact replay, and commits the claim, domain mutation, and canonical generated-target result together. MCP never asks callers to invent_voyant.targetIdfor these actions. A post-dispatch target extractor is not a durable created-target strategy. For handler-owned dispatch only, MCP supplies a freshhandlerActionPolicycontext value containing the stripped invocation controls and selected policy metadata. Handlers use that request-scoped value to validate approval-required created commands without adding_voyantto their domain input schema. The MCP adapter removes any stale caller/basehandlerActionPolicybefore every dispatch and injects a fresh value only for selected handler enforcement; generic and unbound handlers never receive it. - Authorization is not enforced in the registry — the transport binds each tool's
requiredScopestohasApiKeyPermission(AND semantics).
The package depends only on zod; it never imports hono, catalog, or any domain
package.
