The publish button for coding agents

Your agent built it. Your team can use it in two minutes.

Your agent finishes the app. Spryloom runs it for your team behind company sign-in, with a database, HTTPS and a link you can send. No infrastructure, and no auth code in the app.

$ claude mcp add spryloom -- spry mcp
claude · vendor-reconciler
you    get it to the ops team

agent  Publishing to Spryloom.

       Building22s
       Database created
       Sign-in anyone at acme.com
       Certificate issued

       Live at
       https://vendor-reconciler.acme-com.spryloom.app

you    invite ryan@acme.com as admin

agent  Invited 1 person. They'll get a link and
       sign in with it.
Claude CodeCodexCursorspry publishClaude and Cursor marks belong to Anthropic and Anysphere. Spryloom is not affiliated with or endorsed by either, or by OpenAI.

What you get

Everything between “publish” and a link you can send

Nothing is reported until the new version answers a real request. A publish that fails changes nothing: the previous version keeps serving, and the failure names the step that broke.

One call from the agent

Your agent wrote spryloom.yaml during the build. Spryloom reads it, builds in a sandbox, runs in one VM per app, and puts HTTPS and sign-in in front.

Read spryloom.yaml stack, sign-in, roles, tables
Build sandboxed, registry only
Run one VM, capped cpu, memory, disk
Database one per app, one role
Front door HTTPS, sign-in proxy

No sign-in code in your app

Coworkers sign in with an email link. The app is told who they are in plain headers, signed and bound to this app. Anything with that name arriving from outside is stripped first.

x-spryloom-email: attacker@evil.teststripped
x-spryloom-email: ryan@acme.comx-spryloom-role: admin
x-spryloom-app: vendor-reconciler

One database per app

Its own database, its own role, kept across every republish.

vendor-reconcilerrole: app_aown db
onboardingrole: app_bown db
expense-notesrole: app_cown db

Decide who gets in

Four choices. There is no public mode.

privateOnly you
invitedPeople you name
companyAnyone at acme.com
linkAnyone with the address, signed in

Undo in one step

Every version is kept. Roll back with the data untouched.

v3today 14:02
v2← rolled back to
v1Monday

Use cases

Built in an afternoon, in use by Monday

Small software for a handful of people. The kind that never got built because deploying it cost more than writing it.

SSarah, operations at AcmeBuilt with Claude Code

An internal tool for the team

A vendor invoice reconciler that matches invoices against purchase orders. She needs four coworkers using it by Friday, and nobody in IT has heard of it.

visibility: companyroles: admin sarah@acme.com, ryan@acme.comdata: invoices, purchase_orders, matches
Anyone at acme.com can open it. Anyone else is refused, and told nothing about whether it exists.
EEmily, freelancer on GmailBuilt with Cursor

A tool for a client with no IT

A booking tool for a yoga studio, built in an evening. The studio owner is on Gmail too, and has no domain, no admin, and no patience for accounts.

workspace: emily · personal, not gmail-comvisibility: invited jessica@gmail.comdata: classes, bookings
Jessica opens it on her phone from a link in email. No account, no app store, no IT.
MMike, engineering managerBuilt with Codex

A tracker for one team

An on-call handover log for the six people on the rota. The second lead is admin. The third version broke the form, so he rolled back to the second in one step.

visibility: invited · six peopleroles: admin mike@, dana@versions: v1 · v2 ← live · v3
Rolled back with the data untouched. The old version was retired only once the earlier one answered.

Security

What a published app can reach

Not a policy somebody checks. The rule is applied outside the app, by the host it runs on, so nothing the app does can switch it off. Each tile is tried from inside a running app by a script that attempts it.

ALLOWEDIts own databaseOne database, one role, credentials injected at start.
BLOCKEDThe internetNo web, no mail, no outbound route. One port stays open for the app's own database.
BLOCKEDAnother appEach app on its own network, no shared runtime.
BLOCKEDAnother app's databaseRefused by Postgres, not by a rule in front of it.
BLOCKEDSpryloom's recordsThe platform's endpoints are on a listener the app cannot see.
Separate domainApps live on spryloom.app, the dashboard on spryloom.com. An app cannot reach the dashboard's cookies, by construction.
Secrets never come back outEncrypted at rest, bound to their app, injected at runtime. No command shows a value.
An audit log that refuses bad entriesEvery sign-in, invite, role change and publish, with the actor. An entry carrying a token is rejected.
A kill switch the owner cannot undoAn operator can stop any app before understanding the incident, and it is on the record first.

Release 1, exactly

What it does today, and what it does not

Cut scope, never completeness. Everything on the left works end to end. Everything on the right is refused with a clear message rather than half done.

Does

  • Node backends and static or React frontends
  • Publish from Claude Code, Codex, Cursor, or the terminal
  • Import a folder, a zip, or a GitHub repository
  • A Postgres database and secrets per app
  • Email-link sign-in, invitations, two roles
  • Versions, rollback, restart, logs, archive
  • A read-only dashboard and an audit log

Does not

  • Python, or any backend other than Node
  • File uploads or scheduled jobs
  • Outbound calls from an app to other services. Declaring one is refused.
  • Google or Microsoft sign-in. Email link only, which works for both.
  • A public mode. Apps are for people you can name.
  • Open signup. Invitation only until the first outside teams have used it.

If your app needs one of these, it is not a fit yet, and we would rather say so here than after you have published.

An app is always for people you can name. There is no public mode, on purpose.

That one rule keeps abuse, cost and trust simple.

Release 1

Free, and by invitation for now

We are onboarding teams one at a time and watching the first coworker sign in. Tell us what you built and who it is for.

Freepersonal and team use
Nodebackend or static frontend
$0while an app is asleep