Open source · MIT · Self-host or managed

Claude Code that doesn't
close when you do.

The session lives on a machine of its own, not in a terminal on your laptop. Start something at a desk, follow it from a phone on the way out, and let a long job finish while both are shut. The full VS Code editor is there when you sit back down.

Three Cs: Claude, Code, Cloud. The cloud is the part that's ours. Everything above it is Anthropic's CLI, running unmodified.

It's the real CLI

Not a reimplementation. Each conversation is one long-lived claude process, so context, working directory and session id all persist — and a follow-up message costs no startup.

One session, every device

History and the process both live on the server. A laptop and a phone are two windows onto the same conversation, mid-task, with no handoff step. Lock the screen and the work carries on.

Your code stays put

One instance, one persistent volume, one GitHub token — in an account that is yours if you self-host, and one customer's alone if we run it. Voice dictation transcribes on the box itself.

Two ways to run it

Same code, same MIT licence, same repository. The difference is whose account the machine boots in, and who gets paged when it doesn't.

Self-hosted

Freeand not a trial

You run it, in your own AWS account

  • All of it is in the repository. Nothing is held back, no feature is gated, there is no licence key to obtain.
  • You pay AWS, not us — roughly $75/month for the instance and load balancer left running, plus model usage.
  • Your account, your IAM, your volume, your token. We have no access to it and the app phones nothing home.

We are not charging anyone yet, and that button is not a checkout. There is no card field, no invoice and no meter running. Clicking it records that you would be willing to pay by usage once there is something to pay; until then the managed service is free, and you can walk away from it owing us nothing. When that changes you will be told first, in advance, with the numbers — and self-hosting stays free regardless, because it is the same MIT-licensed repository either way.

How it works

One EC2 instance behind a load balancer, with a persistent volume that survives instance replacement. No Kubernetes, no control plane, nothing to operate. Managed is this same diagram in our account instead of yours — not a different product.

your-domain.com
  │
  ALB :443 ── TLS, 4000s idle timeout (a turn can run for many minutes)
  │
  EC2 t4g.large (Graviton) — reachable only from the load balancer
  ├── nginx
  │     ├── /         → chat  (the PWA you install)
  │     └── /editor/  → code-server + the official Claude extension
  │
  ├── chat service
  │     ├── authenticates every request itself   ← the security boundary
  │     ├── one `claude` process per conversation, kept alive
  │     └── whisper.cpp for voice, on the box, no API key
  │
  └── /workspace  ← persistent EBS
        ├── projects/   one directory per repo
        └── claude/     session history

  Bedrock via instance role — no model keys in the browser

Installs like an app

Add to Home Screen on iOS, or the install icon on Android and desktop. Streaming replies, collapsible tool cards, a stop button, and voice dictation that inserts at your cursor.

Survives bad networks

The server keeps the process alive when a phone locks or the signal drops. Reattaching resumes the same conversation mid-task — including work you started on another device.

Read this part

This is a web page that runs shell commands on a machine. That's the product, not a side effect. Anyone who logs in has a shell. Deploy it as one person's workspace — not a shared service, and not something you hand a password to a stranger for.

Which is why authentication is enforced inside the process that spawns claude, and never delegated to nginx or the load balancer alone. That design comes from getting it wrong: an earlier version of this project shipped with the chat API reachable without credentials, because a proxy config described a gate that had never been written and every document repeated the claim.

Closed by default

  • The server refuses to start without a strong password and cookie key.
  • Routes are gated by an allowlist, so a new endpoint is private unless deliberately opened.
  • Rotating the password invalidates every existing session.
  • Login throttling at the proxy and in the app.
  • Least-privilege IAM by default; account-wide access is opt-in and documented.

Checked by machine, not by comment

  • A test suite boots the real server and asserts that every route and the WebSocket upgrade refuse an unauthenticated caller.
  • The deploy script runs it first and refuses to deploy on failure.
  • After deploying, it curls the live URL and aborts if the API answers without a login.

The last time this was checked only by a comment, the comment was wrong for months.

Full threat model, what it does and doesn't defend against, and how to cut the blast radius: docs/SECURITY.md. What a managed instance means for the same questions: docs/MANAGED.md.

Self-host it

You need an AWS account, a Route53 hosted zone you control, and Bedrock model access enabled. About 20 minutes, most of it waiting for first boot.

1 · point it at your domain
cp triplec.config.example.json triplec.config.json
$EDITOR triplec.config.json        # domainName + hostedZoneName

2 · go
./deploy.sh

It validates your config, runs the auth tests, deploys the stack, waits for the instance, ships the app, then verifies that the live URL requires a login. Re-running it is safe and keeps your projects and history.

Bringing existing work across? ./migrate.sh clones your repos onto the volume and copies your local Claude Code history up, rewriting the paths so past conversations stay resumable.

What it isn't

Multi-user

One shared password, no per-user permissions, no audit of who did what. It's one person's workspace — and a managed instance is one customer's.

Free of infrastructure

Self-hosted, it's about $75/month of AWS left running, plus model usage. Managed, that bill is ours for now — which is exactly why "free" has a "for now" attached.

Sandboxed

Claude runs with real permissions by default. Prompt injection reaching a shell is a genuine risk with no clean fix.