05 / 10 · SYSTEM DESIGN

Tools: turn model proposals into authorized actions

Design validation, authorization, idempotency, and reconciliation around external effects.

Content reviewed:

Design question

Who authorizes an AI action, and how do we establish whether it happened?

First read the whole diagram. Expand “Read at full size” to inspect the labels and scroll horizontally, then trace the failure path.

A tool call does not grant authority

Tools connect model output to search, files, scheduling, and other external capabilities. Valid JSON does not establish the caller's permission. Validate arguments, authorize execution, and establish the outcome as separate decisions. This is an original reference architecture, not a claim about deployed Kumyu features.

Require that actions affect only authorized resources, retries do not multiply business effects, and unknown outcomes never appear as success. A prohibition in a tool description does not implement any of these invariants. Enforce them in the server holding authority.

Flow: proposal, validation, execution

A server subjects a model proposal to schema validation, authorization, and required approval before calling an external API and recording the result
Read at full size (scroll horizontally)
A server subjects a model proposal to schema validation, authorization, and required approval before calling an external API and recording the result
Figure 1: Trust boundaries around tools Open full-size diagram ↗

The model's arrow in Figure 1 represents an untrusted proposal. Accept only allowed tool names and validate schema, lengths, enum values, and resource ownership. Bind the actor from authenticated context, not from a model-supplied user ID.

The MCP 2025-06-18 Tools specification defines tool metadata, input schemas, and the tools/list and tools/call messages. That wire contract does not supply application-specific authorization. Treat externally supplied annotations as descriptive data, not proof that an operation is safe.

Read operations can still disclose secrets. For writes, classify reversibility, external notification, money movement, and permission changes. Derive confirmation and audit requirements from those effects. Place guardrails at the execution boundary as well as the language boundary.

State and operation identity

A normalized proposal is approved by content hash, recorded under an operation ID, executed, and reconciled against the external result
Read at full size (scroll horizontally)
A normalized proposal is approved by content hash, recorded under an operation ID, executed, and reconciled against the external result
Figure 2: Proposal to committed outcome Open full-size diagram ↗

Use proposed → validated → approved → executing → succeeded, with distinct failed and unknown outcomes. A policy decision can approve an operation that needs no human confirmation. If confirmation is required, display target, content, and recipients, then bind approval to their canonical hash. Modified arguments require another check.

{
  "operation_id": "op-example",
  "tool": "create_calendar_event",
  "arguments_hash": "example-digest",
  "actor_id": "user-example",
  "resource_id": "calendar-example",
  "state": "executing",
  "external_reference": null
}

This unexecuted example distinguishes a logical business operation from a transport request. A retry may have a new transport ID while retaining the operation ID. Enforce uniqueness for the local operation record. A database unique constraint protects that local record; it does not extend a database transaction into an external API.

Failure: timeout is not proof of failure

An external operation succeeds but its response is lost; the ledger records unknown and reconciles before choosing a final outcome
Read at full size (scroll horizontally)
An external operation succeeds but its response is lost; the ledger records unknown and reconciles before choosing a final outcome
Figure 3: Recovering an ambiguous outcome Open full-size diagram ↗

Suppose a reservation exists but its response disappeared. Marking failure and retrying blindly can create a duplicate. AWS explains the side-effect ambiguity of timeouts.

If an API supports idempotency keys, map the operation ID to its documented contract. Verify scope, retention, and behavior when arguments change. Otherwise reconcile with an external reference or business key. If neither is possible, stop at unknown and assign human reconciliation. Define the conditions for avoiding duplicate effects before optimizing retry convenience.

Compensation is not rollback. Cancelling a reservation may notify its recipient, so it cannot restore a world where nothing happened. Record the original effect, compensation outcome, and user explanation separately. Text returned by a tool also does not authorize its own requested follow-up. Treat it as input data and route every new action through the same checks.

Tradeoffs

Execution model Benefit Remaining concern
Read-only tools Avoid external mutations Disclosure and read authorization
Automatic action within policy Fast routine work Explicit scope and auditing
Confirmation bound to content User can inspect the target action Changes and approval expiry
Asynchronous execution ledger Tracks long-running work Ownership of unknown-outcome reconciliation

Worked design: create one meeting

Fix the calendar, participants, and times from user intent. The server verifies write access, time formats, and an end after the start. Confirmation includes participant notifications. After checking that the approved hash matches execution arguments, create the operation record and call the provider.

Two tabs submitting the same operation converge on one ledger entry. Only the caller that wins an atomic conditional transition from approved to executing may invoke the provider. Losing callers observe the existing operation instead of issuing another external call. Without provider idempotency, that ledger alone cannot eliminate the crash window around the external call. Acknowledge this limitation and define reconciliation from unknown. Monitor outcomes by tool, age of unknown operations, authorization denials, and budget exhaustion. Avoid recording sensitive argument bodies indiscriminately.

Exercise and suggested answer

A model proposes “send it again because it failed.” The first call timed out and its external outcome remains unverified. Should the server follow that suggestion?

Record unknown and check the provider's idempotency or lookup mechanism first. Establish the result before showing success or authorizing a safe retry. A model judgment cannot replace external verification. Keep types, permission, business-operation identity, and observed outcome separate.

What to take away

Models propose arguments. Servers decide permission and execution conditions.

Sources & further reading

  1. MCP 2025-06-18: ToolsContent reviewed: 2026-10-23
  2. AWS: Timeouts, retries, and backoff with jitterContent reviewed: 2026-10-23
  3. PostgreSQL 18: ConstraintsContent reviewed: 2026-10-23

These are conceptual reference architectures for learning and design discussions. They do not describe the deployed Kumyu infrastructure.

← Browse all chapters