Skip to content
Press / to search

Build an Adapter

Build an MCP 2026-07-28, A2A, OpenAPI, function, or custom adapter with native action risk, scoped authority, evidence, replay, and conformance tests.

Integration GuideLast reviewed: Edit on GitHub
At a glance

Adapters are the Action-plane boundary between a model-proposed plan and an external system. They are typed, versioned execution contracts—not API wrappers. The protocol moves a request; the ContextOS binding decides whether that request is admissible and what evidence it must leave.

For profile-aware work, bind the admitted adapter release to the Execution Contract. Control Profiles add requirements from actual enabled features, including active code/tool boundaries, credential and egress mediation, data routes, shared budgets and recovery. A supported protocol or schema-valid manifest is insufficient evidence that those controls run; Conformance requires useful and denied cases against the real deployment.

The production rule

An adapter must answer these questions without consulting model prose:

QuestionRequired artifact
What can it do?Pinned capability manifest with owner, schemas, protocol profile, transport, and version
What can each call affect?Native ActionRisk, capability class, argument/destination ceilings, and v1 approval-mode projection
Who may invoke it?Principal-chain, delegation, tenant, workload-identity, scope, and policy requirements
What proves the result?Output schema, evidence refs, postcondition, mutation/artifact refs, and failure semantics
Can retries duplicate an effect?Stable operation identity, provider-specific idempotency/lookup contract or manual/no-retry strategy, retention window and governed compensation behavior
Can it be audited later?ToolCallEnvelope, ToolResultEnvelope, trace context, protocol/profile pins, and DecisionRecord linkage
Can it be stopped?Owner, kill switch, revocation path, timeout, cancellation, and rollback notes

If any answer is “the model knows,” “the description says,” or “the server advertised it,” the adapter is not admitted.

Choose the narrowest path

PathUse whenImportant boundary
MCP Streamable HTTPShared tool/resource server or cloud integrationTarget 2026-07-28; requests are stateless and self-contained
MCP stdioLocal process or private desktop integrationExplicit install consent, sandboxing, and stdout/stderr discipline
A2AA remote agent owns a durable task and returns messages/artifactsNew trust hop; re-authorize and narrow delegated authority
OpenAPI importA well-scoped service already publishes reliable schemasImport is discovery, not automatic permission
Function adapterYou own a small worker or jobKeep one business capability per operation
Custom connectorQueue, RPC, database, desktop, hardware, or legacy systemDefine equivalent auth, schema, idempotency, trace, and cancellation semantics
SkillA repeatable micro-workflow composes existing capabilitiesA skill may compose permission but cannot create it

MCP and A2A are profiles, not prerequisites. Every path normalizes into the same ContextOS envelopes.

Current standards profile

New MCP work targets MCP 2026-07-28. Existing 2025-11-25 servers may use a separately tested compatibility profile.

SurfaceCurrent profileContextOS consequence
NegotiationVersion and capabilities travel on each request; server/discover is availableNo initialize handshake in new adapters
StateProtocol requests are statelessPass explicit server-minted state handles as ordinary arguments
InputMulti-round-trip input_required resultsRe-authorize each input request; retry the original operation with a new request id
Long-running workio.modelcontextprotocol/tasks extensionBind the task handle to the originating run, principal, policy, budget, and trace
StreamingStreamable HTTP response streamsNo protocol sessions, HTTP GET event stream, or SSE resume/redelivery
Client featuresElicitation remains active; Roots, Sampling, and Logging are deprecatedDo not add deprecated features to new adapters
TelemetryW3C trace context in MCP metadataNormalize into ContextOS spans and lineage; do not put secrets in baggage

For protocol details and migration rules, use the MCP integration profile.

Architecture

Planner proposal
  -> Critic verification
  -> Tool Gateway
       manifest + identity + policy + ActionRisk + approval
       args + destination + budget + idempotency
  -> MCP / A2A / OpenAPI / function / connector
  -> schema + postcondition validation
  -> ToolResultEnvelope
  -> Critic score
  -> DecisionRecord + replay material

