First principles

An agent is a model inside a harness. A coding agent, a personal assistant, a support desk and a voice concierge look nothing alike from the outside, and they are built from the same parts. Glove gives you a primitive for each part. Learn the parts once and every harness becomes an assembly job, not a rewrite.

Three layers, each wrapping the one inside it. Glove is the harness around a model, Foundry turns harnesses into a running system, and Kuiper runs that system in production. Each name is a part you would otherwise build yourself; click one for its primitives.

This page builds that picture from the bottom. First the harness: the seven parts every agent needs and how they connect. Then the system: what changes when there are many agents that act on their own time. Then production: what a system needs to stay up. Each part links to the primitives map, which lists exactly what already exists for it.

The harness

A model does one thing. It takes a list of messages and the tools it may use, and returns text, tool calls, or both. Everything else (running those tools, deciding what the model sees next time, keeping what happened, letting a person in) is the harness. Written out, every harness is this loop:

every harness, in pseudocodetypescript
save(userMessage)
while (true) {
  const input = systemPrompt + history() + liveState()   // context
  const reply = await model(input, tools)                // loop
  save(reply)                                             // state
  if (!reply.toolCalls) return reply.text                 // surface
  for (const call of reply.toolCalls) {
    validate(call)                                        // tools
    if (needsPermission(call)) await ask(person)          // surface
    save(await run(call))                                 // workspace, team
  }
  if (tooLong(history())) compact()                       // context
}

Every line is a decision. Where does history live? What counts as live state, and does adding it break the prompt cache? How do you ask a person and wait without blocking the server? What does "run" mean when the tool is a whole other agent? Glove turns each decision into a primitive you configure instead of code you write. The seven parts are the seven questions:

Here is how they connect in glove-core, for one request. The cycle in the middle is Agent.ask: the message is saved, context is assembled from what is saved, the model asks for tools, the results are saved, and the cycle repeats until the model answers without asking for a tool.

Surfacechat · voice · APIContextprompt · history · live stateModelany providerStatestore · memory · inboxToolsvalidated · gatedTeamsubagents · meshWorkspacefiles · code · webloopuntil the model answersprompttool callsresultshistorymessageanswerdisplay stack: show · ask · waita subagent is a toolacts on
One request through a Glove harness. The message is saved to state; context is assembled from state before every model call; the model asks for tools; results are saved; the cycle repeats until the model answers. Tools can render UI on the surface and wait for a reply, act on a workspace, or hand work to a subagent.

The same parts, in different shapes

What makes harnesses different is the shape each part takes, not which parts they have. Read this table down a column and you have a design; read it across a row and you see that the primitive is the same.

PartCoding agentPersonal assistantSupport deskVoice concierge
LoopLong tool chains, many turns per requestShort turns, often started by a timerOne run per ticket eventA fast model that never blocks on tools
ToolsRead, edit, run, search, gitCalendar, mail, web, remindersTickets, customer records, refundsLookups and bookings
ContextRepository guides as skills, the task listWhat it knows about you, today's agendaThe customer, the policy, the ticketThe form being filled, said out loud
StateThe session transcript and planMemory of you, pending remindersTicket history, facts already givenAnswers so far, goals still open
WorkspaceA sandbox with the repositoryA browser, documents it writesUsually none: tools reach the helpdeskNone: a worker agent does the heavy lifting
SurfaceTerminal or IDE, permission promptsTelegram, email, a web appThe ticket thread, an approvals queueSpeech, sometimes a face
TeamA reviewer or explorer subagentA research subagentA specialist, or a personA worker behind the voice

The harness blueprints work through each column in full: the primitives it uses, what you write yourself, and how it deploys.

The system

A single harness answers when spoken to. A product needs more: one agent per customer, each with its own history; work that happens tomorrow; a Slack message or a webhook that wakes the right agent (or creates it); a person who approves the refund before it goes out; other software that calls the agent over HTTP. These are five more questions, and Glove Foundry answers them:

