The control plane
for coding agents.
Run Claude Code, Codex, Grok and three more from one surface — one at a time, or as a team on one goal. Bring your own subscription.
curl -fsSL https://dl.ycodium.com/install.sh | shIt writes its own tools.
This is a session that actually ran. The agent read the plugin API, wrote a plugin, stopped to ask, and then called the tool it had just built.
*.md.*.md.*.md:
3 README.md
The plugin (line-counter) is mounted in this thread only — it wasn't installed permanently, so it disappears when this session ends. It walks the project tree (skipping .git, node_modules, etc.), matches file basenames against your glob, and returns lines<TAB>path, sorted longest first. Say the word if you want it made permanent (ycodium_plugin_promote).A thin view of the product timeline — expanded output, diffs and the full approval card live in the app.
It looks at the page.
The agent read the page, not a description of it. It took the total off the rendered cart, fixed the line behind it, reloaded, and looked again. Both screenshots below are what it actually saw.
site/cart.js:13 — the reduce sums item.price but ignores item.qty.
Fixing it now.
cart.js:13 summed item.price without multiplying by item.qty, so the Cable's quantity of 3 wasn't counted. Fixed by changing the reduce to sum + item.price * item.qty.
A thin view of the product timeline — the browser itself, the element picker and the console live in the app.
Remote is the default, not an afterthought.
Ycodium runs on a machine you own — a spare desktop, a home server, a small cloud box — and every client connects to that one place.
- Multiple clients connect to the same environment at once.
- Close your laptop — the agent keeps running.
- Check progress from your phone.
- Switch devices and pick up the same thread.
Straight to the Host over your LAN or a reachable address. No third party in the path.
No open ports. Ycodium's relay — hosted or self-hosted — forwards the connection between your client and the Host.
Already on a tailnet? Publish the Host over Tailscale Serve HTTPS and pair through a clean MagicDNS URL.
Point the desktop app at user@host. It starts or reuses Ycodium there and forwards a local port — nothing to set up by hand on the remote box.
The relay introduces you. It never joins the session.
A direct connection cannot reach a machine behind a router you do not control. The relay's job is to put the two ends in touch — not to carry what they say. The session is sealed end to end, and the relay forwards bytes it cannot read.
- which environment a client is asking for
- an endpoint to hand back, good for two minutes
- the size and timing of the bytes it forwards
- anything inside the session
- your machine's static key, or your client's
- a credential it could mint or replay
The session identity is the host's static key and the client's, not a TLS certificate or a tunnel hostname. Your server generates its key on first run and the client pins it; TLS still carries the ciphertext, but it is no longer what you are trusting.
connect returns an environment id, an endpoint and a two-minute expiry. No credential, and it never mints one for you — the client authenticates the endpoint with the grant it already holds, or you pair first.
One set of handlers runs either as a Cloudflare Worker or as a plain Node process, so a self-hosted relay and a hosted one are interchangeable. Neither holds a host key, which is what makes swapping them safe.
Bring your own sub
Ycodium doesn't resell tokens. Plug in the agents you already pay for with the credentials you already have — six come set up by name, and anything that speaks ACP is one command away.
Two accounts on one provider, side by side.
An account is an instance: its own login, its own default model, its own colour. Nothing is shared between them, and the choice rides on the turn — switch mid-thread and the next turn runs on the other account.
CLAUDE_CONFIG_DIR=~/.claude-a- Its own login
- Its own default model
- Its own proxy
CLAUDE_CONFIG_DIR=~/.claude-b- A different login
- A different default
- Direct, no proxy
The driver hands each instance its own config directory when it launches the CLI, so the two logins never overwrite each other. Codex works the same way through CODEX_HOME; the ACP vendors each name their own variable.
displayNameaccentColorenvironmentproxyIdenabledhiddenModelsmodelOrderdefaultModel
- The picker shows who is signed in on each one — read from that instance's own credential file, decoded for display and never used to authorise anything
- Sign in headlessly where the CLI supports a device code: it prints a URL and a code and polls until you approve, so a machine with no browser can still hold an account
- The model selection travels on
thread.turn.start, not on the thread, so one conversation can run turns on two accounts
One thread, three surfaces.
Start a thread on the web, keep it going on desktop, check in from your phone — same environment, same history, no hand-off required.
Or @ a bot in Telegram, WeCom or Lark: the work lands in a normal thread on a normal project, and you pick it up later from any of the three.
Everything else, without leaving the thread.
The panel on the right carries the tools you would otherwise switch windows for. They follow the project you have open, and they run on the environment — not in your browser.
Stage, unstage, commit, switch branch or worktree. Publish a local repository to GitHub or GitLab and wire up the remote in one flow.
Browse, open, edit, search, upload and download — on the machine the agent works on, not a copy of it.
A real shell on that same machine, in a drawer under the conversation.
Read and review GitHub pull requests and GitLab merge requests in the panel.
A built-in preview for the dev server the agent just started.
Four settings, per thread, from the composer: ask every time, auto-accept edits, auto, or full access.
Teach it your tools once. Every agent gets them.
Add an MCP server or a skill in Settings and every provider Ycodium launches receives it. Ycodium never edits a provider's own config files — it passes the entries at launch time, so nothing you set up by hand gets overwritten.
stdio, http or sse, with per-CLI switches and a health check that runs from the environment. A CLI that cannot speak a transport is shown disabled, never silently skipped.
A folder with a SKILL.md, written where Claude, Codex and OpenCode look for it. Two switches decide whether the agent may call it and whether you may.
Environment entries apply to every project on that machine. Entries in a repository's ycodium.json travel with the repo and win on a name clash.
And the product itself is plugins.
The chat bridge, the pull-request panel, session import — each one is a plugin, mounted through the same API a plugin you write gets. Nothing in it is reserved for us.
ctx.toolkit()tools the agents can call, over MCPctx.command()a command the clients can dispatchctx.reactor()a reaction to orchestration eventsctx.interval()a background loop the host stops for youctx.cli()a ycodium subcommandctx.settingsCard()a card in Settings, secrets includedui.pagesa page of your own inside the appui.panelspanels docked beside the conversationui.appearancea theme pack, one per plugin
fs.readread files, path prefixes declared up frontprocess.spawnrun a program from an allowlistprocess.workspaceand run it inside a project directory
Anything not declared is refused at the call, not audited afterwards. The approval card lists what a plugin asked for before you say yes.
conversationtool-displayskill-discoveryconnector-registrytelemetrytrace-diagnosticsplugin-center
Which is the honest test of a plugin API: if it could not carry the product's own features, it could not carry yours. The first demo on this page is an agent writing one of these from scratch and running it in the thread.
Your agents deserve better than a terminal.
Install it, plug in the harness you already pay for, and let your agents get to work.
curl -fsSL https://dl.ycodium.com/install.sh | sh