The Tool Gateway, not the adapter protocol, owns final execution admission.

Build sequence

StepDecisionOutput
1. Name the capabilityWhich user-visible job does one operation perform?Stable capability_id, owner, intent bindings
2. Classify the operationobserve, recall, verify, think_support, or actcapability_class
3. Describe native riskEffect, authority, reversibility, interaction, data scope, decision TTLaction_risk
4. Project v1 compatibilityConservative legacy mode for existing envelopesapproval_mode
5. Select protocol profileMCP, A2A, OpenAPI, function, customVersion/profile pin and transport
6. Design schemasInputs, outputs, structured errors, artifactsJSON Schema and size limits
7. Bind authorityPrincipals, tenant, scopes, destinations, amount/time limitsAuth and policy contract
8. Define effect semanticsObservable postcondition, idempotency, retry, cancellation, recoveryEffect and failure contract
9. Define evidenceFacts the DecisionRecord may citeEvidence keys, source identity, hashes
10. Add observabilityTrace, metrics, policy and protocol lineageSpan contract and envelope fields
11. Test through the GatewayProtocol plus ContextOS boundary behaviorConformance, security, replay, and eval results
12. Publish immutablySign/version and document rollout/rollbackPinned adapter release

Classify against the actual arguments, not only the tool name. A generic operation whose risk changes arbitrarily with its payload is too broad.

Adapter manifest

The manifest is the reviewed admission artifact. Live protocol discovery can confirm compatibility, but it cannot replace this contract.

{
  "adapter_id": "adp_payments_mcp",
  "version": "2.0.0",
  "owner_role": "payments_platform",
  "protocol": {
    "kind": "mcp",
    "profile": "2026-07-28",
    "transport": "streamable_http",
    "endpoint_ref": "https://payments.example.com/mcp",
    "extensions": ["io.modelcontextprotocol/tasks"]
  },
  "auth": {
    "type": "oauth2",
    "resource": "https://payments.example.com/mcp",
    "issuer_allowlist": ["https://identity.example.com"],
    "allow_token_passthrough": false
  },
  "capabilities": [
    {
      "capability_id": "payments.lookup_transaction",
      "protocol_tool": "payments_lookup_transaction",
      "capability_class": "observe",
      "action_risk": {
        "effect": "none",
        "authority": "service",
        "reversibility": "read_only",
        "interaction": "api",
        "data_scope": "CONFIDENTIAL",
        "decision_ttl_seconds": 300
      },
      "approval_mode": "network",
      "input_schema_ref": "schema://payments.lookup_transaction.input.v1",
      "output_schema_ref": "schema://payments.lookup_transaction.output.v1",
      "evidence_keys": ["transaction_id", "status", "settlement_ref"]
    },
    {
      "capability_id": "payments.issue_refund",
      "protocol_tool": "payments_issue_refund",
      "capability_class": "act",
      "action_risk": {
        "effect": "external_state",
        "authority": "user_delegated",
        "reversibility": "compensatable",
        "interaction": "api",
        "data_scope": "CONFIDENTIAL",
        "decision_ttl_seconds": 120
      },
      "approval_mode": "destructive",
      "requires_approval_gate": "GATE_FINANCE_APPROVAL",
      "arg_constraints": {
        "amount_inr": { "min": 1, "max": 50000 },
        "currency": { "enum": ["INR"] }
      },
      "idempotency": {
        "required": true,
        "dedup_window_seconds": 86400
      },
      "postcondition": "refund_exists_for_transaction",
      "recovery": "compensation_token_required",
      "evidence_keys": ["refund_id", "transaction_id", "reversal_token"]
    }
  ],
  "observability": {
    "trace_context": "w3c",
    "metrics": ["latency_ms", "retry_count", "upstream_status", "cost_cents"]
  },
  "kill_switch_ref": "registry://adapters/adp_payments_mcp/revoke"
}

