Documentation
Everything you need to deploy your first app in under two minutes.
Quickstart
Three commands to go from a local project to a live, gated URL.
npm install -g @getworkshop/cli
workshop login # opens browser, sign in with Google, Microsoft, or GitHub
cd my-project
workshop deploy # auto-detects runtime, deploys in ~30sThat's it. Your app is live at your-project.getworkshop.io, gated to your company accounts.
Installation
Install the CLI globally via npm, pnpm, or Bun:
npm install -g @getworkshop/clipnpm add -g @getworkshop/clibunx --bun add -g @getworkshop/cliRequires Node.js 18+. Verify the install:
workshop --versionCLI commands
workshop loginAuthenticate with your Workshop account. Opens a browser window and completes an OAuth flow. Your API key is stored in ~/.workshop/config.json.
--key <key>Skip the browser flow and provide a key directly.workshop deployBuild and deploy the current directory. Reads workshop.config.json if present, otherwise run workshop init first.
-n, --name <name>Override the app name.-a, --access <mode>Access mode: public | link | company | private.--allow <emails>Comma-separated allowlist emails (for private/company).-w, --workspace <slug>Target a specific workspace.-y, --yesSkip prompts (scriptable / CI).workshop initCreate a workshop.config.json in the current directory. Walks you through name, runtime, and access mode interactively.
workshop lsList all your deployed apps with their status and URLs.
--jsonOutput as JSON.workshop open [name]Open an app URL in your browser. If name is omitted and there is only one app, opens that one.
workshop logs [app]Show recent scheduled-run history (status, time, duration, errors) for an app. With no [app], uses the app in the current folder's workshop.config.json.
-n, --limit <count>Number of runs to show (max 200, default 50).workshop delete <name>Permanently delete an app and all its deployments. Requires confirmation.
--yesSkip the confirmation prompt.workshop.config.json
Place a workshop.config.json at the root of your project to set defaults. All fields are optional — if absent, the CLI prompts.
{
"name": "my-dashboard",
"runtime": "nextjs",
"access": "company",
"env": {
"OPENAI_API_KEY": "sk-..."
},
"cron": [
{
"schedule": "0 9 * * 1-5",
"command": "node scripts/daily-report.js"
}
]
}namestringThe subdomain your app deploys to. Must be lowercase letters, numbers, and hyphens. Example: "my-dashboard" → my-dashboard.getworkshop.io
runtime"static" | "nextjs" | "python" | "node"The runtime to use. Workshop auto-detects based on package.json or requirements.txt if omitted.
access"company" | "link" | "public"Access control mode. "company" requires a @yourcompany.com Google login. "link" allows anyone with the URL. "public" is open to the world.
envobjectKey-value pairs injected as environment variables at runtime. Values are encrypted at rest.
cronarrayScheduled tasks. Each entry needs a schedule (cron expression) and a command to run.
Access modes
Company (default)
Visitors must sign in (Google, Microsoft, or GitHub) with an email that matches your company domain. Workshop infers your domain from the email you used to sign up. No invite list, no passwords — any @yourcompany.com account gets in automatically. Add specific people outside your company from the app's Access panel.
Private
Only people on an explicit allowlist can open the app — works with any sign-in (including personal email). Leave the allowlist empty for just you. Edit it anytime from the app's Access panel; changes apply without a redeploy.
Link
Anyone with the URL can access the app. Useful for external demos or contractors. The URL is unguessable but not secret — treat it as a shared password.
Public
The app is open to the world. No authentication required. Workshop will not block search engine crawlers in this mode.
Cron jobs
Add a cron array to your config to run commands on a schedule. Schedules use standard 5-field cron syntax (UTC).
"cron": [
{ "schedule": "0 9 * * 1-5", "command": "node scripts/report.js" },
{ "schedule": "*/30 * * * *", "command": "python sync.py" }
]If a cron run fails, Workshop sends a failure notification to your account email (and to the address in your settings, if set). Free plans include 100 cron runs/month. Solo plans include 10,000.
Data store
Every company- or private-gated app gets a built-in key/value store — no database to set up. It's served from your app's own origin at /__workshop/kv and gated by the same sign-in as the app, so only your viewers can read or write. State is shared across everyone who can see the app.
// Save and load shared state straight from your app's frontend —
// the viewer's session authorizes the call automatically.
await fetch("/__workshop/kv/todos", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify([{ text: "Ship it", done: false }]),
});
const res = await fetch("/__workshop/kv/todos");
const todos = res.ok ? await res.json() : [];
// List keys (optionally by prefix), or delete one:
const { keys } = await (await fetch("/__workshop/kv?prefix=todo")).json();
await fetch("/__workshop/kv/todos", { method: "DELETE" });Values are capped at 256 KB each. It's built for lightweight shared state — settings, small lists, submissions, counters. For larger or relational data, connect your own database with a Workshop secret. The store is only available on company and private apps, since those tie every write to a signed-in viewer; link and publicapps can't use it.
Deploy from Claude / ChatGPT
Workshop speaks MCP, so you can deploy and manage apps just by asking your AI assistant. There are two ways to connect, depending on where you work.
1. On the web (ChatGPT, Claude.ai)
Add this hosted connector and approve the one-time sign-in. It deploys from a connected GitHub repo:
https://app.getworkshop.io/api/mcp2. In your editor (Claude Code, Claude Desktop, Cursor)
The CLI ships a local MCP server that deploys the project you're working in — files included, so it can build front-end apps locally and ship any folder. Log in once, then add the connector:
# Claude Code
claude mcp add workshop -- npx -y @getworkshop/cli mcp
# Claude Desktop / Cursor (mcp config)
{ "mcpServers": { "workshop": { "command": "npx", "args": ["-y", "@getworkshop/cli", "mcp"] } } }Once connected, you can say things like:
- · “Deploy my
acme/inventoryrepo to my team.” - · “What apps do I have and are they up?”
- · “Make the dashboard app private to just me and Sam.”
- · “Show the last runs of my nightly job.”
The hosted (web) path deploys Python/Node server apps and static sites from a repo; front-end apps that need a build step (Vite, Next.js export) deploy via the editor path or the CLI, which build locally. For private repos, install the Workshop GitHub App from Settings → Connections and pick exactly which repos to share (read-only, revocable); public repos work right away. New apps default to private access — you choose who can see them.
Environment variables
You can inject environment variables in two ways:
1. In workshop.config.json
{
"env": {
"DATABASE_URL": "postgres://...",
"API_KEY": "sk-..."
}
}2. Via the CLI flag
workshop deploy --env DATABASE_URL=postgres://... --env API_KEY=sk-...Environment variables are encrypted at rest and injected at runtime. They are never exposed in build logs or the Workshop dashboard.
Something missing?
These docs are a work in progress. If you can't find what you need, just ask.
Contact support →