TrueForge — the harness as a switchboard
The first unit on this register that is not a coding agent. TrueFoundry's open-source runtime drives enterprise agents over MCP servers — a CRM, a tracker, a document store — and it still answers all eleven slots, which is the best evidence yet that the slots are about harnesses and not about code. Its own axis is narrower than any sheet before it: how few tokens can reach the model per turn and still get the same answer. It publishes a benchmark to say so.
Identification
- Repository
- truefoundry/trueforge
- Steward
- TrueFoundry
- Opened
- 23 July 2026
- Licence
- MIT
- Runtime
- TypeScript on Node ≥ 22.14 · Hono · Vercel AI SDK
- Storage
- SQLite (local) · Postgres + Redis (hosted)
- Tools
- MCP only — remote servers, header auth or OAuth
- Surfaces
- chat UI · HTTP API + TS SDK · React UI SDK · Helm
LineageTrueFoundry sells an AI gateway, and the shape of the harness says so: it is a server that other systems call, not a program a person runs at a prompt. The four catalogues it ships — models, MCP servers, skills, sandbox providers — are YAML discovery lists an operator fills once, and every agent is a saved spec that picks from them. The compaction prompt inside it is the familiar eight-section shape (primary request, key concepts, files, errors and fixes, pending tasks, current work, next step) that the coding agents on this register converged on; the difference is what surrounds it. Opened in July 2026, version 0.1.x at the time of reading, and moving quickly — the migration directory gains a file every few days.
Read it as
A telephone exchange
Every line — model, tool server, sandbox — is patched through one board, and the operator keeps the keys. Nothing is connected until a call asks for it, and no line ever holds another line's credentials.
The drawing, in one paragraph
Two decisions generate the sheet. The first is a rule about tokens: every source of context gets a budget, and a mechanism for what happens past it. Tool schemas are not loaded until the model asks for one. A tool result over 6,000 tokens goes to disk and leaves a hundred characters at each end; a batch of results over 10,000 tokens is offloaded largest-first until it fits. A sub-agent returns its final message and nothing else. A Code Mode script prints a summary and the JSON it read stays in the sandbox. At 50,000 tokens of working context the whole history becomes one summary. The second decision is about where the loop lives: on the server, with the credentials, while the sandbox is a tool provisioned only when a turn needs code — so a question answered from three MCP servers never pays for a VM, and no token for a model or a tool server ever enters a container. The benchmark is the two decisions measured: the same fourteen tasks, the same model, the same score as Claude Managed Agents, at 3.7 million tokens a run instead of 10 million.
The examination — eleven slots, one harness
- Built in
- Ships in the core; works with no configuration.
- Via config or extension
- The slot is real but you fill it — config, extension, or convention.
- Deliberately omitted
- Left out on purpose, with a stated argument for the gap.
The system prompt is assembled as a tree of XML sections — <agent-identity>, then a section per enabled capability (sandbox, sub-agents, deferred tools, generative UI), then <user-instructions> wrapped in CDATA so the operator's text is delivered as data rather than markup. The docs are firm about what belongs there: the agent's role and audience, not tool documentation (injected) and not procedures (those are skills). An agent can also carry seed messages, injected at the top of every new session before the user speaks.
Built in
InstructionBuilder XML tree · CDATA user text · seed messages
There is no grep, no read, no retrieval index in the core — material arrives through whatever MCP servers the agent is attached to, or through a shell in the sandbox. What the harness owns is the shape of what arrives: get_tool_output_schema fetches a tool's output schema before the model writes code against it, and Code Mode lets a Python script call MCP tools through an in-sandbox client and print only the fields it wanted. Delivery is bring-your-own; the filter on it is built in.
Via config or extension
MCP servers · sandbox shell · Code Mode via mcp_client
Four layered mechanisms, each with a number. Deferred loading: preload is false by default, so a server contributes its name and description and four meta tools — list_tools, get_tool_info, get_tool_output_schema, call_tool — until a schema is asked for. Large-response offloading: over 6,000 tokens for one result, or 10,000 combined across parallel calls, the payload is written to a sandbox file and replaced by its first and last hundred characters plus the path. Sub-agents return only a final message. Compaction: when prompt plus completion tokens cross 50,000, a 931-token prompt turns the whole history into one assistant summary followed by a fixed continuation note — the working context is overwritten; the session's event record is not.
Built in
defer by default · 6k / 10k → disk · compact at 50k
Every external tool is MCP, remote, over HTTP — with header auth or OAuth including dynamic client registration, and an in-chat Connect button when a server needs authorising mid-run. Per server, selectors resolve against the annotations the server publishes: enable @all or @read-only, require approval for @write and @destructive by default, or name tools literally. The harness's own tools are few and local: the sandbox, ask_user_question, create_sub_agent, and the OpenUI block for generative UI.
Built in
remote MCP + OAuth · @read-only / @write / @destructive selectors
The stated position is sandbox as a tool, against agent in a sandbox: the loop and every credential stay on the server, and an isolated environment is provisioned only when a turn needs code, files, or a skill — then reused across the session and stopped after idle time. The boundary holds even for Code Mode: a script's MCP calls are bridged back to the harness, which applies the stored credentials, so the container never holds a token. Approval is the second gate — write and destructive tools pause the turn until a human allows or denies. Providers are bring-your-own; the docs name Daytona as the only supported one today.
Built in
sandbox as tool · credentials never enter it · approval on @write
The session is an event log, and the runtime README states the ordering rule as law: yield the event, let the consumer persist it and possibly throw, and only then mutate memory. Sessions, turns, threads, and events go to SQLite in local mode or Postgres in hosted mode, with a Redis Stream fanning events out across replicas; a conversation survives a reconnect, a restart, and a sandbox crash. Compaction overwrites the model's working context and leaves the record whole, so the full history stays queryable through the events API after the model has forgotten it.
Built in
event log · persist before mutate · SQLite / Postgres + Redis
One thread loop with three processor phases — pre-send, pre-LLM, post-tool-call — that compaction and offloading plug into, streamed step by step over SSE. The loop pauses in two named states, approval required and response required, and will not accept a new user message while either is open. A safety stop caps iterations per turn at 100, adjustable to 1,024; a response format can demand JSON against a schema. The same loop is driven from the chat UI, the HTTP API, or an embedded React client.
Built in
three processor phases · pause states · 100-iteration cap
A single create_sub_agent tool, on by default. A child gets the same tools and the same sandbox but a fresh context — the tool description warns the model that the child has no access to the conversation and must be given a self-contained brief — and returns only its final message. Children run in parallel and the root waits for all of them; they cannot ask the user anything, though their approval-gated calls still pause for the human; and delegation is one level deep by rule. With a model set configured, the root picks a model per child from a described list.
Built in
create_sub_agent · one level · parallel · model per child
Skills are git repositories. A SKILL.md with name and description in frontmatter, registered once by URL, path, and ref — pin a tag for production — and attached to an agent by name. Only the name and description ride in the prompt; when the model chooses one, a sparse clone lands at /opt/tfy/skills/{name} in the sandbox and the model reads the body and runs the bundled scripts there. Skills therefore require the sandbox, which makes the progressive disclosure literal: the second stage is a filesystem.
Built in
git-backed SKILL.md · sparse clone into the sandbox
Observability is the event log itself — every model message, tool call, approval, and context overwrite is an event you can subscribe to live or page through afterwards — plus a tracing interface with OpenTelemetry spans around MCP operations and the sandbox. Verification of the answer is thinner: a JSON schema on the response format is the only check in the loop. The judge lives outside it, in a benchmark harness the repo ships — a blind LLM grader over DevRev's Enterprise-Bench that scored the harness at 10.7 of 14, level with Claude Managed Agents. The roadmap names an evaluation pipeline in CI as the next step.
Via config or extension
events API · OTel spans · judge outside the loop
Nothing compounds on its own. An agent is a spec in the database and evolution is editing it — a new model name, a tighter tool list, a skill attached, a threshold moved; skills evolve where they live, in git. The roadmap is candid about what is missing: automatic model selection per task, agent instructions auto-composed from a chat that went well, and approve-once so a decision outlives one call. Each of those is a place a lesson could persist; today each is a human's edit.
Via config or extension
the agent spec is the surface · roadmap names the rest
Where this design runs out of road
Every budget is a place the model can be starved. A schema it did not think to ask for, a result whose one decisive line fell between the first hundred characters and the last, a compaction summary that kept the files and dropped the constraint — and the recovery path for all three runs through the sandbox: read the file, fetch the schema, grep the dump. The sandbox is off by default and bring-your-own. Turn it off to save the VM and the exchange still answers, but with nothing behind the preview. The second cost is the one the benchmark cannot see. It grades answers, not receipts; the harness that reaches the same score at a third of the tokens has also removed most of the material a reviewer would use to check how it got there.
06Side by sideThe comparison table — one row per primitive, one column per harnessRead from — every finding traces to one of these
- truefoundry/trueforgeRepository — packages/trueforge-core/src/core, packages/trueforge/src
- Harness CapabilitiesDocs — input vs runtime context, compaction, how the strategies compose
- Deferred Tool LoadingDocs — the four meta tools and selective preload
- Large Tool ResponsesDocs — the 6,000 / 10,000-token thresholds and the preview
- Subagents · Code ModeDocs — one-level delegation, and tool calls bridged from a script
- SandboxDocs — sandbox as tool versus agent in sandbox, credential safety
- Create an AgentDocs — the full agent spec, selectors, approval, iteration limit
- BenchmarkingDocs — 14 Enterprise-Bench tasks, n = 3, cost and tokens per run