One Twin, Many Interfaces
The same governed model of your business, reached through role-specific first-party interfaces today, with a safe external surface being prepared next.
In You Are Not the Front Door, I made a single claim: the chat box is not the product, the Twin is, and whatever someone types into a prompt is one temporary way of reaching a governed model of their own business. This article is the concrete sequel. It is a map, not an argument. It sets out what already works, what is being stabilised next, and what genuinely cannot connect yet, with no rounding up.
Interfaces Are Promises, Not Logos
It is tempting to describe an interface by naming a client or a protocol. People say "we support Claude Code" or "we speak MCP" or "there is a REST API" as if that settled the question. It does not. A logo tells you which application is holding the phone. A protocol tells you the shape of the envelope. Neither tells you what the receiver actually promises to do with what arrives.
The Twin's interfaces are promises about six things: who the caller is, which organisation they are scoped to, what capability policy permits, which approved product and version they are allowed to touch, what evidence must accompany an answer, and whether the whole invocation left an auditable record. A transport that carries those promises faithfully is a real interface. A transport that carries a request but drops one of them is a leak wearing a protocol's clothes.
Every interface below differs in ergonomics but agrees on that contract. That agreement is the point, and it is the thing that has to survive when the transports change.
An Honest Map of What Exists Today
Today the Twin lifecycle is already reachable through several first-party interfaces, each cut for a specific role.
Organisation admins use the console at /admin/foundry/twin. It is deliberately human: Overview, What it knows, Review changes, Source coverage and User demand. An admin does not write a query here. They see what the Twin has learned, approve or reject proposed changes, understand which sources are covered, and read what their own users are actually asking for. This is the surface where meaning is governed by a person.
Applications and coding agents use the TypeScript SDK namespace sdk.twin. It offers typed discovery, lifecycle, evaluation and a governed query helper. Discovery requires a verified organisation-admin identity, which matters: this is an SDK interface for building on top of the Twin, not a general public agent endpoint that anything on the internet can hit.
MLX task agents use bound product skills together with twin-catalog. A task agent queries the organisation-scoped catalog and then reads only the published relation named by the selected manifest. It does not roam. The catalog is the index, the manifest names one relation, and the agent touches that and nothing adjacent.
Fleet operators use bun run fleet twin for inventory and controlled discovery across many organisations. This is an operational lens, not a customer path, and it is guarded accordingly: shared writes require worker or operator authority and the explicit --allow-live-write flag rather than being available by default.
Evaluation runners use bun run eval:run, eval:canary and eval:target. These give deterministic execution and persisted verdicts, so a Twin's behaviour can be checked and rechecked rather than judged by feel. A verdict that survives is a fact you can point at later.
Finally, scratch and recovery operators have direct database tooling. This exists on purpose and is deliberately outside the end-user SDK. It is not a normal customer mutation path, and it is fenced off precisely because it bypasses the ergonomics that make the other surfaces safe.
Six interfaces, one lifecycle. None of them is the Twin. Each is a promise-preserving way to reach it.
A Closer Look at runTwinQuery
The most instructive of these is the governed query helper, sdk.twin.runTwinQuery. It is worth slowing down on because it shows how much of the contract lives in composition rather than in a single call.
runTwinQuery is a TypeScript SDK composition, not one public OpenAPI query operation. There is no single "query the Twin" endpoint that it thinly wraps. Instead it assembles a governed path. It creates a foreground Electric run fixed to a readonly-data profile, the mlx-warehouse plugin and twin-catalog. It waits for that run to complete. Then it does the part that actually matters: it rejects any result that does not arrive with three things at once. There must be catalog evidence. There must be evidence that the manifest's published relation was the relation queried. And there must be a matching structured product citation. Miss any one, and the result is refused rather than returned.
That refusal is the promise made mechanical. An answer that cannot show where it came from is not a slightly weaker answer; it is not an answer. This is what "reached through a governed interface" means in practice, as opposed to "wired up to a database". The read-only profile means the path cannot mutate. The fixed plugin and catalog mean the caller cannot smuggle in a different data source. The evidence gate means the model cannot narrate a plausible number and have it pass as fact.
The Agent Binds to One Product, Not Every Tool
The same principle shows up in the agent harness, and it is the clearest illustration of the whole philosophy.
Under direct_governed routing, once the exact products and active publication skills have already been resolved, the runtime exposes exactly one typed tool: mlx_governed_product_query. Not a toolbox. One tool, bound to the approved products selected for the run. From there the runtime selects the bound relation and mechanically compiles the query. The model does not rediscover the catalog. It does not describe tables. It does not write SQL. It does not reach for an adjacent product because a name looked similar. All of that has been decided before the model gets a turn, and the model's job is narrow by construction.
This is not the only routing architecture in MLX, and not every task takes this shape. Other patterns exist for exploratory and retrieval work. But direct_governed expresses the key idea cleanly. A governed agent binds to an approved product, not to a bag of arbitrary tools it is trusted to use wisely. Capability comes from the binding, not from the model's judgement in the moment.
Why the Names Had to Stabilise First
That brings us to the part being prepared next, and to a piece of work that looks cosmetic but is not.
The current product surface standardises on Twin, sdk.twin, /api/twin, twin-catalog and consistent product binding identifiers. The coordinated operational rollout is separate work. This can look like naming tidy-up from the outside. It is closer to pouring foundations.
Identifiers here are not labels you can change your mind about later. They leak. A name that starts life as an SDK method becomes a route, becomes a line in a skill, becomes a binding, becomes a field in audit evidence, and finally becomes part of an immutable receipt that may need to answer "what exactly did this agent do?" years later. Once a name is embedded in receipts that cannot be rewritten, renaming it stops being a refactor and starts being a migration of history.
So the naming cutover is deliberately a prerequisite. MLX is making semantics, identity and evidence coherent before anything external is frozen against them. Freezing a public surface on top of names that were still expected to move would be committing a promise the product was not ready to keep.
What a Safe External Surface Must Preserve
What is being prepared, and what will it have to carry?
The direction is a narrow, safe way for agents the company does not operate to reach a governed slice of the Twin. Concretely, that means a machine-readable public-interface manifest, a set of Twin MCP tools, and a public user-facing CLI, none of which should be frozen until the groundwork above is solid. Planned MCP tool names include twin_query, twin_query_result and twin_list_products. They make the direction legible. They are planned, not available.
The public CLI in that direction is distinct from the CLIs that exist today. bun run fleet twin and the recovery tooling are operator surfaces for people inside the boundary. The future public CLI is for callers outside it, which is a different trust problem entirely.
Whatever transport carries this, it has to preserve the whole contract across the wire, not a convenient subset. Caller identity. Organisation scope. Capability policy. Approved product and version. Evidence. An auditable invocation record. If a remote MCP call or public CLI invocation cannot carry all six with the same fidelity as an in-process SDK call, then it is not ready, no matter how good the demo looks. The transport is allowed to change. The promises are not.
What Cannot Connect Yet
Here is the boundary, stated plainly, because rounding up here would be the one dishonest move available.
MLX does not currently expose a generally available remote endpoint that arbitrary Claude Code, Codex, Gemini, ChatGPT or other third-party agents can connect to directly. If that is what you need today, it is not there.
Two things are true at once and are easy to conflate. Some internal runtime plugins already use MCP-compatible server mechanisms in places. That is real, and it is not the same thing as an inbound public Twin MCP gateway that outside agents can reach. Internal use of a mechanism is not an external interface.
The Contract Outlives the Protocol
A stable company-side contract matters more than any single transport. The same Twin lifecycle is already reachable through an admin console, a typed SDK, bound task-agent skills, a fleet CLI, evaluation runners and guarded recovery tooling. Each is a different shape of the same promise.
The next task is not to invent the Twin's meaning again for a new client. It is to make one narrow governed surface safely reachable by agents MLX does not operate, without dropping identity, scope, capability, approved product, evidence or the audit record on the way out.
Protocols will keep arriving. MCP today, something else in two years. The public surface should freeze only once semantics, identity and evidence are coherent, so that when the protocol underneath it changes again, the contract on top does not have to.
Previous: Five Gates Between a Guess and a Governed Answer. Why approved meaning passes through distinct evidence and activation gates before it becomes usable.
Next: Every AI Answer Needs a Receipt. Why every interface must preserve the evidence showing which governed product actually answered.
Frequently asked
- Can my Claude Code, Codex, Gemini or ChatGPT agent connect to the Twin today?
- Not directly. MLX does not currently expose a generally available remote endpoint that arbitrary third-party agents can connect to. Applications and coding agents can build on the typed sdk.twin namespace, and MLX-operated task agents reach the Twin through bound product skills. A safe external surface is being prepared, but it is not shipped, and we are not promising a date.
- If I build on sdk.twin now, will the method names and routes change under me?
- The current interface surface standardises on Twin, sdk.twin, /api/twin, twin-catalog and stable product binding identifiers, while coordinated operational rollout remains separate work. That stability is a prerequisite for freezing a public manifest because these identifiers can enter audit evidence and immutable receipts and cannot be casually renamed later.
- How do I know an agent answer came from approved data and not from the model guessing?
- The governed query helper rejects any result that lacks catalog evidence, proof that the manifest's published relation was actually queried, and a matching structured product citation. An answer without that provenance is treated as a failure, not a best effort.