Docs/Concepts
Guide source3 min read

Contracts, handlers and adapters

Understand the separate responsibilities that let one operation serve several interfaces.

Download Markdown ↓
Source and verification context ⌄

Source-guided

Examiner la source ↗

Repository links may require access. Source inspection is separate from a clean public-package installation.

AN INTERACTIVE READING MAP

Get the shape of this guide.

Move through the ideas, inspect their relationships, or make a focused reading path. The complete guide stays below.

SÉQUENCE DE LECTUREComprendre les liens entre les idées
Choose a point to look closer
01 / Section du guide

The contract describes the behavior

An operation contract names a command or query and describes its data and requirements. The model includes metadata, input and output schemas, result definitions, policy, declared effects, transport hints and links to related presentations or tests.

Lire le contexte à l’appui

A declaration is useful before it executes: another engineer can inspect its purpose and a tool can discover its shape. But an operation description is not a database implementation, and a policy field is not itself a trusted authorization decision.

Explore a section, then continue with the complete article below.

1 / 4

The contract describes the behavior

An operation contract names a command or query and describes its data and requirements. The model includes metadata, input and output schemas, result definitions, policy, declared effects, transport hints and links to related presentations or tests.

A declaration is useful before it executes: another engineer can inspect its purpose and a tool can discover its shape. But an operation description is not a database implementation, and a policy field is not itself a trusted authorization decision.

The handler performs the work

A handler is the application function bound to a registered operation. It reads or changes the resources your product owns and returns a result that the runtime can validate. It can use host-provided dependencies without putting those providers into the portable declaration.

Business invariants remain your responsibility. A valid input might still refer to an unavailable resource or request a transition the product does not allow. Model those outcomes deliberately and test them in the handler.

The adapter translates an interface

Adapters connect transport-specific requests to the registry. REST handles HTTP input and responses; MCP registers tool shapes and returns tool results. They can call the same operation without having identical wire formats.

The host constructs the context behind those adapters. It establishes identity, binds policy and approval ports, and supplies persistence or provider implementations. Keeping that setup explicit is what lets the contract stay portable.

CoucheOwnsDoes not imply
ContractMeaning, shape and declared requirementsAn implemented or authorized effect
Registry and runtimeBinding, common execution and result handlingA production identity system or database
HandlerBusiness implementationAutomatic correctness from its type
AdapterHTTP, MCP or other interface projectionIdentical transport semantics
HostTrusted context and concrete dependenciesAuthority from a browser-supplied role string

Follow a change through the layers

Suppose an export now requires a reason. The contract gains a required input field, callers must provide it, and the handler decides how that reason is used or recorded. Runtime validation can reject an old request shape, while a migration determines whether older consumers remain supported.

This makes a change easier to review: the declaration exposes the intended boundary, and the implementation diff shows the business consequence.

A change has an owner and a set of consequences.Trace the mechanism · 3 ways to look closer

A report export now needs a reason. Follow the change through authored meaning, derived output and a caller that still uses the old input.

Which part are you changing?
UNE SITUATION CONCRÈTE

The requirement becomes part of declared behavior.

A required reason is added to the operation input.

01 / Author

Change the declaration that owns the required input.

Ce qui change

Callers must now supply the new field for that contract version.

Ce qui reste explicite

The handler still decides how the reason affects the business work.

SUIVRE LA CONSÉQUENCE

Plan compatibility for existing consumers. A required input can be a behavioral break even if the handler’s main implementation is unchanged.

Where this explanation comes from

An authored situation, grounded in the linked source guides. Choosing a case explores its expected responsibilities; it does not execute an operation.

See it in an example.

Contracts / Beginner

Write your first contract

Define an operation

Follow user.create from an email schema to a typed handler. Start with the smallest maintained example.

  1. Describe the input
  2. Name the operation
  3. Follow the handler

Ce que montre la sourceThe maintained source declares user.create with a required email input and a typed output.

Ne démontre pasA database account is created or an email is sent.

Inspect the walkthroughBehavior · proof and limits · source checks

Follow the source behavior

A small user.create command accepts one required email address. Its current handler returns the same email. This gives you a compact place to understand the contract and handler boundary before adding storage or authentication.

  1. Describe the input

    Read UserInput in src/contracts/user.ts. The schema has one required EmailAddress field. The command uses the schema for both input and output.

  2. Name the operation

    Inspect the user.create key, version 1.0.0, owner, goal, and anonymous authentication policy. These describe the operation and its boundary.

  3. Follow the handler

    Open src/handlers/user-input.handler.ts. HandlerForOperationSpec derives the handler shape from CreateUser. The implementation returns input.email; it does not create a persisted account.

  4. Inspect and adapt the starter

    Read the package smoke fixture and validation script. Replace the echo handler with your own behavior, then test that behavior and the contract boundary together.

What this example establishes
Ce que montre la source
  • The maintained source declares user.create with a required email input and a typed output.
  • The handler is typed from the operation specification.
  • A source smoke fixture checks starter metadata and feature registration.
Ne démontre pas
  • A database account is created or an email is sent.
  • This example exposes an MCP tool: its manifest disables MCP.
  • This starter implements an approval gate, persistence, or production authentication.
Reproduce the source checks

The smoke fixture checks metadata and feature wiring; validation checks the contract. Neither is an account-creation integration test.

Répertoire de travail examples/minimal

bun run smoke
bun run validate

Commands and source inspected; not executed here.

Agents / Intermediate

