> ## Documentation Index
> Fetch the complete documentation index at: https://docs.checkfu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Harnesses and models

> Choose a harness, compatible model, and model access for your agent.

Choose a **harness** for how your agent works and a compatible **model** for its
responses. The harness controls the agent loop, tools, and interaction. The
model performs inference. Checkfu manages the Agent and Session around them.

Select both explicitly; there is no default harness. Start with a managed
harness, or bring one built for your workflow. For a support assistant, for
example, you might use an existing harness to draft replies or build your own
around ticket triage and review. Compare results, required capabilities, and
cost on your own tasks. Checkfu does not automatically choose the best or
cheapest combination.

Model access is a separate choice: use Checkfu-managed supply or bring your own
key (BYOK). Bringing your own harness (BYOH) chooses the implementation, not the
account that pays for model calls.

<Warning>
  Plain HTTP against the Checkfu API needs no private package.
  The Checkfu CLI and TypeScript SDK are optional private-alpha artifacts; the HTTP requests work without them.
  Live readiness is deployment- and Workspace-specific and is not asserted by this page.
  Confirm [capability status](/getting-started/status) before making availability part of your application's contract.
</Warning>

## Choose a harness

<span id="supported-harnesses" />

<span id="first-party-managed-harnesses" />

Checkfu's managed roster covers eight families:

| Harness | Catalog name |
| - | - |
| Claude Agent | `claude-code` |
| Cline | `cline` |
| Codex | `codex` |
| Cursor | `cursor` |
| Deep Agents | `deepagents` |
| DeepSeek | `deepseek` |
| OpenCode | `opencode` |
| Pi | `pi` |

Checkfu owns their integration and support. Choose the release that supports
your model route and the capabilities your application needs. Membership in
this roster does not make every model or feature available on every release.

### Bring your own harness

Build a harness for your domain or adapt an existing implementation, including
a derivative of Pi or Codex. Official and custom implementations use the same
adapter contract and release qualification. You own support for your custom
implementation.

Start from the interface your harness exposes. Its ancestry or package name
does not determine its capabilities.

<span id="harness-lanes" />

| Interface | What to check |
| - | - |
| Native SDK or session interface | The exact package, runtime, model transport, and native lifecycle supported by its adapter. |
| ACP | The protocol version and the interaction, tools, approvals, and resume behavior the implementation actually serves. |
| App server | The versioned server protocol and its supported events and controls; Codex app server is one such integration. |
| One-shot | The declared input/output contract and any explicit resume support. A command that returns text does not imply an interactive session. |

Pi Durable on Cloudflare and Pi coding-agent native extensions are separate
integrations. Neither one's capabilities establish the other's. The same rule
applies to a native SDK package and an ACP image.

The [custom harness guide](/guides/bring-a-custom-harness) covers the public ACP
and one-shot image authoring paths. It is not a scaffold for every interface in
the table. Internal native SDK exports do not establish a public BYOH API.

For invited CLI users, [get CLI access](/getting-started/cli-access), then start
an ACP implementation with:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu harness init acp --directory ./my-harness
```

Use `oneshot` for the one-shot scaffold. Package and qualify the exact release
before using it; the scaffold alone does not prove your implementation's
capabilities.

## Choose a model

A model must be compatible with both the selected harness release and its model
route. Matching a provider name is not enough. Check the request format, model
metadata, and features your application uses.

| If your application needs… | Check… |
| - | - |
| Images, reasoning, or a large context window | The selected model's limits and the harness's serialization support. |
| Tools or approvals | Native tool handling, correlated results, and approval of the exact proposed call. |
| Steering or subagents | The controls and events exposed by that interface and release. |
| Continuation or recovery | The declared recovery capability. Reusing a transcript, restoring files, resuming native state, and restoring processes are different promises. |

Use the [harness/model matrix](/concepts/harness-extensions#harness-x-model-provider-reachability)
for request-format compatibility and the
[capability declarations](/concepts/harness-extensions#capability-ceilings-and-server-envelopes)
for release details. A shared format does not guarantee every model feature.
Unsupported combinations are refused; Checkfu does not silently substitute a
provider, model, format, or paid supply.

## Model access

An Agent's model is reached one of two ways:

* **Managed by Checkfu.** Name a model Checkfu supplies, such as
  `google/gemini-3.6-flash` on Checkfu's OpenRouter account. Usage is billed to
  your plan as platform supply. No key is needed.
* **Your own key.** Add a model credential, then pin it from the Agent's model
  config. Usage is billed by the provider to your account; Checkfu's model charge
  is zero.

A model credential holds a provider API key and nothing else. Checkfu does not
store consumer-subscription logins or refresh tokens as model credentials, and
a credential that was stored that way before this change is shown as a retired
subscription credential: you can revoke it, but Sessions never use it. Create an
API-key credential and pin it instead.

| Provider | Credential | Request formats served |
| - | - | - |
| OpenAI | `provider_key: "openai"` and a key | OpenAI Chat Completions, OpenAI Responses |
| Anthropic | `provider_key: "anthropic"` and a key | Anthropic Messages |
| Gemini | `provider_key: "google-ai-studio"` and a key | OpenAI Chat Completions |
| OpenRouter | `provider_key: "openrouter"` and a key | all three |
| Fireworks | `provider_key: "fireworks"` and a key | all three |
| Custom endpoint | your own name, `base_url`, and `api_format` | exactly the `api_format` you choose |

A custom endpoint uses a public DNS hostname over HTTPS on port 443 and speaks
one of the three formats, such as a hosted LiteLLM, vLLM, or Ollama deployment.
Set `base_url` to its API root, without URL credentials, a query or a fragment.
Endpoints on a private network are not reachable.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
POST /v1/organizations/workspaces/{workspace_id}/model-credentials
{
  "key": "team-vllm",
  "provider_key": "vllm-hosted",
  "base_url": "https://llm.example.com/v1",
  "api_format": "openai_chat",
  "kind": "api_key",
  "api_key": "..."
}
```

