> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stardeck.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Run Your App Locally

> Pull your app's cloud environment to your machine and run it with npm run dev — wired to the same data store, secrets, and storage your sandbox uses.

Connecting [Claude Code](/local-claude-code/connect) gives your editor tools that reach your platform data while you build. Running the app is the other half: your app also needs to reach those services — its data store, storage, payment keys, and secrets — to actually start on your machine.

Those values live on the platform, not in your repo. `stardeck env pull` fetches them for you and writes a local `.env.local`, so `npm run dev` boots a real, wired-up app on `localhost` — reading and writing the **same sandbox data** your cloud sandbox uses.

<Note>
  These two guides go hand in hand. **[Connect Claude Code](/local-claude-code/connect)** lets Claude reach platform services over MCP to help you *build*. **This page** lets your running app reach them over ordinary environment variables to *run*. Set up both and you have a full local loop: edit with Claude, run the result locally.
</Note>

## How it works

Both halves talk to the same platform, through different doors. Claude Code connects over MCP for its tools; your running app reads pulled env vars and calls the platform's SDKs and services directly.

```mermaid theme={null}
flowchart LR
    CC["💻 Local Claude Code"] -- "OAuth (MCP)" --> P["☁️ Stardeck platform"]
    APP["🖥️ npm run dev (localhost)"] -- "env vars → SDK calls" --> P
    P --> S["Data store · Storage · Secrets · Payments"]
```

`stardeck env pull` asks the platform to assemble your project's **sandbox** environment, rewrites the app's own URL to point at your local dev server, and returns the result. A few things worth knowing up front:

* **It's your sandbox environment.** You get the sandbox data store, secrets, and storage — the same ones the cloud sandbox uses. Writes you make locally land in that shared sandbox, not production.
* **Your own local identity.** The pull registers a per-developer *local deployment* for you, with its own secret that authenticates your app's calls back to the platform. It's separate from the sandbox and production deployments, and can be revoked without touching them.
* **Secrets land in `.env.local`.** The file holds real, decrypted values. It's written readable only by you and is already git-ignored — never commit it.

## Before you begin

You'll need:

* A **local checkout** with dependencies installed — follow [Connect Claude Code → Before you begin](/local-claude-code/connect#before-you-begin) and [Installing dependencies](/local-claude-code/connect#installing-dependencies) first.
* An **organization API key with an Admin role**. Pulling an environment returns decrypted secrets, so it requires an admin-scoped key. Create one under **Settings → API Keys** — see [Authentication](/api-reference/authentication).
* Your **project** — its ID or its slug (the slug is the readable name in your dashboard URL).

## Pull your environment

<Steps>
  <Step title="Set your credentials">
    Export the key and project once in your shell. Keep the key in an environment variable — never on the command line or in a file you might commit.

    ```bash theme={null}
    export STARDECK_CONTROL_PLANE_URL=https://www.stardeck.ai
    export STARDECK_API_KEY=sk-org-...          # your Admin org API key
    export STARDECK_PROJECT_ID=my-app           # project ID or slug
    ```

    Have more than one branch? Add `export STARDECK_BRANCH_ID=<id-or-name>`. With one branch you can skip it — the pull defaults to your **main** branch.
  </Step>

  <Step title="Pull the environment">
    From your app's root:

    ```bash theme={null}
    npm run env:pull
    ```

    This writes `.env.local` with your app pointed at `localhost`. Add `-- --verbose` to print the variable **names** it wrote (never the values).

    <Note>
      No `env:pull` script? It ships in newer app templates. In any repo you can run the CLI directly — it reads the same `STARDECK_*` variables:

      ```bash theme={null}
      npx @stardeckai/cli env pull --port 3333
      ```

      Pass `--port` to match your dev server's port so the app's own URL is correct.
    </Note>
  </Step>

  <Step title="Run the app">
    ```bash theme={null}
    npm run dev
    ```

    Your app boots on `localhost`, reading and writing your sandbox data store, using your sandbox secrets and storage. Open it in the browser and you're developing against the live platform.
  </Step>
</Steps>

## What gets pulled

The pulled `.env.local` is your sandbox environment with local overrides. Notably:

| Variable                             | Value                            | Why                                                         |
| ------------------------------------ | -------------------------------- | ----------------------------------------------------------- |
| `BASE_URL`, `NEXT_PUBLIC_BASE_URL`   | `http://localhost:<port>`        | Your app's own URL points at your dev server, not the cloud |
| `CONTROL_PLANE_URL`                  | The platform URL you pulled from | Where the SDKs send their calls                             |
| `DATABASE_URL`                       | Your **sandbox** data store      | The same data the cloud sandbox reads and writes            |
| `DEPLOYMENT_ID`, `DEPLOYMENT_SECRET` | Your local deployment's identity | Authenticates your app's calls back to the platform         |
| `NEXT_PUBLIC_ENVIRONMENT`            | `development`                    | Marks the app as running locally                            |

Storage, payments, data store, and any environment variables you've set for the sandbox come through as well, so features that depend on them work without extra setup.

<Warning>
  **`.env.local` contains decrypted secrets.** It's written readable only by you and is git-ignored, but treat it like a password file: don't commit it, don't paste it, and re-pull rather than copying it between machines. Anyone who obtains it can act as your app against your sandbox.
</Warning>

## What local dev does *not* do

Running locally covers everything your app *initiates* — page loads, data store queries, SDK calls, storage. It does **not** receive traffic the platform *sends to* your app.

<Warning>
  **Inbound platform traffic is not delivered to your machine.** Webhooks (payments, connected services), scheduled jobs, and cross-app calls are routed to your deployed sandbox or production URL — not to `localhost`. To exercise those end to end, use the [cloud sandbox](/sandbox-preview). Your local dev server won't see them.
</Warning>

You're also working against **shared sandbox data**. It's not a throwaway database — a teammate's sandbox, the in-product agent, and your local app all read and write the same store. Be deliberate with destructive changes, the same as you would in the cloud sandbox.

## Command reference

Every option can come from a flag or an environment variable; flags win when both are set.

| Flag                  | Environment variable         | Default      | Description                                     |
| --------------------- | ---------------------------- | ------------ | ----------------------------------------------- |
| `--control-plane-url` | `STARDECK_CONTROL_PLANE_URL` | —            | The platform URL to pull from                   |
| `--api-key`           | `STARDECK_API_KEY`           | —            | Admin org API key (`sk-org-…`)                  |
| `--project`           | `STARDECK_PROJECT_ID`        | —            | Project ID or slug                              |
| `--branch`            | `STARDECK_BRANCH_ID`         | main branch  | Branch ID or name                               |
| `--port`              | —                            | `3000`       | Local dev server port your app's URL should use |
| `--out`               | —                            | `.env.local` | Where to write the result                       |
| `--verbose`           | —                            | off          | Print the variable names written (not values)   |

The `npm run env:pull` script sets `--port` to your template's dev port for you; when running the CLI directly, pass `--port` yourself.

## Troubleshooting

### `Missing required configuration`

One of the control plane URL, API key, or project is unset. The CLI lists exactly which — set the flag or the `STARDECK_*` variable it names. (Branch is optional and won't appear here.)

### `403` — env pull requires an admin-scoped org API key

Your key's role doesn't grant admin access. Pulling an environment returns decrypted secrets, so it needs an **Admin** role. Create or pick an Admin key under **Settings → API Keys** — see [Authentication](/api-reference/authentication).

### `404` — Project not found / Branch not found

* The project ID or slug doesn't match a project **your key's organization owns**. Check the slug in your dashboard URL, and confirm the key belongs to the same org.
* For a branch, the name must exist on that project. Omit `--branch` to fall back to the main branch.

### The app starts but can't reach the data store or a service

Your `.env.local` may predate a change to the sandbox — for example a new environment variable or a rotated secret. Re-run `npm run env:pull` to refresh it, then restart `npm run dev`.

## Next steps

<CardGroup cols={2}>
  <Card title="Connect Claude Code" icon="plug" href="/local-claude-code/connect">
    The other half — give your local Claude Code tools that reach platform data
  </Card>

  <Card title="Tools & Permissions" icon="shield" href="/local-claude-code/tools">
    What Claude can do through the gateway, and how the role controls it
  </Card>

  <Card title="Cloud Sandbox" icon="cloud" href="/sandbox-preview">
    Test inbound traffic — webhooks, schedules, cross-app calls
  </Card>

  <Card title="Environment Variables" icon="gear" href="/environment-variables">
    Set the sandbox variables your app pulls
  </Card>
</CardGroup>