The schema above is an integration blueprint, not a new published ContextOS schema. A deployment should validate its manifest format and version it independently.

Tool design

RuleGoodUnsafe
Name the business operationpayments_issue_refunddo_it, api_request, run_query
Keep one effect shapelookup and refund are separate toolsone tool may read, write, or delete based on free-form input
Bound argumentsenums, ranges, patterns, destination allow-listsarbitrary payload string
Type the resultids, status, artifacts, evidence, recovery tokenprose the model must reinterpret
Verify the postconditionindependent read confirms the intended statetrust the tool’s success message
Declare safe effect recoveryexact provider key/payload/retention guarantee, or explicit lookup/manual/no-retry strategyassume a local key prevents remote duplicate effects
Expose partial effectstyped failure plus mutation/recovery evidencegeneric error after an unknown mutation

Use JSON Schema 2020-12 unless a protocol or upstream system requires a different dialect. Keep ContextOS metadata in the adapter binding unless the protocol provides a clearly namespaced extension point.

Protocol objects are not equally trusted

ObjectTreatment
ToolModel-invocable candidate capability; must have a registered binding
ResourceData/evidence candidate; record source, classification, integrity, freshness, and hash
PromptUser-facing prompt artifact; version and evaluate it, never grant it policy authority
MCP App/UIPresentation and input surface; constrain origins and validate every returned value
A2A Agent CardDiscovery metadata; verify provenance and apply local admission policy
SkillInstructions plus composition; cannot expand the pack’s capability set

Discovery metadata and returned content are untrusted evidence. Neither can alter the registered principal, scope, destination, risk ceiling, or approval status.

Input-required and durable work

For MCP multi-round-trip input:

  1. persist the input_required result and request state;
  2. validate that each requested input type is supported;
  3. apply consent, redaction, approval, and identity policy;
  4. retry the original request with inputResponses and a new protocol request id; and
  5. preserve stable ContextOS operation identity, any provider idempotency key and originating run lineage when the same admitted action continues.

Protocol request IDs are attempt identifiers, not business-operation identity. If returned input changes the bound action, arguments, destination or release, invalidate the old approval and construct the appropriate new authorized proposal; a continuation cannot edit an already approved operation’s immutable action. A broken response after possible dispatch remains unknown until the declared provider contract makes recovery safe.

For the Tasks extension, authenticate and authorize tasks/get, tasks/update, and cancellation individually. Scope handles to the original relationship, generate them with high entropy, and never expose a task-listing backchannel. Resuming a task does not reset ContextOS budget or approval state.

A2A tasks follow the same principle: the remote task lifecycle is interoperability state; ContextOS still owns the narrowed delegation envelope and parent/child evidence linkage.

Error model

FailureAdapter resultContextOS treatment
Protocol/version/schema framing errorProtocol errorFail; no model retry unless the compatibility policy explicitly permits it
Correctable business validationTyped operation errorPlanner may repair arguments within retry and risk limits
Authorization or policy denialGateway refusal before callReject or pause for a named obligation
Additional user input neededinput_required or equivalentPause and re-authorize the input flow
Long-running operationDurable task handleTrack under the existing run and authorization context
Timeout with no known effectTyped timeout with idempotency stateRetry only when policy and the effect contract allow it
Partial or ambiguous effectFailure plus mutation/postcondition/recovery evidenceEscalate; never report clean failure or success

Transport and authorization

  • For stdio, launch a pinned command, keep protocol data on stdout/stdin, send logs to stderr, sandbox the process, and minimize filesystem/network access.
  • For Streamable HTTP, validate Origin, authenticate every request, bind tokens to issuer and resource, constrain redirects/egress, and apply request/body/time limits.
  • For MCP 2026-07-28, do not implement protocol sessions or resumable SSE. Any permitted reissue uses a new protocol request id while retaining stable operation identity and any provider key for the same bound action. The transport’s new-request requirement does not authorize an unsafe write retry; reconcile uncertain effects first.
  • Never pass through a user token minted for another service. Exchange for a short-lived, capability-bound credential when possible.
  • Keep authorization independent from application-level approval: OAuth scope does not prove tenant eligibility, evidence sufficiency, user intent, or approval-gate completion.