Use the returned credential ID in the Agent's `model` object. The public
`POST /v1/agents` request accepts a model ID, provider, and credential pin;
`model_routing_profile_key` and `environment_key` are not fields of this request.
For example, with a compatible `cline` harness:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
POST /v1/agents
{
  "name": "Coder",
  "harness": "cline",
  "model": {
    "id": "qwen3-coder",
    "provider": "vllm-hosted",
    "model_credential_id": "mcred_0123456789abcdef0123456789abcdef"
  }
}
```

Replace the example credential ID with your own. A direct credential pin does
not require a routing-profile grant. If the Agent also has a granted routing
profile, it must use that same credential. Select the Environment when creating
the Session and grant the Agent permission to use it, as shown in the
[Quickstart](/getting-started/quickstart).

Session admission resolves the pinned credential generation and freezes its
format. A missing, revoked, rejected, or other-provider credential refuses the
Session; a refused key never falls back to Checkfu-managed tokens.
The harness must also speak a format the route serves. Request formats
belong to the exact admitted harness release;
check its declared formats when choosing a credential or model route. A harness
name alone does not establish compatibility. An impossible pairing is refused
at Session creation with the alternatives named. The full harness and route
matrix is generated in
[Harness extensions](/concepts/harness-extensions#harness-x-model-provider-reachability),
together with the evidence each route carries.

Model credentials provide authentication for model calls.
[Connections](/concepts/connections) identify accounts used by tools. Neither
selection grants permission to use the resource. BYOK does not remove other
Checkfu charges. See
[Billing](/concepts/billing-and-platform-supply) for usage and charges.

Custodied model keys stay at the trusted model boundary. They do not enter
Agent instructions, harness configuration, Session events, tool payloads, or
sandbox workloads. Model calls still follow the selected route, current
permission, policy, and Budget. Provider receipts supply Usage facts.

## Session configuration

<span id="what-belongs-where" />

The Agent records your harness, model, instructions, and tools in an immutable
AgentVersion. Select the [Environment](/concepts/work-environments) separately
when starting a Session. Checkfu freezes the selected configuration for that
Session; later edits apply to future Sessions.

Your harness's native state and logs do not replace the Session's accepted
history. See [Product model](/concepts/product-model) for Agent, Session, and Run
boundaries. Checkfu-managed and customer-operated Cloudflare use the same
product model; [deployment ownership](/concepts/deployment) is separate from
harness choice, model access, and ConnectedRuntime attachment.

## Selection refusals

| Selection | Result |
| - | - |
| Invalid harness reference syntax | `400 validation.malformed` when saving the Agent. |
| Unknown harness, missing Workspace profile, or unavailable release | `409 validation.conflict` when starting a Session; no replacement harness is selected. |
| Unknown managed model or provider | `400 validation.malformed` when creating or updating the Agent. |
| Harness and model route share no request format | `409 validation.conflict` at Session creation. |
| Format incompatibility found while compiling a later Run | `runtime.harness_incompatible`. |

`model.no_eligible_model` is not the error for every invalid selection. A pinned
BYOK credential may name a provider-served model outside the reviewed catalog;
saving it does not prove the provider serves that model or that the harness can
use it. Inspect the actual provider and model in Run and Usage records.

For a custom HarnessProfile, the dashboard distinguishes incompatible formats,
unverified compatibility when the release declares no formats, and unavailable
information when the release cannot be read. These notices do not prevent
creating an Agent. Creation saves configuration; compatibility is checked when
a Session starts. An omitted format declaration is unconstrained at admission,
not proof of compatibility.

The dashboard pins a custom profile as `name@N`, its current published Version.
The API also accepts `name@latest` or a bare profile name to select the profile
head. A catalog harness uses its bare name. The Agent's harness selection stays
immutable; a Session freezes the release it selected.

In the dashboard, **Model credentials → Add credential** creates the credential;
**Create Agent → Bring your own key** selects and pins it. Credential creation
is a human step. CLI and MCP hand it off to the dashboard so a secret need not
pass through an agent. The SDK and `checkfu agent create --input` accept the
public model configuration above. See [SDK access](/reference/typescript-sdk)
and [CLI access](/getting-started/cli-access) for artifact distribution.

## Native execution

<span id="native-sdk-execution" />

<span id="native-execution-compatibility" />

Native Cloudflare Agents execution selects an exact model from the pinned
native catalog, or an explicitly declared custom model with the metadata below.
It preserves the model's request format, which must match the Session's frozen
credential route. Naming a custom HTTPS endpoint or saving a noncatalog model
alone does not supply that metadata or transport.

The gateway's provider table is not a native execution guarantee. The exact
package release, adapter, model route, and deployment must support the selected
combination. Native package tests do not qualify an image, and an image's
conformance report does not qualify a native Durable Object harness.

### Custom model declarations for native execution

A native model outside the reviewed SDK catalog needs explicit protocol metadata
on its model candidate. Declare `context_window_tokens`, `native_capabilities`,
and `native_sdk_estimation`; naming a catalog model as an alias does not supply
missing custom metadata. Pin a credential with an explicit `base_url` and
`api_format`, even when its provider has a default endpoint or supports several
formats. Missing endpoint or format metadata is refused on this custom native
path; Checkfu does not infer it from the model name.

`native_capabilities.version` is `1`. Select `openai_chat`, `openai_responses`,
or `anthropic_messages` as `wire_format`, matching the pinned credential. Declare
an output-token limit no greater than the context window, unique supported
`text`/`image` input modalities, reasoning support, all seven thinking-level
mappings, and the compatibility flags for that format. A null thinking mapping
means no value is sent for that level. These declarations describe serialization;
they do not grant tools, egress, model access, or provider capabilities.

`native_sdk_estimation` uses `version: 1`,
`unit: "usd_per_million_tokens"`, and `source: "profile_declared"`. All four
finite, nonnegative rates are required: `input`, `output`, `cache_read`, and
`cache_write`. An explicit zero is an SDK display estimate, not a free-provider
claim. Managed quotes, Usage, Budgets, and charges use their own authoritative
accounting; omitted rates never become zero.

Session admission retains the original credential generation, endpoint, request
format, and resource version. Native requests must match that original endpoint
and current authority before dispatch. Later credential edits do not rewrite
those coordinates. Missing metadata, incompatible formats, or endpoints the
selected serializer cannot represent are refused; they never switch to a
catalog alias or paid managed supply.

This declaration does not make a native harness launchable. The selected release
still needs its own qualified execution prerequisites and supported capabilities.
Consult [capability status](/getting-started/status) for the actual offering.

### Native image configuration

Some images accept non-secret configuration validated against the schema stored
with their release. For example, an image may accept `native_model` and a
`model_catalog` with `id`, `context_window`, and `max_tokens`. These are
caller-declared values, not provider-verified capacity or support claims.

Where that schema applies, the selected model must occur exactly once and
`max_tokens` must be less than `context_window`. A model-only selection uses the
image's catalog metadata and defaults where permitted. Empty configuration is
valid only for an image that supports it; locked native profiles reject these
overrides.

Image configuration does not select the model credential route or override the
model for an active turn. Follow the image's native hot-reload rules. A schema
change requires a compatible image and new release; ordinary configuration
changes follow profile versioning. Qualify the image, configuration, and model
route together.

## Support

<span id="conformance-and-support" />

<span id="everything-else-in-the-catalog" />

Support belongs to an exact release and configuration. A package, catalog row,
image build, or deterministic fixture does not establish a customer offering.
The roster governs managed families; custom implementations and supported
ConnectedRuntimes follow their own contracts. Research entries outside the
managed roster are not additional supported families. Local fixtures remain
for development and tests.

For custom images, server-issued, signature-verified conformance evidence is
required. An immutable recipe image or release, an authorized HarnessProfile,
its Environment, and `use_harness` permission remain separate requirements.
Catalog profile creation needs a published default image; otherwise it returns
`409 validation.conflict`.

Changing the binary, image digest, adapter, protocol, Environment, model route,
or policy can require new qualification. Distribution and license terms,
hosting, and authentication also apply to the exact combination. One supported
route does not qualify every route in the family.

## Portability

Agent, Environment, Session, and event semantics stay consistent across
harnesses. Their native capabilities and private state can differ. Switching a
harness does not promise it can resume another harness's process state or safely
retry an uncertain external effect. Preserve the original Session configuration,
permission, Usage, and effect records during recovery.

## Next steps

* [Quickstart](/getting-started/quickstart): select an Agent and Environment and start a Session.
* [Run Claude Agent](/guides/run-claude-agent) or [Run Codex](/guides/run-codex): configure a managed family.
* [Bring a custom harness](/guides/bring-a-custom-harness): implement and qualify the ACP or one-shot image contract.
* [Harness extensions](/concepts/harness-extensions): inspect protocol, model-format, and capability details.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.