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

# Walkthrough: ship with Claude

> From an empty directory to a deployed Flynet app on Vercel — built with Claude Code, with your credentials handled safely the whole way.

# Walkthrough: ship with Claude

This is the full path: wire Claude Code into Flynet, have it build a Next.js app on the SDK, handle your credentials without ever exposing them to the agent or the browser, and deploy to Vercel. About 30 minutes end to end.

**You'll need:** Node 18+, [Claude Code](https://code.claude.com), a [Vercel account](https://vercel.com) with the CLI (`npm i -g vercel`), and Flynet credentials from [request access](/resources/request-access) — an API key for Discovery, OAuth client credentials for member features.

## 1. Wire Claude into Flynet

Three commands, run inside your project directory, give Claude everything it needs:

```bash theme={null}
mkdir my-flynet-app && cd my-flynet-app

# The agent skill + Cursor rules — teaches Claude the auth model and SDK surface
npx -y @flynetdev/skills

# The Docs MCP — Claude reads these docs live while it writes
claude mcp add --transport http flynet-docs https://docs.flynet.org/mcp

# The API MCP — Claude calls Flynet directly to check its own work
claude mcp add flynet --env FLYNET_API_KEY=bb_... -- npx -y @flynetdev/mcp
```

The API MCP line is the one place a credential goes into a command — it lands in Claude Code's local MCP config on your machine, not in any conversation.

## 2. Scaffold and build

Start Claude Code and hand it the job:

```bash theme={null}
npx create-next-app@latest . --typescript --app
claude
```

A prompt that works well:

> Build a restaurant discovery page using @flynetdev/core and @flynetdev/react. Fetch restaurants server-side with FlynetDiscoveryClient and render them with RestaurantList. Follow the Flynet skill's rules. The API key is in the API\_KEY environment variable — never read or print its value.

With the skill installed, Claude already knows the two-credential model, that Discovery calls stay server-side, and which components exist. With the Docs MCP connected it pulls exact field names from these docs instead of guessing; with the API MCP it can call `list_restaurants` itself to confirm the shape of real data before writing code against it.

## 3. Handle secrets — the part to get right

The rule that makes agent-assisted development safe: **the agent works with the names of your secrets, never the values.**

**Put values in `.env.local` yourself** — type them in your editor, not into the chat:

```bash .env.local theme={null}
API_KEY=bb_...
CLIENT_ID=...
CLIENT_SECRET=...
REDIRECT_URI=https://your-subdomain.ngrok-free.app/callback
```

<Note>
  The OAuth `redirect_uri` must be a public, allowlisted URL — `localhost`
  won't be registered. Run `ngrok http 3000` and register that exact URL as
  your redirect URI (use a reserved ngrok domain so it's stable). Full detail
  in [OAuth → Environment](/concepts/oauth#environment). The API-key-only
  steps above work on plain `localhost`; only the OAuth step needs the tunnel.
</Note>

`create-next-app` gitignores `.env.local` by default — verify `.env*.local` is in your `.gitignore`. Then commit an `.env.example` with names only, so the repo documents what's needed without containing anything:

```bash .env.example theme={null}
API_KEY=
CLIENT_ID=
CLIENT_SECRET=
REDIRECT_URI=
```

**Block the agent from reading env files.** Claude Code respects deny rules in `.claude/settings.json` — add one so the agent can't open the file even by accident:

```json .claude/settings.json theme={null}
{
  "permissions": {
    "deny": ["Read(/.env*)"]
  }
}
```

This covers Claude's file tools and the file commands it runs in Bash (`cat`, `head`, `tail`, `sed`). It doesn't stop a custom script the agent writes from opening the file itself — the names-not-values habit above is the real protection; the deny rule is the guardrail.

**Keep secrets out of the browser.** In Next.js, only variables prefixed `NEXT_PUBLIC_` reach the client bundle — so never put that prefix on `API_KEY` or `CLIENT_SECRET`. Server code (route handlers, Server Components) reads them from `process.env`; if generated code ever references the API key in a client component, that's the bug to flag.

<Warning>
  Never paste a credential into a chat with any AI agent. Conversations can be logged, summarized, or fed back as context. The agent doesn't need values to build — it needs to know `process.env.API_KEY` exists.
</Warning>

## 4. Verify locally

```bash theme={null}
npm run dev
```

Restaurants should render at `localhost:3000`. A useful habit: ask Claude to verify its own work — *"call list\_restaurants through the Flynet MCP and confirm the fields you rendered exist on the real response."* That closes the loop against live staging data instead of assumptions.

## 5. Deploy on Vercel

Link the project, then set the same variables in Vercel — values go into the CLI prompt or the dashboard, never the chat:

```bash theme={null}
vercel link

# Prompts for the value interactively — paste it there
vercel env add API_KEY production
vercel env add CLIENT_ID production
vercel env add CLIENT_SECRET production
vercel env add REDIRECT_URI production   # your deployed callback URL, e.g. https://my-app.vercel.app/callback

vercel --prod
```

Scope variables to the environments that need them (`production`, `preview`, `development`) — a preview deployment doesn't need production credentials. To sync your local file from Vercel later, `vercel env pull .env.local` (note it overwrites the file).

Update your app's redirect URI in your Flynet developer app to the deployed callback URL, and the OAuth flow works on the live site.

<Note>
  The SDK defaults to staging, so your deployed app talks to the Flynet staging API. To go live on production, point the clients at the production host — `serverURL: "https://api.blackbird.xyz/flynet/v1"` and `authBaseUrl: "https://api.blackbird.xyz/oauth"` — using the separate production credentials Blackbird issues on approval.
</Note>

## What you shipped

A deployed Next.js app on the Flynet SDK — built by an agent that read the live docs, called the real API to check its work, and never saw a single credential value.

<CardGroup cols={2}>
  <Card title="Member dining app recipe →" icon="utensils" href="/recipes/mains/member-dining-app">
    Add OAuth and member components to what you just built.
  </Card>

  <Card title="How it fits together →" icon="diagram-project" href="/build-with-ai/architecture" />
</CardGroup>
