# Glove on Kuiper

> How an agent built with Glove and Glove Foundry runs on Kuiper. Which Kuiper service backs each part of the agent, what to set before the first deploy, and the steps for a personal agent, a support desk, a coding agent and a web or voice front.

Web page: https://kuiper.sh/docs/glove/

## Three layers

[Glove](https://glove.dterminal.net) is a TypeScript framework for building agents. Kuiper runs what you build with it. An agent you deploy here has three layers:

| Layer | Built with | What it adds |
| --- | --- | --- |
| Harness | Glove | The agent loop, tools, what the model sees, what it remembers, a workspace for files and code, and the way people reach it |
| System | Glove Foundry | Many agents from one definition, conversations, schedules and sleep, inbound channels, approvals, an HTTP API and an inspector |
| Production | Kuiper | Somewhere to run it, somewhere to keep its state, models, browsers, sandboxes and mail to reach, and a way to watch it |

Glove's [first principles](https://glove.dterminal.net/docs/first-principles) page explains each part, and its [primitives map](https://glove.dterminal.net/docs/primitives) lists what already exists for each one. This page covers the last layer: what Kuiper gives a Foundry app, and what you set up for it.

![A Kuiper project with a Foundry unit. People and apps reach the unit over HTTPS. The unit reads and writes its /data volume, takes database URLs and secrets through variables, and calls the gateway's models, browsers, sandboxes and inbox with one key. The dashboard, CLI and MCP read its logs and runs.](https://kuiper.sh/docs/img/glove-on-kuiper.svg "A Foundry agent on Kuiper: one unit, its volume, the project's databases and secrets, and the gateway's services.")

## What backs what

Each part of a Glove agent has a Kuiper service under it:

| In your agent | On Kuiper |
| --- | --- |
| `glove foundry start` | A unit, built from your folder or repository with no Dockerfile. See [Glove Foundry units](https://kuiper.sh/docs/foundry.md). |
| `FileFoundryDataAdapter`: instances, conversations, schedules, workspace data | A file on the unit's volume, `/data`. It stays across restarts and deploys. |
| Conversation stores, `glove-memory/sqlite`, working environment snapshots | Files on `/data` too, or your own adapter on a [managed Postgres](https://kuiper.sh/docs/databases.md). |
| Schedules, sleep and playbook subscriptions | One running copy of the unit. Every Foundry runtime arms the schedules it finds, and a unit with a volume always runs one copy, so each schedule fires once. |
| `createAdapter` from `glove-core` | The [model gateway](https://kuiper.sh/docs/models.md), with your own provider keys. Every call is recorded with its tokens and cost. |
| Glove tools that drive a browser | [Browsers](https://kuiper.sh/docs/browsers.md): real Chrome behind Steel's API, with profiles for logins. |
| Glove tools that run code | [Sandboxes](https://kuiper.sh/docs/sandboxes.md) from [ready-made images](https://kuiper.sh/docs/sandbox-images.md), or Station's own container sandboxes on the unit. See [Browsers and sandboxes from glove-execution](#browsers-and-sandboxes-from-glove-execution). |
| An agent's email | A [mailbox](https://kuiper.sh/docs/inbox.md), and the Glove tools in `@kuiper-sh/inbox/glove`. |
| `requestAuthorization` and a bearer token | The unit's **Inspect** card and the project's **Agents** page, which read runs, conversations and approvals from Foundry's own API. |
| API keys in `.env` | [Secrets](https://kuiper.sh/docs/variables/#secrets), bound into the unit's variables. They never enter the image and are redacted from logs. |
| Foundry's event stream | Logs that survive restarts, [network logs](https://kuiper.sh/docs/network.md), and [usage](https://kuiper.sh/docs/usage.md) with [budgets](https://kuiper.sh/docs/budgets.md). |

The built-in `models`, `browsers`, `sandboxes` and `inbox` resources give each running copy of a unit the gateway's address and a key. Reference the outputs, under names of your choosing:

| Output | What it is |
| --- | --- |
| `${{models.BASE_URL}}` | The base URL for Glove's providers, except `anthropic` |
| `${{models.ANTHROPIC_BASE_URL}}` | The base URL for Glove's `anthropic` provider |
| `${{browsers.BASE_URL}}`, `${{sandboxes.BASE_URL}}`, `${{inbox.BASE_URL}}` | The other services |
| `${{models.API_KEY}}` | The running copy's gateway key. Any service's `API_KEY` is the same key |

The key opens only the services the unit's variables reference. A unit that calls models and reads mail references both `${{models.…}}` and `${{inbox.…}}`. See [Variables and secrets](https://kuiper.sh/docs/variables/#models-browsers-sandboxes-and-the-inbox).

## Before the first deploy

A Foundry app needs four things to run well here.

1. **Keep state on the volume.** Foundry's default data adapter lives in memory, and each run starts a new process, so a plain in-memory conversation store forgets earlier turns. Write both to `/data`:

   ```ts foundry.application.ts
   import { defineApplication, FileFoundryDataAdapter } from 'glove-foundry';

   export default defineApplication({
     name: 'concierge',
     data: new FileFoundryDataAdapter({ file: '/data/foundry.json' }),
     // conversationStore: a durable store, also under /data
     // requestAuthorization: see step 2
   });
   ```

   Glove's [persistence guide](https://glove.dterminal.net/foundry/docs/persistence) covers the four kinds of state to keep: Foundry's data, transcripts, memory and the working environment's files.

2. **Add an authorizer.** Foundry won't listen on a public address without `requestAuthorization`. [Add an authorizer](https://kuiper.sh/docs/foundry/#add-an-authorizer) has one that accepts a bearer token and a dashboard login.

3. **Call models through the gateway.** `@kuiper-sh/sdk` gives Glove's `createAdapter` its base URL and key:

   ```ts agents/concierge/agent.ts
   import { Kuiper } from '@kuiper-sh/sdk';
   import { createAdapter } from 'glove-core/models/providers';
   import { defineAgent } from 'glove-foundry';

   const kuiper = new Kuiper(); // reads KUIPER_GATEWAY_KEY

   export default defineAgent({
     description: 'Answers for Acme',
     model: () => createAdapter({ provider: 'anthropic', model: 'claude-sonnet-5-5', ...kuiper.models.glove('anthropic') }),
     systemPrompt: 'You answer questions for Acme. Use your tools for facts.',
   });
   ```

   ```sh
   kuiper providers add anthropic --key -
   kuiper env set -u concierge 'KUIPER_GATEWAY_KEY=${{models.API_KEY}}'
   ```

   Without the SDK, pass `baseURL` and `apiKey` yourself: see [Models](https://kuiper.sh/docs/models/#glove).

4. **Deploy.**

   ```sh
   kuiper units create concierge
   kuiper deploy --source . -u concierge --wait
   ```

   To deploy on every push instead, `kuiper link` the repository. See [Deploying](https://kuiper.sh/docs/deploying.md).

Then turn on the [Foundry inspector](https://kuiper.sh/docs/foundry/#log-in-from-a-browser) login, and generate the token the **Inspect** card reads with.

## Deploy a harness

The same unit takes different shapes of agent. These are the steps for four common ones.

### A personal agent

An assistant you message, that remembers you, sets reminders, browses and writes back.

1. **Give it a mailbox.** Run `kuiper inbox create assistant` and return `inboxTools(inbox, { mailbox: 'assistant' })` from the agent's `tools`. [Example: an email agent](https://kuiper.sh/docs/email-agent/#in-a-glove-foundry-app) has the code.
2. **Let it check in on its own.** Foundry's built-in `glove_foundry_schedule` and `glove_foundry_sleep` tools create reminders and wake-ups. They are kept in `/data` and survive deploys.
3. **Give it a browser.** Use [Browsers](https://kuiper.sh/docs/browsers.md) from a tool, with a [profile](https://kuiper.sh/docs/browsers/#profiles) so logins carry over between sessions.
4. **Keep its memory on the volume.** Point `glove-memory`'s SQLite adapters at a file under `/data`.
5. **Reach it from a chat app.** A chat platform that you poll, such as a bot's long-polling API, needs no public route. One that calls a webhook goes through a small forwarding unit, as in the support desk below.

### A support desk

Agents per customer that wake when a ticket or message arrives.

1. **Model the channel in Foundry.** A transmission and a playbook decide which agent takes each event. See [Apps and transmissions](https://glove.dterminal.net/foundry/docs/applications) in Glove's docs.
2. **Receive the provider's webhook in a second unit.** Foundry's API sits behind your authorizer, so a ticket system can't call it directly. Deploy a small web unit that checks the provider's signature and forwards the event with `dispatchInbound` from `glove-foundry/client`.
3. **Reach Foundry privately.** Point the web unit at the Foundry unit's private address, which needs no public route:

   ```sh
   kuiper env set -u hooks 'FOUNDRY_URL=${{concierge.INTERNAL_URL}}'
   ```

4. **Keep customer data in Postgres** if you outgrow files: `kuiper db create postgres main`, then reference `${{main.DATABASE_URL}}`.

A tool that needs approval pauses the run until someone approves or denies it, in the inspector or through Foundry's API, or until the request expires.

### A coding agent

An agent that writes code and runs it somewhere other than your unit's own process. Two ways work today:

1. **Kuiper's sandboxes, from your own tools.** `kuiper.sandboxes.create({ image: 'kuiper/coding' })` gives a remote computer with a terminal, files and ports. It runs on separate machines, is billed by the second and can [hibernate](https://kuiper.sh/docs/sandboxes/#hibernate-a-sandbox). See [Sandboxes](https://kuiper.sh/docs/sandboxes.md).
2. **Station's container sandboxes, on the unit.** Foundry's managed Station can host `ContainerSandboxAdapter` from `station-sandbox`, which agents reach with `mountSandbox` from `glove-execution`. When your app depends on `station-sandbox`, the builder adds the Docker CLI and asks for a Docker socket that Kuiper serves. Start images by name, such as `kuiper/coding`; see [Sandbox images](https://kuiper.sh/docs/sandbox-images.md).

### A web or voice front

A Next.js app, or a voice host, in front of durable Foundry agents.

1. **Deploy two units from one repository:** the Foundry unit, with its root set to the Foundry app, and the web or voice unit with its own `kuiper.json`.
2. **Connect them privately** with `${{concierge.INTERNAL_URL}}`, as in [Next.js with Foundry](https://kuiper.sh/docs/foundry/#next-js-with-foundry).
3. **Keep the voice provider's key a secret** of the voice unit. The voice host hands durable work to Foundry over the private address.

## Browsers and sandboxes from glove-execution

`glove-execution` gives a Glove agent `execute_browser` and `execute_sandbox`. Its adapters today drive browsers and sandboxes that a Station hosts. It has no adapter for Kuiper's gateway yet.

- **Station on the unit.** Foundry's `stationDaemon` hosts Station's container sandboxes and browsers, and the agent mounts them. On Kuiper, depending on `station-sandbox` or `station-browser-use` gives the unit a Docker socket that Kuiper serves and polices. Every container runs under gVisor within the unit's limits. Images other than Kuiper's ready-made ones must be on your operator's allowlist.
- **Kuiper's services in your own tools.** Call [Browsers](https://kuiper.sh/docs/browsers.md) and [Sandboxes](https://kuiper.sh/docs/sandboxes.md) through `@kuiper-sh/sdk` from Glove tools you write. They run apart from your units and are held to your [budgets](https://kuiper.sh/docs/budgets.md).

## Next

- [Glove Foundry units](https://kuiper.sh/docs/foundry.md) What the builder does, the authorizer, the inspector login and the Inspect card.
- [Example: an email agent](https://kuiper.sh/docs/email-agent.md) A unit, a mailbox, its webhook, variables and models, step by step.
- [Models](https://kuiper.sh/docs/models.md) Provider keys, fallbacks, and every call recorded.
- [Variables and secrets](https://kuiper.sh/docs/variables.md) How `${{…}}` references work.

On Glove's site, [Put it in production](https://glove.dterminal.net/docs/build/production) walks one agent from a laptop to Kuiper, and [Deploy on Kuiper](https://glove.dterminal.net/foundry/docs/kuiper) is the Foundry side of this page.
