Part of Host AI-built appsHost AI-built apps · Guide

From Claude Code or Cursor to a deployed app.

Claude Code and Cursor leave you with an app that runs on your laptop: a dev server, a local .env, often a SQLite file, sometimes no lockfile. To deploy it, commit the lockfile, move secrets into environment variables, make the server read PORT and give it a real database. Then run canner deploy or let the agent deploy over MCP.

Facts checked

What the agent leaves you with

An agent optimises for “it works when I run it here”. That is the right goal while you build, and it leaves the same handful of things behind almost every time:

  • A dev command, not a start command. npm run dev, next dev or vite on localhost:3000 or 5173.
  • Secrets in a local file. .env or .env.local with real keys. Sometimes an .env.example listing what the app expects, sometimes nothing.
  • A local database. A dev.db SQLite file, or a DATABASE_URL pointing at Postgres on your machine.
  • A lockfile that is missing or stale. The agent edited package.json and never re-ran the install, or the lockfile was never written.
  • A port or URL typed in. app.listen(3000), or http://localhost:3000 as the API base in the frontend.
  • An adapter for someone else’s platform. Ask for “a SvelteKit app” after reading a Vercel tutorial and you may get @sveltejs/adapter-vercel.

The gaps to close, and what the build log says

Until a project’s first successful deploy, Canner reads the upload before building and writes a warning for each of these into the build log, prefixed [canner] ⚠. The middle column is that text, or the error the build stops on. Fix them before the first deploy and you skip a round trip.

GapWhat the build log saysFix
No lockfile[canner] no lockfile found — installing with … The build continues, but dependencies aren’t pinned.Run npm install (or pnpm, yarn, bun) and keep the lockfile it writes.
Stale lockfilenpm’s own error: npm ci can only install packages when your package.json and package-lock.json … are in syncRun the install again locally and deploy the updated lockfile.
Variables in .env.example not setEnv vars RESEND_API_KEY are listed in .env.example but not set — add them in the project's Environment variables.canner env set KEY=value --sensitive, or paste your .env into the bulk editor on the Env Vars tab.
Supabase keys missing at buildsupabaseUrl is required.Set VITE_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_URL and the anon key before you build: browser variables are baked in at build time.
Hard-coded portapp did not respond on / within 30sListen on process.env.PORT. Canner sets it.
ORM but no databaseUses Prisma but the project has no database yet — create one on the project's Database page so DATABASE_URL is set at build and runtime.canner db init. DATABASE_URL is injected for the build and the running app.
Vendor adapter@sveltejs/adapter-vercel only runs on that vendor's platform — switch to the Node adapter for your framework.Use @sveltejs/adapter-node (or your framework’s Node adapter).

Deploy with the CLI

The CLI is the shortest path, and Claude Code or Cursor can run it in their own terminal. No Git repository is needed: canner deploy packs the folder and sends it to the same build pipeline a push uses.

npm install -g @canner-ca/cli     # Node 20 or later
canner login                      # paste a cnr_ token from Identity → API keys
canner init                       # creates the project, writes canner.json
canner db init                    # only if the app uses Postgres
canner env set OPENAI_API_KEY=sk-... --sensitive
canner deploy --follow            # uploads, builds, streams the log

Keep your .env out of the upload

canner deploy always leaves out node_modules, .git, .next, .nuxt, .turbo, .vercel and .svelte-kit. It does not read .gitignore, so a local .env goes up with everything else unless you exclude it. Add a .cannerignore next to package.json:

Set the real values as environment variables instead. --follow exits with 0 when the app is live and 1 when the build fails, so an agent running the command sees the failure and can read the log. The compressed upload is capped at 100 MB on Starter and 500 MB on Live.

# .cannerignore  (canner deploy does not read .gitignore)
.env
.env.*
*.sqlite
coverage/

Or let the agent deploy through MCP

The Canner MCP server gives the agent tools instead of shell commands: canner_create_project, then canner_save_app with the files, then canner_get_deployment to read the build log. Deleting projects, databases, domains or tokens is not exposed, so an agent can’t do it by mistake.

  • Prompt: “Create a Canner project for this app, save it with the Canner tools, set the environment variables from .env.example, and give me the live URL. If the build fails, read the log and fix it.”
  • CLI or MCP? canner_save_app needs the complete contents of every file sent through the conversation, up to 2,000 files. That is fine for a small app and slow for a large one. For anything big, have the agent run the CLI.
  • Tokens: if you already ran canner login, the local server reads that token and you can leave out CANNER_TOKEN. For a token pasted into a third-party tool, use the “MCP connector (deploy only)” type.
ClientHow to add Canner
Any agent with a terminalNo MCP needed: the agent runs canner deploy --follow itself.
Claude Code, local server †claude mcp add --env CANNER_TOKEN=cnr_… --transport stdio canner -- npx -y @canner-ca/mcp
Claude Code, remote server †claude mcp add --transport http canner https://api.canner.ca/mcp --header "Authorization: Bearer cnr_…"
Cursor †Add the canner entry from the MCP docs to .cursor/mcp.json (this project) or ~/.cursor/mcp.json (every project).

† Competitor details come from each vendor’s own published pages on the dates shown; prices and plans change, so check the vendor before you decide. Claude Code, local server (2026-10-29) · Claude Code, remote server (2026-10-29) · Cursor (2026-10-29)

After the first deploy

  • Logs: canner logs --follow streams the running app’s output. The agent can do the same with the MCP tools for errors and logs.
  • Migrations: put npx prisma migrate deploy (or your tool’s equivalent) in the release command under Settings → Build, not in the build command.
  • Sleep: Starter apps sleep after 3 hours without a request and wake on the next one. Live keeps 2 projects always on and adds custom domains.
  • Everything else for AI-built apps is on the Host AI-built apps page.

Questions

Can Claude Code deploy my app by itself?

Yes. It can run canner deploy --follow in its terminal and read the build log, or call the Canner MCP tools to create a project and save the app. Destructive actions such as deleting a project are not available to it.

Does canner deploy upload my .env file?

Yes, unless you exclude it. It skips node_modules, .git and build folders, but it does not read .gitignore. Add .env and .env.* to a .cannerignore and set the values as environment variables.

Do I need GitHub to deploy?

No. canner deploy and the MCP canner_save_app tool both upload files directly. Connect GitHub later if you want a deploy on every push and preview URLs for pull requests.

Why does the build fail with “supabaseUrl is required”?

The Supabase client is created during the build and the URL is empty. Browser variables such as VITE_* and NEXT_PUBLIC_* are baked in at build time, so set them on the project and deploy again.

Deploy what your agent built.

Starter is free and needs no card. Run canner deploy once and you have an HTTPS URL in Montréal.