Foundry keeps one rule that explains most of its design. Definitions are code, instances are data. An agent definition (agents/support/agent.ts) says what an agent of that kind can assemble, and every field may be a function of the instance, the conversation and the incoming message. An instance is a persisted record: its id, its context, the capabilities installed on it, its playbooks. Every run reloads the instance and assembles a fresh Glove harness from the definition, in its own process. So a customer's agent can gain a tool by installing it, with no deploy.

Outside worldSlack · email · webhooksTransmissionverify · normalisePlaybookmatch · provisionSchedulescron · interval · sleepInstancedefinition + dataClienttyped · REST · OpenAIConversationdurable threadRuna fresh Glove per runReplyoutbound toolApprovalpause · approve · denyInspectorevery run and calleventtypedroutes · createsactivationmessagehistoryassemblesrepliesasksemits
How work reaches a Foundry agent and what comes out. Events from the outside world pass through a transmission and a playbook, which may create the instance that handles them; schedules wake an instance on their own; clients send messages into a conversation. Every run assembles a fresh Glove from the definition, the instance and the message, in its own process.

Production

A system that works on your laptop still has to run somewhere. It needs to stay up and restart cleanly, and its state has to survive a redeploy. It needs keys for model providers, browsers and sandboxes it can trust with untrusted pages and code, and an email address. Someone has to see what it did last night and what that cost. Kuiper is a deployment platform built for exactly this: it detects a Foundry folder and deploys it with no Dockerfile, the way Vercel deploys a Next.js app.

Kuiper projectKuiper gatewayPeople · appsyour domainFoundry unitglove foundry start/data diskdata · transcripts · VFSPostgresRedis · bucketsSecretssealedModelsyour provider keysBrowsersreal ChromeSandboxeskuiper/coding …Inboxemail in and outDashboard · CLI · MCPlogs · runs · model calls · usage · budgetsHTTPSreads · writesvariablesone keyreads runs and logs
A Foundry agent on Kuiper. The unit is built from your folder or repository and served over HTTPS; Foundry's data, transcripts and memory live on its /data disk; databases and secrets are wired in by variable templates; one gateway key reaches the model providers, browsers, sandboxes and inbox. The dashboard reads the agent's runs through the node, without your app's token leaving Kuiper.

The rules the primitives follow

Glove's packages were written to a handful of rules. Knowing them lets you guess an API before you look it up, and tells you where your own code belongs.

  1. The model reaches everything through tools. A subagent is a tool (glove_invoke_subagent). An MCP server's operations become tools. A browser is a tool that runs a script (execute_browser). In Foundry, an outbound Slack reply is a tool generated from a transmission. If you can describe it as a tool, every other primitive (permissions, approvals, summaries, tracing) already applies to it.
  2. Every boundary is an adapter. Models, stores, display managers, subscribers, memory stores, mesh transports, filesystem backends, sandbox backends and Foundry's data layer are interfaces. Glove ships a reference implementation of each; production swaps in yours without touching agent code.
  3. Capabilities mount; they don't wrap. Packages attach to an agent you already built (mountMcp(glove, …), useFormRunner(glove, …), mountBrowser(glove, …)) and never replace its model or loop. So they compose: a voice agent with memory, a sandbox and an MCP server is four mounts on one Glove.
  4. Live state goes at the tail, not in the prompt. The system prompt and saved history are a stable prefix, which providers can cache. Current state (the open form, the goal checklist, pinned facts, the latest screenshot) arrives through context providers just before each model call and is never saved to history.
  5. Work happens in files and code, not in context. Large data lives in a virtual filesystem or a REPL binding; the model writes a program that reads, filters and computes, and only the answer comes back. That is how one tool replaces fifty and how a 40 MB spreadsheet never enters the window.
  6. Asking a person is a primitive. In an app, pushAndWait suspends a tool until the user answers. In Foundry, a permission-gated tool becomes an expiring approval record anyone with access can resolve. Neither needs a pause/resume protocol of your own.
  7. Credentials never reach the model. Foundry stores account references, not secrets; adapters you own resolve them at call time. On Kuiper, provider keys stay at the gateway and units get a scoped gateway key.

Where to go next