← Back to dashboard
vercelhostingfresh

Vercel + Claude Code Integration Guide

Where does my code run?

The real model

Static → ISR → Edge-SSR → Node-SSR, with Suspense/streaming layered on either SSR.

App-router rendering is decided per-segment by what you `await` and which dynamic APIs you touch (`cookies()`, `headers()`, `searchParams`). Reach for the Edge runtime when you need geographically-fast SSR with no Node APIs (small bundle, V8 isolates, no fs/native modules). Drop to Node runtime when you need Node-only libs, AWS SDKs, heavy CPU, or long timeouts. ISR is the sweet spot for content that's mostly read but occasionally written — use `revalidateTag()` over hard TTLs once your data model fits. Streaming + RSC lets the page shell paint at Edge-SSR speed while slow data resolves underneath, which often makes “but I need personalisation” not actually require Node-SSR.

Five rendering strategies

Same Next.js project can mix all five — one per route. Tap a card for the trade-offs.

Pick a strategy by asking four questions

Flip the toggles for one route at a time. The recommendation underneath updates to whichever strategy fits the smallest set of guarantees you actually need — overshooting costs TTFB and money.

Rendering-strategy chooserrecommendation: Static
StaticTTFB ~30 ms · 100% edge

Generated at build time; served globally from CDN.

Why this one: SEO-critical, content rarely changes → pre-render once, serve from every edge.

Heuristics, not laws. Real apps mix strategies per route — your marketing pages can be Static while your dashboard is Edge-SSR, all in the same Next.js project. The chooser exists to break the “just SSR everything” reflex.

The most common mistake: defaulting to Node-SSR when a route only needs cookies + a fast database call. Edge-SSR or Streaming usually covers it at 1/3 the latency.

Text
██╗   ██╗███████╗██████╗  ██████╗███████╗██╗
██║   ██║██╔════╝██╔══██╗██╔════╝██╔════╝██║
██║   ██║█████╗  ██████╔╝██║     █████╗  ██║
╚██╗ ██╔╝██╔══╝  ██╔══██╗██║     ██╔══╝  ██║
 ╚████╔╝ ███████╗██║  ██║╚██████╗███████╗███████╗
  ╚═══╝  ╚══════╝╚═╝  ╚═╝ ╚═════╝╚══════╝╚══════╝

Vercel + Claude Code Integration Guide

Focus: Deploying, inspecting, and automating Vercel projects from inside Claude Code using the official Vercel MCP server and Vercel CLI.

Overview

Vercel is a cloud platform for frontend and serverless deployment. Its official MCP server gives Claude Code direct access to deployments, logs, environment variables, domains, and projects — no browser required. Combined with the vercel CLI and GitHub Actions, you can build fully automated deploy, preview, and rollback pipelines driven by Claude Code.

Here is the core flow at a glance — a single git push fans out into builds, previews, and a production deploy on the edge:

Official Documentation


MCP Server Setup

Vercel hosts an official MCP server at https://mcp.vercel.com using OAuth authentication.

Bash
# Add Vercel MCP to Claude Code (authenticates via OAuth browser flow)
claude mcp add --transport http vercel https://mcp.vercel.com

Claude Code will open a browser to complete OAuth. Once done, the token is cached automatically.

.mcp.json Configuration (Token-based)

JSON
{
  "mcpServers": {
    "vercel": {
      "type": "http",
      "url": "https://mcp.vercel.com",
      "headers": {
        "Authorization": "Bearer ${VERCEL_TOKEN}"
      }
    }
  }
}

Available MCP Tools

ToolDescription
list_projectsList all Vercel projects in your account
get_projectGet project details, framework, settings
list_deploymentsList deployments with status and URLs
get_deploymentGet deployment details and build status
get_deployment_build_logsFetch build logs for debugging
get_runtime_logsFetch serverless function runtime logs
list_teamsList your Vercel teams
check_domain_availability_and_priceCheck if a domain is available
search_vercel_documentationSearch Vercel docs in natural language

CLI Integration

Installation

Bash
npm install -g vercel

Authentication

Bash
vercel login
# Or use a token:
vercel login --token $VERCEL_TOKEN

Key Commands

Bash
# Deploy current directory
vercel deploy

# Deploy to production
vercel --prod

# List deployments
vercel ls

# Inspect a deployment
vercel inspect <deployment-url>

# View logs
vercel logs <deployment-url>

# Manage environment variables
vercel env add MY_VAR production
vercel env ls production
vercel env rm MY_VAR production

# Rollback to previous deployment
vercel rollback

# Pull env vars to local .env
vercel env pull .env.local

# Link project to local directory
vercel link

# Open project dashboard in browser
vercel open

Environment Variables

Bash
# Vercel token (from vercel.com/account/tokens)
VERCEL_TOKEN=...