Draft freely. Send with approval.

Control side effects

Follow one contract boundary through a workflow and an in-memory MCP transport.

  1. Separate the two operations
  2. Inspect the workflow
  3. Inspect the MCP boundary

Ce que montre la sourceThe source smoke fixture drives a real MCP server/client over linked in-memory transports.

Ne démontre pasDelivery of a Slack message, email, invitation, or other network request.

Inspect the walkthroughBehavior · proof and limits · source checks

Follow the source behavior

A reference agent drafts a message, waits for approval, and invokes sendMessage. The MCP smoke test uses a real MCP server and client over an in-memory transport. The actual handlers remain deterministic fixture logic.

  1. Separate the two operations

    The source defines draftAndSend.draftMessage and draftAndSend.sendMessage. Drafting is automation-safe; sending declares its approval requirement.

  2. Inspect the workflow

    The example connects draft, approval wait, send, and receipt stages through the WorkflowDevkit adapter. This is a composed reference flow, not an invitation feature in the minimal starter.

  3. Inspect the MCP boundary

    The smoke test registers the operation registry as MCP tools, then calls sendMessage with valid, absent, and tampered receipt evidence. It expects success only for the valid case.

  4. Read what send actually does

    The bound handler derives a message ID and returns status sent in memory. To send through a real provider, supply your own port and preserve the same execution boundary.

What this example establishes
Ce que montre la source
  • The source smoke fixture drives a real MCP server/client over linked in-memory transports.
  • The fixture asserts APPROVAL_REQUIRED for missing and tampered receipts.
  • The same registry gate is used by the MCP adapter rather than a second hand-written approval path.
Ne démontre pas
  • Delivery of a Slack message, email, invitation, or other network request.
  • A fresh successful run or production human approval system.
  • That the minimal example includes MCP; this is a separate source package.
Reproduce the source checks

The source fixtures inspect workflow sequencing and successful versus denied MCP calls with deterministic handlers.

Répertoire de travail examples/draft-and-send-agent

bun test src/mcp-smoke.test.ts src/draft-and-send.workflow.test.ts

Test and handler source inspected; not executed here.

Continue from here.

Concepts

What the runtime checks

3 min read

Follow a call from transport context to handler execution, then understand the limits of each guard.

Look inside the guideOpening context · complete reading path

Follow the execution boundary

A registered call resolves an operation and its bound handler, prepares the input and execution context, invokes the handler, and validates the returned value. The exact checks depend on the contract and the ports supplied by the host.

Work through the guide
Début

Adopt ContractSpec in an existing codebase

3 min read

Wrap one behavior you already own, preserve its observable behavior, and expand from evidence.

Look inside the guideOpening context · complete reading path

Select a small adoption seam

Choose a function or endpoint that already has a clear owner and useful tests. Prefer a contained read or a reversible local action for your first exercise. A workflow that spans several providers, jobs and billing decisions makes it difficult to tell whether a problem comes from your application or the integration.

Work through the guide
Concepts

Model inputs, outcomes and failures

3 min read

Make the data boundary explicit while keeping business meaning in the operation and handler.

Look inside the guideOpening context · complete reading path

Describe what the caller must supply

An input schema should express the shape you actually accept, including required values and constraints that can be checked before execution. Keep the distinction between an absent value and a valid empty value clear.

Work through the guide
Next: What the runtime checks →
Votre vue

Make room for your context.

Shape the presentation around this moment. You can change it whenever you need.

Votre contexte

The different parts of you

Choose a starting point

Un mélange utile de contexte, de visuels et de guidage discret.

Tune each dimension
Each dimension can change independently. Product permissions and available actions stay unchanged.

Support the way you begin and return

Tune your support

Confort de lecture

Choisir votre langue

La langue de l’interface change uniquement le texte. Les marchés, les prix et les parcours conservent leurs propres paramètres.

Couverture des traductions

Une partie du contenu est affichée en anglais.

Navigation151
Graphe616
Catégories378
Portfolio833
Exemples2 035
Aperçu de la source1 542

D’autres traductions seront ajoutées à mesure que le contenu sera relu.

Cette préférence est enregistrée dans ce navigateur.

Rechercher sur le site

Des points de départ utiles

Aucun résultat. Essayez une expression plus courte, un nom d’opération ou un autre périmètre de recherche.

UN PEU DE PLACE POUR EXPLORER

Trouvez quelque chose à explorer.

Ouvrez un aperçu détaillé sur cette page, essayez une autre perspective ou suivez le détail vers sa propre page.

Fonctionnement des aperçus et des commandes
01

Regarder avant de partir

Survolez un lien ou sélectionnez-le avec Tab pour voir un aperçu. Cliquer sur le lien d’origine ou appuyer sur Entrée ouvre toujours sa destination.

02

Rester dans le contexte

Entrez dans l’aperçu pour explorer ses sections. Depuis un lien sélectionné, utilisez Alt + ↓ pour y entrer au clavier. Échap le ferme.

03

Ouvrir les possibilités

Les lignes dépliables, les choix de perspective et les commandes mises en évidence révèlent davantage. Votre vue adapte le confort de lecture et le contexte exploré.

Un bouton séparé pour voir de plus près

Affichez de petits boutons d’aperçu à côté des liens quand l’espace le permet. Touchez l’œil pour examiner ou le lien pour y aller directement. Ce choix reste dans cet onglet.

Aucun historique de navigation n’est collecté. La réduction des animations suit votre appareil et Votre vue.