@somewhere-tech/cli
v0.36.1
Published
CLI for somewhere.tech — auth, projects, deploy, pull, promote, db, logs, env, MCP bridge.
Maintainers
Readme
@somewhere-tech/cli
CLI for somewhere.tech. Like gh for GitHub, vercel for Vercel.
Install
npm install -g @somewhere-tech/cliOr run directly:
npx somewhere-cli deployFrom a project folder, that single command deploys anonymously when no account
is configured and prints the live URL, claim URL, and expiry. The scoped package
name works too: npx @somewhere-tech/cli deploy.
Quick start
somewhere login # OAuth in browser, stores API key
somewhere init # Create project, write .somewhere.json + .mcp.json
somewhere dev # Serve your app on localhost, compiled by the platform
somewhere deploy # Deploy current directory
somewhere logs # Stream logs
somewhere open # Open in browserThe CLI needs no MCP setup: every command works from the shell, and somewhere run <script> executes code against your live project. somewhere init also writes a .mcp.json so supporting hosts can additionally connect the same tools in context — optional, not required. Just start coding.
Commands
| Command | What it does |
|---|---|
| somewhere login | Authenticate via browser (Google OAuth) |
| somewhere auth login | Alias of somewhere login |
| somewhere logout | Clear stored credentials |
| somewhere whoami | Show current user, plan, project count |
| somewhere init | Create project + write .somewhere.json + .mcp.json |
| somewhere init --link | Link to an existing project |
| somewhere projects | List all projects with status |
| somewhere project create <name> | Create a new project |
| somewhere project view [name] | Show project details |
| somewhere project delete <name> | Delete with email confirmation |
| somewhere dev | Serve your app on localhost, compiled by the platform's own compiler; save a file and the page updates in milliseconds |
| somewhere preview | Run your app on the platform instead of your machine — every save goes to a private URL, and production is untouched until you promote |
| somewhere dev <cmd...> | Run your own command locally with the project's env vars injected |
| somewhere deploy | Deploy current directory to linked project |
| somewhere deploy --dry-run | Preview the deploy diff without shipping |
| somewhere deploy --scope functions | Deploy backend only (leave the site untouched) |
| somewhere deploy --force | Intentionally overwrite remote changes made since this machine last deployed |
| somewhere git connect [owner/repo] | Install/authorize the GitHub App if needed, deploy repository HEAD, then deploy every push |
| somewhere git status | Show connected repo, commit, deploy status, logs link, and live URL |
| somewhere git disconnect | Stop push-to-deploy; the currently deployed site stays live |
| somewhere pull | Download a project's live deployed source + scaffold tsconfig/package.json for local typechecking |
| somewhere typecheck | Loads the pulled tsconfig.json explicitly (equivalent to project-wide tsc --noEmit) — catches a dropped import (TS2304) with file:line; do not append source-file args, which bypass the project config |
| somewhere logs | Show recent logs |
| somewhere logs --follow | Stream logs in real-time |
| somewhere logs --level error | Filter by level |
| somewhere run <script.js> | Run a one-off script once against the project's live bindings (sw.db/sw.fs/sw.ai…) and print its return value + logs — no deploy |
| somewhere errors | Show the most recent exceptions (endpoint, status, error, time) — the curated error view |
| somewhere rollback | Revert production to the previous deployed version |
| somewhere env list | Show environment variables |
| somewhere env set KEY value | Set an env var |
| somewhere env delete KEY | Delete an env var |
| somewhere env pull | Write a local .env listing the keys the project expects (values blank — secrets never leave the platform) |
| somewhere status | Show project + workspace status |
| somewhere open | Open project URL in browser |
| somewhere open --dashboard | Open the dashboard |
| somewhere api GET /v1/projects | Raw API call with auto-auth |
| somewhere advisor "<question>" | Ask the platform advisor anonymously; login adds linked-project context (--json for automation) |
| somewhere docs [topic] | Read public text docs or an MCP manual topic such as sw.db (--json supported) |
| somewhere catalog | Browse the live platform tool catalog (--json for the raw catalog) |
| somewhere mcp | Run MCP server over stdio (proxies to mcp.somewhere.tech) |
| somewhere mcp install <host> | Configure an MCP host (codex, claude-code, cursor) |
| somewhere mcp doctor | Check MCP setup: login, token, server reachability, host configs |
Short alias: sw works everywhere somewhere does.
Auth flow
somewhere login opens your browser, you sign in with Google, the platform redirects back to a local server with your API key. The key is stored in ~/.somewhere/config.json (mode 600).
The CLI configures every MCP host (Claude Code, Cursor, Codex) to use the stdio bridge (somewhere mcp), not a baked-in token. The bridge re-reads ~/.somewhere/config.json on every launch, so a later somewhere login (which rotates your key) never leaves a stale token behind — no manual config editing, ever. If your stored key is a refreshable cli-pair key, the CLI also swaps in a fresh access key automatically on expiry, so a long-running agent session never logs itself out.
Init flow
somewhere init creates a project on the platform and writes two files:
.somewhere.json— project ID, name, subdomain. The CLI reads this to know which project you're working on..mcp.json— optional MCP server config pointing at thesomewhere mcpstdio bridge. Supporting hosts connect the same tools in context using your live login; the CLI itself never needs it. No token baked into the file, no manual config.
After init, claude "build me a booking app" works immediately.
Deploy
somewhere deploy reads all files in the current directory (skipping node_modules, .git, .env, etc.), sends them to the platform, and they're live at {subdomain}.somewhere.tech. Deploy raw source — the platform compiles JSX/TSX, resolves npm imports, and bundles for you. Don't run a build step first.
Files under functions/ (and root-level api/ and _lib/) are deployed as server-side functions.
Files under public/ deploy at the site root, matching Vite's convention: public/images/logo.png serves as /images/logo.png.
To exclude local-only files from deploy, add gitignore-style patterns to .somewhereignore in the project root. The CLI also respects the root .gitignore. .somewhereignore is applied after .gitignore, so it can add deploy-only excludes or ! re-includes. Built-in safety excludes such as node_modules, .git, .env, dist, and dotfiles still apply.
After each successful linked deploy or pull, the CLI records the current deployed version in .somewhere.json. If the project changed elsewhere since that version, the next deploy refuses before overwriting anything and names the changed files. Run somewhere pull to bring remote source back locally, or somewhere deploy --force --yes to overwrite intentionally.
GitHub push-to-deploy
somewhere git connect owner/repoThe CLI uses the GitHub App, not a pasted personal access token. It opens GitHub only when the account or repository still needs authorization, resumes automatically, deploys the repository's default-branch HEAD immediately, and waits for that exact commit before printing its status, logs link, and live URL. Later pushes to the connected branch deploy automatically.
Use --project <id-or-slug> outside a linked directory, --branch <name> for
a non-default branch, and --root <directory> for a monorepo app. connect,
status, and disconnect support --json. Disconnecting stops future GitHub
deploys but does not undeploy the current site.
Deploy options
| Flag | What it does |
|---|---|
| --scope functions | Deploy only the backend functions; leave the site untouched |
| --scope static | Deploy only the site; leave functions untouched |
| --dry-run | Show what would change (added / modified / removed) without deploying |
| --replace-functions | Drop deployed functions not present locally. A full deploy already does this and names each removed function; use it with --scope functions, which otherwise keeps them |
| --project <id> | Deploy to a specific project instead of the linked one |
| --force | Overwrite remote changes even when this machine has an older deployed version |
| --yes | Skip the --force confirmation prompt |
After a successful deploy the CLI prints a build log — the entry chunk, each compiled chunk with its size, each function with its size, and any compiler warnings.
somewhere deploy --dry-run # preview the diff first
somewhere deploy --scope functions # ship a backend fix without touching the site
somewhere deploy --force --yes # overwrite remote edits intentionallyDevelopment: somewhere dev
somewhere dev serves your app on localhost and compiles it with the
platform's own compiler — the same one that compiles your deploy — so what
renders locally is what deploy produces, not a lookalike built by a second
toolchain. Save a file and the page updates in milliseconds.
somewhere dev # serve on http://localhost:8787
somewhere dev --port 3000 # pick the port
somewhere dev --open # open the browser once it is servingThere is no dev version of your app. From the first file you are building the
production app against real data: api/ functions run in local Node, and
sw.db, sw.fs, sw.ai and sw.auth inside them call your real project.
Same app, same data, same build. Functions run on your machine's Node during
the loop rather than on the platform's runtime, so a deploy is still what
proves a function in production.
Nothing to install and nothing to build first. Your app's dependencies resolve
from the project's node_modules when it exists, and otherwise from a cache
the CLI manages for you. A compile error prints the file and line in the
terminal and shows on the page, with the last working page still underneath; a
function that throws returns its stack trace.
Environment variables come from a .env in the project directory. Run
somewhere env pull to write the list of keys the project expects (values stay
on the platform), then fill in the ones you want locally. somewhere dev
names any key the project expects that has no local value.
somewhere preview
There are two loops, and they are named after where the app runs.
somewhere dev runs it on your machine. somewhere preview runs it on the
platform.
somewhere preview sends every save to a private URL, reachable only by you
until you share the link. The build is the one production would get. The
database starts as a separate copy of your production data, rows included,
taken when the preview was created, so you test against real-shaped data and
nothing you try in a preview can change production rows. Because that copy is
real data, the link is what grants access to it; treat sharing one as sharing
that copy. After each update the
command prints that URL and the somewhere promote command that makes those
exact bytes live. Reach for it when you want a URL to send someone, or when the
agent doing the work reaches the platform over MCP and has no local machine to
serve from.
Nothing your users see changes while you preview. Production keeps serving what you last promoted.
The URL is single-use and short-lived by design: opening it exchanges it for a private session in that browser, and saving a file replaces it with a new one. Use the newest URL the command printed. Anyone without a live URL — signed out, or signed in as someone else — gets a 404.
A preview is built against your live version, so a project that has never been
published has nothing for the first one to build on. On such a project
somewhere preview asks before publishing once (--publish-first gives that
consent up front in a script), and every preview after that stays private to you
and never changes what is live.
somewhere preview is included on the Builder, Pro and Scale plans. somewhere
dev runs the same app on your machine on every plan, and deploying is
unaffected on every plan.
somewhere dev --cloud still starts the same loop and points you at the new
name. somewhere dev --local is accepted and does what bare somewhere dev
does.
Running your own command
somewhere dev <cmd...> runs a command of your choosing with the project's
environment variables injected — for example somewhere dev npm run dev.
Client-side code: use the SDK
The CLI deploys and manages projects. For client-side code (browser / Node app talking to your backend), install the SDK — a familiar { data, error } client:
npm i @somewhere-tech/sdkimport { createClient } from '@somewhere-tech/sdk';
const db = createClient(URL, KEY);
const { data, error } = await db.from('todos').select('*');Inside deployed functions you use the sw runtime directly (sw.db.query(...), sw.auth, sw.email, …) — no SDK needed there.
What the CLI does NOT do
- No hosting or running production code (the platform does that)
- No build step before deploy — deploy raw source; the platform compiles it.
somewhere devcompiles locally to serve the loop, using the platform's own compiler, and never asks you to run a build - No application AI calls (the
advisorcommand only exposes the platform-help expert) - No workspace management (dashboard)
- No billing (dashboard)
Requirements
Node.js >= 18
License
MIT © somewhere.tech
