# AGENT.md — somewhere.cloud for coding agents ## How Somewhere works Somewhere is in public beta. Somewhere is the backend for apps your agent builds. One project gives your app its web address, server functions, one SQL database, sign-in, files, email, AI and background work. Write React and TypeScript, then run `somewhere deploy`. The platform compiles your source and serves the app and its functions together. Somewhere runs on Cloudflare. Functions run on Workers, each project has its own D1 database, files are stored in R2, and Durable Objects coordinate real-time channels and releases. Replicas and limits: `docs({ topic: 'database-engine' })`. A starter has these parts: | Part | Source | Purpose | |---|---|---| | App | `src/`, `index.html` | The interface and browser routes. | | Functions | `api/` | Server code: `api/notes.ts` answers `/api/notes`. Every handler receives `sw`, bound to the project. | | Data | `db/schema.ts` | Optional: tables, columns and access rules, applied on deploy. The default starter has none. | | Auth | `api/auth/[...path].ts`, `src/auth/` | Working sign-in and session hooks to extend. | The default starter includes sign-in screens; minimal includes the SDK and auth route, while bare omits both. Browser sessions use Secure, HttpOnly cookies. Normal owner-table operations get the user from the verified session and scope rows to that user. A table's `client` block chooses which operations and columns the browser may use. Your functions decide who may perform privileged actions. Check the caller before using server authority, sending an email or charging a card. Keep secrets in `sw.env`, read them inside handlers, and make repeated effects safe with a stable operation identity. Deploy raw source from the app root; the platform handles compilation. Expose a browser value only with `public: true` and a `VITE_` or `REACT_APP_` name; visitors can read it. Start with **Start an app**, **Data**, **Auth**, **Functions** and **Env vars and secrets**. Each primitive opens with one working path and links to deeper sections. Recipes contain complete jobs and live outside this short reading path. The index below lists every topic, including specialized capabilities. Use `somewhere docs ` or MCP `docs({ topic })`. To load one section, use `somewhere docs --section ` or `docs({ topic, section })`. Use an explicit full view for the complete reference. Recipe first calls already return the whole recipe. ## Complete capability index Read any topic for its examples, signatures and limits. ### How Somewhere works - **Handled for you — the foundation behind your app** — Built-in work and the choices your app owns. `docs({ topic: 'handled-for-you' })` - **Database — SQL support, capabilities, and limits** — Capabilities, limits, concurrency, supported SQL. `docs({ topic: 'database-engine' })` - **Security model — who can read/write what** — Developer, project, end-user, and server authority boundaries. `docs({ topic: 'security-model' })` - **Built-in protections — what the platform handles** — Runtime, deploy and safety responsibilities. `docs({ topic: 'guarantees' })` - **Portability — getting your data out** — Export data and move your app. `docs({ topic: 'portability' })` ### Primitives - **Start an app** — Build, deploy, and verify a first app. `docs({ topic: 'getting-started' })` - **Deployed Functions** — Server routes, HTML pages and SPA coexistence with Request/Response and sw. `docs({ topic: 'functions' })` - **sw.env — Environment Variables (inside deployed functions)** — Server keys and deliberate public browser keys in one store. `docs({ topic: 'sw.env' })` - **Declared data — the schema file is the contract** — Schema, access rules, typed client. `docs({ topic: 'declared-data' })` - **Groups** — Shared rows, invites and roles. `docs({ topic: 'sw.groups' })` - **sw.db — Database (inside deployed functions)** — Queries, atomic writes, live views and server SQL. `docs({ topic: 'sw.db' })` - **Auth — End-User Authentication** — Sign-in, sessions, OAuth and account settings. `docs({ topic: 'sw.auth' })` - **Files** — Who reads, uploads, replaces, deletes files; somewhere:files. `docs({ topic: 'declared-files' })` - **sw.fs — File Storage (inside deployed functions)** — Store, read, version, publish, sign, move, and upload files. `docs({ topic: 'sw.fs' })` - **Email** — Email on every plan: managed sender for users/owner; own sender domain for anyone. Caps: `/v1/pricing`. `docs({ topic: 'sw.email' })` - **AI and search** — Text, image, speech, embeddings, moderation, memory and agents. `docs({ topic: 'sw.ai' })` - **Search — managed document search and named indexes** — Search files or build semantic indexes over app data. `docs({ topic: 'search' })` - **Somewhere agent loop — sw.agent** — Bound agent steps and spend; hooks, durable status, retries. `docs({ topic: 'sw.agent' })` - **Jobs and schedules** — Background jobs: status, retries, cancel. `docs({ topic: 'sw.jobs' })` - **Cron — Scheduled Tasks** — Schedule recurring function execution with cron expressions. `docs({ topic: 'cron' })` - **Payments** — Onboard sellers; charge, refund, reconcile. `docs({ topic: 'payments' })` - **Deploy and domains** — Deploy source, promote, roll back and undeploy. `docs({ topic: 'deploy' })` - **Custom Domains** — Attach, verify, inspect, and remove custom domains. `docs({ topic: 'domains' })` - **Test, observe and troubleshoot** — Test live pages, screenshots and interactions. `docs({ topic: 'browser' })` - **sw.endpoint — declarative endpoint wrapper** — Optional auth, validation and rate limiting around a handler. `docs({ topic: 'sw.endpoint' })` - **sw.fetch — outbound HTTP fetch from a function** — Policy-checked outbound HTTP requests from deployed functions. `docs({ topic: 'sw.fetch' })` - **sw.rateLimit — Rate limiting** — Limit requests and actions. `docs({ topic: 'sw.rateLimit' })` - **sw.notifications — unified notify primitive** — One notification through bell, push, or zero-setup email. `docs({ topic: 'sw.notifications' })` - **sw.push — Web Push notifications** — Browser notifications; per-device send history. `docs({ topic: 'sw.push' })` - **Inbox — Inbound Email** — Receive, search, thread, reply to, and route inbound email. `docs({ topic: 'inbox' })` - **Live updates — a browser subscribing to a declared database view** — Subscribe a browser to a declared live view. `docs({ topic: 'live' })` - **Project groups** — Organize projects with shared access and themes. `docs({ topic: 'project-groups' })` - **Render — PDFs** — Render HTML or URLs into PDF documents. `docs({ topic: 'render' })` - **sw.web — Read pages from the public web** — Read and extract content from public web pages. `docs({ topic: 'sw.web' })` - **sw.image — Image transformations** — Transform, resize, convert, and optimize image assets. `docs({ topic: 'sw.image' })` - **Calendar — atomic holds and reservations** — Atomic time holds, availability, confirmation and release. `docs({ topic: 'calendar' })` - **sw.billing — plans & feature gating for YOUR app's users** — Plans and entitlements for your app's own users. `docs({ topic: 'sw.billing' })` ### Recipes and jobs - **Recipe — Sign-in, email alerts, daily reminder** — Owner rows, contact form and daily reminder. `docs({ topic: 'recipe-signed-in-app' })` - **Recipe — Sign-in: the starter, your data, then providers** — Starter login, social sign-in and magic links. `docs({ topic: 'recipe-login' })` - **Recipe — File uploads: each user's own files** — Owner-scoped uploads from the page. `docs({ topic: 'recipe-file-uploads' })` - **Recipe — Email the signed-in user** — Verified recipients, test inbox, send outcomes. `docs({ topic: 'recipe-email' })` - **Recipe — Push notifications to a signed-in user** — Notify a user; check delivery. `docs({ topic: 'recipe-push-notifications' })` - **Recipe — A background job with a status the user sees** — Per-user work, status and repeat-safe results. `docs({ topic: 'recipe-background-jobs' })` - **Recipe — AI features: suggest a title** — Signed-in model call, model choice, AI options. `docs({ topic: 'recipe-ai-features' })` - **Recipe — Read receipts with AI** — Read private receipts with AI; review and save. `docs({ topic: 'recipe-ai-receipts' })` - **Recipe — SEO: titles, previews, sitemap** — Titles, link previews, sitemap, robots and SEO checks. `docs({ topic: 'recipe-seo' })` - **Recipe — CSV import** — Upload, one job, retry-safe batched writes. `docs({ topic: 'recipe-csv-import' })` - **Recipe — PDFs** — Generate, store privately, preview, merge, split. `docs({ topic: 'recipe-pdfs' })` - **Recipe — Paid and OAuth-protected APIs** — 402 payment and 401 OAuth challenges. `docs({ topic: 'recipe-paid-api' })` - **Recipe — Bring an existing app** — From GitHub, a folder, a zip, Supabase or Lovable. `docs({ topic: 'recipe-import-app' })` - **Recipe — AI agent with tool calls** — Agent chatbot with owner rows and conversation history. `docs({ topic: 'recipe-ai-agent' })` - **Recipe — Booking / calendar app** — Start booking checkout with a calendar hold. `docs({ topic: 'recipe-booking' })` - **Recipe — Fixed-price catalog checkout** — Start a fixed-price catalog checkout. `docs({ topic: 'recipe-ecommerce' })` - **Recipe — Multi-chat (Claude.ai-style conversation list)** — Multi-conversation chat with history and search. `docs({ topic: 'recipe-multi-chat' })` - **Recipe — Cheap model escalates to smart model when stuck** — A low-cost model escalates to a stronger one when stuck. `docs({ topic: 'recipe-escalation' })` - **Live data — one poller, fan out to every client** — Recipe: one cron poller, fanned out by a live view. `docs({ topic: 'live-data' })` - **Architecture Patterns — How to wire common app shapes** — Compose primitives into common app architectures. `docs({ topic: 'architecture-patterns' })` - **Migrating a Supabase app** — Move a Supabase app and its data. `docs({ topic: 'migration-supabase' })` ### Surfaces - **Setup — Use the CLI, or connect MCP without a shell** — Connect with CLI or MCP. `docs({ topic: 'setup' })` - **@somewhere-cloud/cli — full command reference** — CLI commands and JSON output. `docs({ topic: 'cli' })` - **@somewhere-cloud/sdk — optional adapter, one auth path** — Optional SDK for browser and server code. `docs({ topic: 'sdk' })` - **Client SDK — JavaScript and TypeScript** — JS/TS SDK: starter auth, typed function calls, automation. `docs({ topic: 'sdks' })` - **Local dev — `somewhere dev`** — Run locally with `somewhere dev`; pull, typecheck, inspect. `docs({ topic: 'local-dev' })` - **Auth on the client — the correct session code** — Browser sign-in with HttpOnly cookies. `docs({ topic: 'auth-client' })` - **Typed functions — one contract, both sides** — Typed handlers and browser calls. `docs({ topic: 'typed-functions' })` - **GitHub push-to-deploy** — Deploy on GitHub push; check status. `docs({ topic: 'github' })` - **Preview — `somewhere preview` (every plan)** — Private previews for signed-in accounts on every plan. `docs({ topic: 'dev-environments' })` - **Projects — Full Lifecycle** — Create, edit, export and manage projects. `docs({ topic: 'projects' })` - **Inspect — Read live state before writing** — Inspect source, releases, routes, logs and live state. `docs({ topic: 'inspect' })` ### Reference and help - **Verify before deploy** — Typecheck, compile and handler checks, and unit tests. `docs({ topic: 'verify-before-deploy' })` - **Limits** — Function, record, env, upload, and deploy ceilings. `docs({ topic: 'limits' })` - **Deploy intelligence — what a deploy records, and where to read it** — Analysis and diagnostics after each deploy. `docs({ topic: 'deploy-intelligence' })` - **Smoke tests — deploy and recurring checks** — Automatic uptime and behavior checks. `docs({ topic: 'smoke' })` - **SQL compatibility — what Postgres code ports, and what doesn't** — How Postgres-style SQL translates and where it differs. `docs({ topic: 'sql-compatibility' })` - **PostgreSQL** — Attach a PostgreSQL database you own; use its driver. `docs({ topic: 'postgres' })` - **CORS — which browser origins may call your project's functions** — Your own origins already work; add a third-party origin. `docs({ topic: 'cors' })` - **Design System — Read before generating UI** — Starter tokens, components, themes and design. `docs({ topic: 'design-system' })` - **Pricing** — Current plans and limits. `docs({ topic: 'pricing' })` - **Plans & Pricing** — Usage, plan activation and account billing. `docs({ topic: 'billing' })` - **Pricing comparison — somewhere.cloud vs the stack** — Compare costs with a conventional assembled stack. `docs({ topic: 'pricing-comparison' })` - **You own your domain** — Domain custody, portability, renewal and detachment. `docs({ topic: 'domain-ownership' })` - **sw.logs — Application Logging (inside deployed functions)** — Write logs and inspect failures. `docs({ topic: 'sw.logs' })` - **Analytics — Track Events, Query Aggregates** — Track events and query aggregates for an application. `docs({ topic: 'analytics' })` - **Tasks — shared context for work** — Per-project work, comments, relationships, completion. `docs({ topic: 'tasks' })` - **Recent behaviour changes** — Dated behaviour changes. `docs({ topic: 'changes' })` - **Platform Feedback — Bug? Doc gap? Tell us.** — Report and follow platform or docs issues. `docs({ topic: 'feedback' })` - **Speed** — Measure latency and speed up your app. `docs({ topic: 'speed' })` - **Common Mistakes — Things real users have hit** — Avoid recurring deploy, auth, database, and file mistakes. `docs({ topic: 'common-mistakes' })` - **Troubleshooting — Common errors and what to do** — Common platform errors and their recovery paths. `docs({ topic: 'troubleshooting' })` - **File tools — project-wide search, glob, diff and integrity check** — Developer search, glob, diff, integrity checks. `docs({ topic: 'file-tools' })` - **Discovered API surface** — REST, runtime and MCP calls. `docs({ topic: 'api-surface' })` - **somewhere.cloud vs Supabase — honest comparison** — Compare capabilities and operating tradeoffs with Supabase. `docs({ topic: 'vs-supabase' })` - **somewhere.cloud vs Vercel — honest comparison** — Compare capabilities and operating tradeoffs with Vercel. `docs({ topic: 'vs-vercel' })` ## Getting started — build, deploy, verify `somewhere init --name ` writes React + TypeScript. Signed out: local only; signed in: also creates and links a project. Default: sign-in UI; minimal: SDK/auth route; bare: neither. `init --catalog --json`: modules. `npx @somewhere-cloud/cli deploy` publishes raw source: signed out, a temporary URL, claim URL and expiry; linked, your account project. On a hosted VM, `somewhere login` uses browser approval and keeps you signed in. Account operations, test inbox and cron need login. Start auth/data/cron with `somewhere docs recipe-signed-in-app --full`. After edits: `somewhere typecheck` and focused local/browser tests. Publish: 1. `somewhere deploy` (do not build first). Deploy checks compilation, schema and secrets; `somewhere deploy-check` runs them without publishing (diagnosis, review, `--run /api/x`). 2. Run `somewhere verify` on the final journey (`--flow flow.json`); rerun after fixes. Sign test users up in-app at `*.test.somewhere.site`; more: `actors` + `journey` (`somewhere docs browser`). 3. Inspect: `somewhere browser`; diagnose: `somewhere logs --tail 10`, `somewhere errors`. 4. Test mail: `somewhere email test-inbox ` includes `verification_code`. Don't retest sign-in or `sw.db.from` scoping; test each table's scope, auth before `sw.db.server`/raw SQL, bad input and journeys. Routes: `index.html` loads `src/main.tsx`; unmatched extensionless paths (`/signin`) serve it. Route the app by `location.pathname`. `api/notes/[id].ts` is `/api/notes/:id`; `_`-prefixed names are import-only helpers. Avoid names differing only in case. With auth enabled, `api/auth/[...path].ts` is `export { somewhereAuth as default } from '@somewhere-cloud/sdk/server'`; pages use `createSomewhereAuth()` from `@somewhere-cloud/sdk/auth` (client and React hooks: `somewhere docs auth-client --section react-auth-state`). `auth.signUp({ email, password, displayName? })` / `auth.signIn({ email, password })` return the user or throw with the message. Gate on `auth.getState().status` (React: `useAuthState()`). Sign-up sets `email_verified: false`; unverified users pass `auth: 'required'`. `sw.auth.requireUser(req)` returns `{ id, email, role, email_verified, … }` or throws 401 `AUTH_REQUIRED`; `sw.auth.fromRequest(req)` returns it or `null`. Functions: JSON endpoints use `sw.endpoint({ auth, body, rateLimit, handler: async ({ body, user, params }, sw) => value })`; set `auth` (`'required'`, `'optional'`, `'none'`) or deploy refuses it. Webhooks and streaming use a bare `export default async function (req: Request, sw: SomewhereRuntimeContext)` returning a `Response`. Params: `params.id` there, `sw.params.id` bare. Data: `id()` is a random text key on new tables (reference with `text()`); integer-id tables keep integers. The starter's `id({ uuid: false })` is deliberate. Declare tables in `db/schema.ts`; pages use `somewhere:data` (`data.notes.list()`, `.create()`, `.update(id, …)`) without API files. Use `owner()` for personal rows, `group()` for invited teams, `appRole()` for app-wide roles, `anyOf()` for owner or a role, `allOf()` for members-only rows. Booking/help desk: `somewhere docs sw.db --section provider-or-booker-and-owner-or-staff-recipes`. Keep fitting scopes when an exceptional write needs `sw.db.server.tx`. `shared()` gives signed-in reads and creator-only writes. `client` sets browser columns; `publicRead: { where }` admits visitors. Public-profile enquiries use `client.intake` (`somewhere docs declared-data`). Keep scopes and grants; functions handle authorized exceptional writes and side effects. Declare the body schema (a missing or mistyped field is a 400); `handle` below is a public address its owner claimed: ```ts export default sw.endpoint({ auth: 'none', body: { handle: 'string', title: 'string', from_email: 'email' }, handler: async ({ body }, sw) => { const title = body.title.trim(); if (!title || title.length > 200 || /[\r\n]/.test(title)) return Response.json({ error: 'bad title' }, { status: 400 }); const { data: [profile] } = await sw.db.server.from('profiles', { where: { handle: body.handle }, limit: 1 }); if (!profile) return Response.json({ error: 'unknown handle' }, { status: 404 }); await sw.db.server.insert('entries', { user_id: profile.user_id, owner_email: profile.owner_email, title, from_email: body.from_email, created_ms: Date.now() }); }, }); ``` Use the looked-up owner, never the body. Rate limits/alerts: `recipe-signed-in-app`. Use `serverOnly()` only when every operation needs a function's own access check. Structured queries: `sw.db.from` / `insert` / `update` / `remove` return `{ data: rows[], count, changes }`; `where: { a: 1, b: { in: ids }, c: { gte: 2 }, d: null }` (one operator per column). Raw SQL uses a separate raw database, never managed tables. For cross-user managed work, authorize the caller and use `sw.db.server.from` / `insert` / `update` / `remove`; keep `owner()`/`group()`. Parallel reads: `Promise.all`. Unique pair: `unique: [['org_id','email']]` in table options. Test schedules now: `somewhere cron run --wait`. Do not wait for it to fire. ## More information - Anonymous quickstart: . If that URL cannot be fetched, `npx -y @somewhere-cloud/cli@latest docs start` prints the same text, and `docs({ topic: 'getting-started' })` covers the same first app. - Agent contract (the file project initialization writes): - Security practices: - Migration and portability: - Long-form reference: For current plans, prices and limits, see https://somewhere.cloud/pricing. If a documented contract appears wrong, call `support_ticket({ message })` with the smallest reproduction; read it back later with `support_ticket({ ticket_id })`.