examples/custom-acp/server.mjs in the Checkfu repository, an ACP v1 server in about three hundred lines of plain Node with no dependencies at all.
Two companion pages carry the normative truth this guide deliberately does not restate. Harness wire extensions is the contract page — its capability matrix and slot inventory are machine-generated from the same code the platform runs, so they cannot drift. The acp-v1 extension schema and golden wire vectors are the machine-readable wire artifacts. When this guide and those artifacts ever disagree, the artifacts win.
Every server.mjs block below is excerpted from that file, not retyped, and the repository’s documentation checks fail if one drifts from the source. The CLI invocations later on are ordinary examples, not quotes — check them against checkfu harness --help if a flag ever looks wrong.
The wire: JSON-RPC over stdio
A harness is a process. The Runner launches it inside the sandbox, writes newline-delimited JSON-RPC 2.0 to its stdin, and reads the same framing from its stdout. Stderr is yours for logging. The entire transport layer of the reference server is one line:path=examples/custom-acp/server.mjs
path=examples/custom-acp/server.mjs
initialize: declare only what you serve
The first request is initialize. The response names your protocol version and capabilities:
path=examples/custom-acp/server.mjs
mcpCapabilities: { http: true } is load-bearing: it tells the platform this harness can accept HTTP MCP servers in session/new, which is how the platform tool plane arrives (below). Richer harnesses additionally declare Checkfu’s namespaced extensions — native steering, cooperative interrupt, observed subagents — in the initialize response _meta; the exact admission rules are in the declaration handshake.
Declare honestly, and only what you serve. A declaration is never evidence: conformance actively exercises every declared surface, and only server-issued, signed conformance evidence realizes a capability. Declaring an axis you do not serve is worse than not declaring it — the platform will drive the declared surface and the failure modes are honest ones, up to failing the Run.
Session and turn lifecycle
session/new opens a session and hands over the MCP server list; the reference server keeps it and answers with a session id:
path=examples/custom-acp/server.mjs
session/prompt is a turn. While it runs, the harness streams session/update notifications — agent message chunks, tool calls, tool results — and settles the turn by answering the request with a stop reason:
path=examples/custom-acp/server.mjs
The model plane arrives in the environment
A harness never holds provider credentials. The sandbox environment carriesCHECKFU_MODEL_BASE_URL and CHECKFU_MODEL_TOKEN — the platform-neutral names, and the ones to prefer in new code — pointing at the governed model gateway. The same values are also exported under the vendor-shaped aliases OPENAI_BASE_URL/OPENAI_API_KEY and ANTHROPIC_BASE_URL/ANTHROPIC_API_KEY, so a harness built against an existing SDK works unmodified; note that ANTHROPIC_BASE_URL is the origin without the /v1 suffix its OpenAI-shaped sibling carries. Routing, budget, and usage accounting stay with the platform, and the model name you send is rewritten to the admitted route. The reference server reads the OpenAI alias:
path=examples/custom-acp/server.mjs
The platform tool plane: MCP handoff
Granted platform tools arrive as ordinary HTTP MCP servers insession/new — the handoff your initialize response opted into. The reference server looks up the control server by name when its turn needs a governed capability:
path=examples/custom-acp/server.mjs
tools/list, tools/call:
path=examples/custom-acp/server.mjs
tool_call and tool_call_update session updates so the activity is observed rather than narrated — the platform’s own served-call record, not your narration, is the authority on whether tool delivery happened.
The image contract
Your harness runs under a container posture the sandbox imposes, not one your image chooses: the process runs as user65532:65532, the root filesystem is read-only, and exactly /workspace, /tmp, and /home/checkfu are writable. Build for it — a harness that expects to write elsewhere, or to be root, fails at runtime rather than at registration.
Be precise about what enforces this. The sandbox provider applies the posture at materialization; the values above are the same ones the catalog’s image contract records for first-party entries, and a custom image registered through harness add oci has no catalog entry at all. Conformance does not check container posture — its case set covers the ACP handshake, tool correlation, and the declared control axes, and contains no uid, read-only-root, or writable-path case. So the reference server does what any harness author should do while developing: it proves each property from inside and reports it as ordinary evidence, which is a self-report, not platform attestation.
path=examples/custom-acp/server.mjs
CHECKFU_HARNESS_CONFIGURATION, validated against the configuration schema registered with the release. Credentials never belong there — provider access rides the model plane above, and tool authority rides the MCP handoff.
Register, verify, run
Registration is the same public arc for every custom harness: build and push an immutable image, adopt the digest as a HarnessProfile, request server-signed conformance, then create and publish an Agent on the verified profile.name@sha256:... form registers; a mutable tag fails before anything persists, and a new image is always a new release. The walked five-step transcript — including the Agent creation, PermissionAssignments, and Session chat — is the Custom ACP harness example.
Upgrade and roll back one logical harness
Keep the HarnessProfile name stable after initial adoption. Test and publish a new immutable digest, then create the release, advance the profile with optimistic concurrency, and verify the exact resulting version in one CLI workflow:--expected-version is checked before the CLI creates a release, then the API
guards the patch with the same current version. The command prints a recovery
command as soon as an OCI release exists, so a failed or interrupted profile
patch never strands an undiscoverable artifact. After a successful patch it
prints the exact rollback command. Rollback is an ordinary forward version:
--verify targets the
returned profile version directly instead of resolving the logical name a
second time. Non-secret configuration is retained unless --configuration
is supplied, and the CLI validates the resulting configuration against the
target release before patching.
For an OCI-to-OCI update, omitted process, platform, configuration-schema,
model-wire, and MCP options inherit from the current immutable release. This
keeps an image-only rebuild exact without silently dropping a declared
capability; pass an option only when the new binary intentionally changes that
part of the release contract.
Or hand us the repository instead
If you would rather not run a container build at all,POST /v1/organizations/{organization_id}/harness-builds takes a GitHub repository URL, an optional ref, and an explicit platform build pool or Workspace/RunnerPool target. Checkfu builds the image and mints the Organization-owned, digest-pinned release for you. Ownership never implies execution authority. The ref is resolved to an exact commit at submission and only that commit is stored, so the immutability rule above is unchanged rather than relaxed: no branch or tag is ever stored on the result, and re-registering a repository is always a new build. Submission is accepted with 202; poll GET /v1/organizations/{organization_id}/harness-builds/{id} for settlement.
The CLI drives that same public resource. It can stop at the ordinary
release-profile handoff, or compose adoption and signed verification without
introducing a privileged build-only profile path:
--adopt, success prints checkfu harness add release --name ... --release hrel_... --driver checkfu:acp-v1@1. With --adopt, the CLI submits
that same public profile-creation payload; --verify additionally waits for
signed conformance and prints status. Building an image grants no conformance
or admission privilege.
For an existing profile, leave --adopt off and pass the resulting release to
checkfu harness update <profile> release --release <hrel_...> instead. OCI
releases select the canonical protocol driver automatically; a non-OCI release
requires the explicit --driver value. The update path then follows the same
fresh-verification rule above.
Where to go next
- To understand the boundary, stay with
examples/custom-acp— minimal on purpose, every line of the contract visible. - To adapt an SDK-authored agent, use the OpenAI Agents SDK over ACP example — it pins the official SDK, routes its fixed model through Checkfu’s gateway, disables the SDK’s separate trace exporter, and declares no MCP handoff.
- To build a real harness inside an authorized Checkfu source checkout, start from
apps/harness— pi’s agent loop behind the same ACP server contract, with durable turn journals, checkpoints, completion evidence, and the extension declarations this page only gestures at. Its README carries the same export → modify →checkfu harness add oci→checkfu harness verifyarc. The package and standalone export are private qualification artifacts today; no public repository or npm package is claimed. - For the contract itself, Harness wire extensions and the schema and vector artifacts remain the normative source.