# Project and team (from project settings or `vercel link`)
VERCEL_ORG_ID=team_...
VERCEL_PROJECT_ID=prj_...

# Used inside deployed functions
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgresql://...

Sync local .env.local with Vercel:

Bash
vercel env pull .env.local

vercel.json Configuration

vercel.json is the main knob for edge/serverless behavior — it lives at the project root and controls rewrites, redirects, response headers, per-function compute (region, runtime, memory, maxDuration), and scheduled crons. Settings here are committed to git and apply on every deploy, so they are the durable counterpart to anything you can also click in the dashboard. Start the file with the $schema line for editor autocomplete and validation.

How a request and a scheduled job flow through it:

JSON
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "redirects": [
    { "source": "/old-pricing", "destination": "/pricing", "permanent": true }
  ],
  "rewrites": [
    { "source": "/api/proxy/:path*", "destination": "https://api.example.com/:path*" }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Frame-Options", "value": "SAMEORIGIN" },
        { "key": "X-Content-Type-Options", "value": "nosniff" }
      ]
    }
  ],
  "functions": {
    "app/api/mpesa/stk/route.ts": {
      "maxDuration": 30,
      "memory": 1024
    }
  },
  "crons": [
    { "path": "/api/reconcile-mpesa", "schedule": "0 * * * *" }
  ]
}

Field notes (verified against the current schema):

  • redirects — use "permanent": true for 301/308, false for 307. source/destination support :param and :path* patterns.
  • rewrites — proxy without changing the visible URL; great for fronting an external API under your own domain.
  • functions — keys are file globs (e.g. app/api/*/route.ts). Set maxDuration (seconds), memory (MB), and runtime. Routes with different settings are bundled separately.
  • regions — set a top-level "regions": ["fra1"] to pin functions to a region. For Kenyan / East African users, fra1 (Frankfurt) is the lowest-latency Vercel region; the default iad1 (US East) adds a costly round trip.
  • crons — each entry needs a path (starting with /) and a standard 5-field schedule expression.

Gotcha — secure your cron endpoints. Cron paths are publicly reachable URLs; anyone who guesses /api/reconcile-mpesa can trigger your job. Vercel sends an Authorization: Bearer <CRON_SECRET> header on scheduled invocations — set a CRON_SECRET env var and reject any request whose header does not match:

TypeScript
// app/api/reconcile-mpesa/route.ts
export function GET(request: Request) {
  const authHeader = request.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 });
  }
  // ... reconciliation logic
  return Response.json({ ok: true });
}

Second gotcha: when Fluid Compute is enabled, memory cannot be set in vercel.json — configure it in the project dashboard instead. maxDuration and regions still work in the file.


Automation Workflows

You are in great shape to automate the full loop — here is how Claude Code drives a deploy with the CLI and then inspects the result through the MCP server:

Claude Code Hook: Post-Deploy Notification

.claude/settings.json:

JSON
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_OUTPUT\" | grep -q 'vercel --prod'; then node scripts/notify-deploy.js; fi"
          }
        ]
      }
    ]
  }
}

Slash Command: Deploy and Inspect

.claude/commands/deploy.md:

Markdown
Deploy the current project to Vercel production and report the deployment URL and status.

Use Bash to run:
```bash
vercel --prod --yes 2>&1 | tail -5

Then use the Vercel MCP tool list_deployments to get the latest deployment's URL and build status. Report back with the deployment URL, status, and any build warnings.

Text

Usage: `/project:deploy`

### CI/CD: GitHub Actions with Vercel

```yaml
# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Vercel CLI
        run: npm install -g vercel
      - name: Pull Vercel environment
        run: vercel env pull .env.production --token=${{ secrets.VERCEL_TOKEN }}
      - name: Build
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - name: Deploy
        id: deploy
        run: |
          url=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$url" >> $GITHUB_OUTPUT
      - name: Comment PR with preview URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `Deployed to: ${{ steps.deploy.outputs.url }}`
            })

Preview Deployments per Branch

Bash
# Deploy a preview for the current branch
vercel deploy --env BRANCH=$(git branch --show-current)

Common Use Cases

Use CaseApproach
Inspect failing buildMCP get_deployment_build_logs
Debug serverless functionMCP get_runtime_logs
Rollback bad releasevercel rollback or MCP
Manage env varsvercel env add/ls/rm
Domain assignmentMCP check_domain_availability_and_price
Preview links in PRsGitHub Actions + vercel deploy

Troubleshooting

IssueFix
vercel: command not foundnpm install -g vercel
OAuth timeoutUse VERCEL_TOKEN in .mcp.json instead
Build failingUse MCP get_deployment_build_logs to read errors
Env vars missing in prodRun vercel env ls production to verify
VERCEL_PROJECT_ID unknownRun vercel link in project root