Browse all docs

Anvil Cloud / Runtime

Local runtime

Anvil Local runs a built Cell without a cloud provider.

It uses the same handleRuntimeRequest boundary as deployment adapters, then provides local implementations for database, files, env, auth, logs, events, jobs, workflows, and supervised services.

The runtime binds to 127.0.0.1 by default. Use --host <address> only when a native device or another machine must connect. Lens and the /_anvil/* management actions are development controls, so do not expose that port to an untrusted network.

What starts with anvil cloud dev

anvil cloud dev runs a build first. If the build passes, it imports the server bundle, loads the manifest, and starts:

  • local runtime HTTP server
  • local client asset server
  • local agent runtime with the deterministic stub provider registered by default
  • JSON database adapter
  • local file adapter
  • local environment adapter
  • local auth adapter
  • local log adapter
  • local event adapter
  • local job adapter
  • local workflow adapter
  • local service supervisor

When capabilities.outboundFetch.allow is declared, local request handlers and workflow steps run with the same outbound host guard as AWS preview. Calls to undeclared hosts fail with OUTBOUND_FETCH_NOT_ALLOWED.

Default ports:

Surface Default
Runtime 8787
Client 5173

Options:

anvil cloud dev --port 8787 --client-port 5173
anvil cloud dev --json
anvil cloud dev --agent --json

Local routes

The local runtime exposes:

POST /_anvil/query/:name
POST /_anvil/mutation/:name
ANY  /api/*
GET  /_anvil/health
GET  /_anvil/manifest
GET  /_anvil/inspect
GET  /_anvil/lens
GET  /_anvil/agents
POST /_anvil/agents/:name
GET  /_anvil/approvals
GET  /_anvil/approvals/audit
POST /_anvil/approvals/:id/approve
POST /_anvil/approvals/:id/reject
GET  /_anvil/traces
GET  /_anvil/traces/:traceId
POST /_anvil/agents/:name/sessions
POST /_anvil/agents/sessions/:sessionId/messages
GET  /_anvil/agents/sessions/:sessionId/stream?after=:token
POST /_anvil/channels/simulate
POST /_anvil/workflows/run/:name
GET  /_anvil/workflows
GET  /_anvil/workflows/:runId
GET  /_anvil/schedules
POST /_anvil/schedules/:name/run
GET  /_anvil/services
POST /_anvil/services/:name/start
POST /_anvil/services/:name/stop

Endpoint requests under /api/* are translated into endpoint runtime requests and matched against declared Cell endpoints.

Agent requests under /_anvil/agents/:name invoke mounted Cell Agents through the same provider-neutral AgentRuntime used by tests and provider mode. The local stub inference provider is registered automatically for provider: "local".

Approval-gated tool execution records pending requests in local state and returns a pending approval id instead of executing the gated action. Use /_anvil/approvals, Lens, or anvil-cloud approvals ... --json to inspect, approve, reject, and audit those requests.

Session routes add resumable event history around mounted agents. Create a session, send messages to it, then reconnect to the SSE stream with the last continuation token to replay missed events.

Channel simulation routes normalize local Slack/GitHub/Discord-style inbound messages and map them to mounted agent sessions. They are for local development and tests; real provider credentials and webhook verification stay outside Cell code.

Local state

Local state lives in .anvil/local by default:

.anvil/local/
  auth.json
  approvals.json
  agent-sessions.json
  dev.db
  events.json
  files/
  jobs.json
  logs.ndjson
  schedules.json
  services.json
  traces.json
  workflows.json

The current database adapter stores JSON records in dev.db. It is intentionally simple, inspectable, and suited to alpha local development.

Local database branches snapshot that JSON store for previews, tests, and agent experiments. main maps to .anvil/local/dev.db; named branches live under .anvil/local/db-branches with metadata in .anvil/local/db-branches.json. Cell code still sees the same ctx.db contract regardless of the selected branch.

Scheduled jobs declared with job({ schedule }) are tracked in schedules.json. Local scheduling supports rate(1 hour), @every 5m, and five-field cron expressions. Missed runs while the dev runtime is stopped are skipped rather than replayed. Use Lens or anvil-cloud schedules list|run --json to inspect and manually trigger schedules.

Database behavior

ctx.db.<table> supports table operations through the local JSON adapter:

  • all
  • get
  • insert
  • update
  • delete
  • where(...).all
  • where(...).first
  • where(...).count

Inspection commands:

anvil cloud db list --local --json
anvil cloud db dump notes --local --json
anvil cloud db branch preview --from main --ttl 3600 --json
anvil cloud db use preview --json
anvil cloud dev --db-branch preview --json
anvil cloud db diff preview --against main --json
anvil cloud db promote preview --json
anvil cloud db delete preview --yes --json
anvil cloud db cleanup --expired --json

Files

ctx.files stores local file data under .anvil/local/files.

Supported operations:

  • get
  • put
  • delete

Deployment adapters map the same capability to their own backing store.

Auth

Local auth state is stored in .anvil/local/auth.json.

Handlers can use ctx.auth.requireUser() to require a current local user. Local auth is a development emulator; production auth belongs behind configured OIDC providers.

Logs

Local logs are NDJSON in .anvil/local/logs.ndjson.

Read them with:

anvil cloud logs --local --json

Runtime errors include request id, handler kind, handler name, message, and error metadata.

Workflows

Local workflows persist state to .anvil/local/workflows.json. The runtime records each step transition so a running workflow can resume when the local server starts again.

Useful commands:

anvil cloud workflows list --json
anvil cloud workflows show <runId> --json
anvil cloud workflows run <name> --input '{"example":true}' --json

Services

Local services run under the runtime service supervisor. Service state snapshots are written to .anvil/local/services.json.

anvil cloud services list --json

For live state while the dev server is running, use the local Lens UI or GET /_anvil/services.

Inspection

Use:

anvil cloud inspect --local --json

The local inspection payload includes:

  • build status
  • manifest
  • current auth user
  • table row counts
  • recent runtime errors
  • declared workflows and recent run state
  • service state when recorded

The value of local runtime is not that it perfectly mimics a provider. The value is that the app contract can be executed and inspected before adapter behavior enters the conversation.