Skip to content

Your first workbench

You’ve installed Monoceros - if not, start with Installation. Now for your first workbench: set your identity and tokens once, describe a container, and let an agent work inside it.

Commits made inside a container need a name and email. Set them once for every container in monoceros-config.yml:

monoceros-config.yml
defaults:
git:
user:
name: Jane Doe
email: jane@example.com

You can also skip this and let the first monoceros apply ask you - it offers to save the answer here. Either way, a container or a single repo can override it later; see Commit identity.

For private repositories, to push to public ones, and to sign in gh / glab inside the container, add a personal access token to monoceros-config.env:

monoceros-config.env
GITHUB_API_TOKEN=ghp_...

Creating a token walks through it for each provider, and Several accounts covers how Monoceros picks the right one. A read-only clone of a public repository needs none, so you can come back to this.

Time to build something real. You don’t need an existing repository to start - spin up a fresh project and let Claude scaffold it inside the container.

First, monoceros init describes the workbench and writes it to a config file. Here you ask for a Node toolchain, the Claude Code agent, and one exposed port - 3000 - so you can reach the API from your host once it is running:

Terminal window
monoceros init acme --with-languages=node --with-features=claude --with-ports=3000

That creates two files: the config at ~/.monoceros/container-configs/acme.yml and its secrets at ~/.monoceros/container-configs/acme.env. Compare them with yours:

schemaVersion: 1
name: acme
runtimeVersion: 1.8.0
languages:
- node
features:
- ref: ghcr.io/getmonoceros/monoceros-features/claude-code:1
options:
apiKey: ${CLAUDE_CODE_API_KEY}
git:
user:
name: ${GIT_USER_NAME}
email: ${GIT_USER_EMAIL}
routing:
ports:
- 3000

How Claude signs in is up to you. If you have a Claude API token, put it in acme.env as CLAUDE_CODE_API_KEY and Claude runs against the API. If you’re on a Claude subscription plan instead, leave it empty - Claude signs you in through your browser on the first run (step 4).

GIT_USER_NAME and GIT_USER_EMAIL are for the commits this container makes. Leave them empty to use the machine-wide identity you set in step 1, or fill them here to give this container its own git identity.

Now monoceros apply turns that description into a real, running container:

Terminal window
monoceros apply acme

The first apply pulls the base image and installs your tools, so it takes a few minutes. Every apply after that is seconds, and always rebuilds to the same result on any machine. If you skipped the git identity in step 1, apply asks for it now.

Claude is already installed and signed in inside the container. Hand it a task and it builds right there in the workbench - creating files, installing packages, running tests - without touching the rest of your machine:

Terminal window
monoceros run acme --in=projects -- claude "Create a small Express API with a /health endpoint and a test for it"

The very first run depends on how you set Claude up in step 3. With an API token, Claude asks once whether to trust it. On a subscription plan, a browser tab opens once to sign you in. Either way the session then persists across rebuilds. From there it works on its own: in Auto Mode it doesn’t stop for approval on every step, because the container is the boundary, not each prompt. When it finishes, run monoceros shell acme to step inside and see what it built.

That is the whole loop: describe a workbench, build it, hand a task to the agent. If you’d rather drive Claude from your editor than the terminal, you can attach the Claude Code desktop app to the workbench over SSH - no install or login inside the container - as described in Claude Code.

You have a running workbench with an app Claude just built. The natural next moves:

See it run. You exposed port 3000, so once the API is started it is reachable from your host at acme.localhost/health. Start it from a shell (monoceros shell acme, then run the app in projects/), or just ask Claude to. Ports are routed through the Monoceros proxy.

Keep building. Hand Claude the next task the same way - it stays in the container:

Terminal window
monoceros run acme --in=projects -- claude "Add a /todos endpoint with in-memory storage"

Add a database. When the app needs persistence, add a service and re-apply. It comes up alongside the workspace and is reachable inside the container by name (postgres:5432):

Terminal window
monoceros add-service acme postgres
monoceros apply acme

See Services for the curated set and how connection details reach the container.

Add more tools. More languages, AI agents, or CLIs - monoceros add-language / monoceros add-feature, or edit acme.yml directly, then monoceros apply again. The catalog is in Features and every yml field in Workbench configuration.

Bring an existing repo. Instead of a fresh project, point Monoceros at a repo: add --with-repos=https://github.com/you/your-repo.git to monoceros init (or run monoceros add-repo later). Monoceros clones it into projects/ and, for a GitHub or GitLab repo, adds the matching CLI. Then point the agent at it with --in=projects/your-repo. See Get your repo into a container.