Supply-chain admission

Pin and verify:

  • publisher/owner and source revision;
  • manifest and schema hashes;
  • executable or image digest;
  • dependencies and build provenance;
  • protocol/profile compatibility;
  • requested destinations, scopes, data ceilings, and local permissions;
  • security and conformance results; and
  • operational owner, revocation path, and rollback target.

Re-run admission when publisher, dependency, endpoint, schema, requested permission, ownership, or executable digest changes. A protocol registry entry is useful discovery, not supply-chain assurance.

Testing matrix

Test classRequired cases
Contractinput/output schemas, required fields, bounds, size limits, malformed results
Protocolcurrent profile negotiation, unsupported versions, discovery, list/call/read flows
Legacy isolation2025-11-25 initialize/session behavior only inside the labeled compatibility profile
Policydenied capability, vector-dimension denial, conservative mode projection, gate required
Identitywrong tenant/audience/issuer, revoked workload, broader child delegation, expired claim
Idempotencyduplicate, timeout then retry, concurrent duplicate, dedup expiry
Effectpostcondition mismatch, partial mutation, compensation success/failure
Input flowdecline, invalid response, stale request state, untrusted URL, privilege expansion attempt
Durable taskpoll, input update, cancellation, authorization on every request, terminal-state invariants
Trace/replaytrace propagation, protocol/profile lineage, transcript-only replay, no live write on replay
Supply chainchanged digest, dependency/publisher drift, revoked signer, kill switch
Evaluationrepresentative tasks plus high-risk and adversarial slices before promotion

Test through the Tool Gateway. A raw protocol server can be correct while its ContextOS binding is unsafe.

Release checklist

  • Stable capability ids, owner, version, and kill switch exist.
  • Protocol and compatibility profile are pinned; legacy behavior is isolated.
  • Discovery and admission are separate.
  • Every capability has a class, native ActionRisk, and conservative v1 approval mode.
  • Inputs, outputs, errors, evidence, postconditions, and partial effects are typed.
  • Write-class calls persist operation identity before dispatch and enforce the declared provider-specific retry/reconciliation contract; key presence alone is not a guarantee.
  • Required execution boundary, credential mediation, actual data/processor route and aggregate reservation are verified before protected work.
  • Exact stored approvals and current ancestor authority are rechecked on input, retry, resume and delegation; cancellation preserves in-flight uncertainty.
  • Identity, tenant, scope, destination, amount, data, and time ceilings are explicit.
  • Input-required and task flows preserve authorization, budget, trace, and idempotency state.
  • Deprecated MCP features are absent from new adapters.
  • Supply-chain artifacts and provenance are pinned.
  • Conformance, security, replay, and evaluation suites pass.
  • Rollout, rollback/compensation, cancellation, and revocation have been rehearsed.

Common mistakes

MistakeConsequenceBetter design
Treating discovery as permissionNewly advertised tools become ambient authorityAdmit a pinned capability manifest
Classifying only with ApprovalModeInteraction, data, authority, and reversibility collapse into one lossy labelEvaluate ActionRisk; retain the mode only for v1 compatibility
Mixing MCP protocol erasSession and lifecycle bugs become silent fallbacksSeparate current and legacy profiles with conformance tests
Generic proxy capabilityModel can construct undeclared operationsExpose narrow business capabilities
Trusting declared successExternal state may be absent or partialVerify an observable postcondition
Letting task/input handles grant accessReference becomes a bearer secretRe-authorize every request and scope high-entropy handles
Hiding model work inside deprecated SamplingCost, lineage, and policy disappearRoute model calls through the governed model gateway
Testing only the serverContextOS policy, identity, and replay gaps surviveExercise the complete Gateway path

Next steps