← Back to dashboard
netlifyhostingfresh

Netlify + Claude Code Integration Guide

What is Netlify?

The real model

Git-driven deploys + Deno-based Edge Functions + Lambda Functions + Blobs + Image CDN.

Edge Functions run on Deno at the request CDN node; Functions run as AWS Lambda in one region. Netlify Identity (GoTrue) is a built-in auth option if you want to skip Clerk for simple sites. Netlify Blobs is an S3-like key-value store callable from Functions. Image CDN exposes Netlify's Image CDN API for transformation via URL params. Best fit when the team's mental model is "static site + a few API calls" rather than full-stack Next.js.

Five Netlify primitives

Static-site DNA with serverless bolted on for the rest.

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

Netlify + Claude Code Integration Guide

Focus: Deploying sites, managing edge functions, and automating Netlify projects from Claude Code using the official Netlify MCP server and netlify-cli.

Overview

Netlify is a platform for hosting web apps with built-in CI/CD, edge functions, forms, and identity. Its official MCP server (launched Feb 2025) lets Claude Code create projects, trigger deploys, manage environment variables, install extensions, and query build logs — all via natural language inside your coding session.

Here is the big picture of how a change reaches your users — once you see the flow, the commands below click into place:

Official Documentation


MCP Server Setup

Official Netlify MCP Server

The official Netlify MCP server is at GitHub: netlify/netlify-mcp.

Bash
# Add via Claude Code CLI (npx transport)
claude mcp add netlify -- npx -y netlify-mcp

.mcp.json Configuration

JSON
{
  "mcpServers": {
    "netlify": {
      "command": "npx",
      "args": ["-y", "netlify-mcp"],
      "env": {
        "NETLIFY_AUTH_TOKEN": "${NETLIFY_AUTH_TOKEN}"
      }
    }
  }
}

Requirements: Node.js 22+, a Netlify account with a personal access token.

Available MCP Tools

ToolDescription
netlify_create_siteCreate a new Netlify site
netlify_list_sitesList all sites in your account
netlify_deployTrigger a deploy for a site
netlify_get_deployGet deploy status and logs
netlify_set_env_varSet an environment variable
netlify_list_env_varsList all environment variables
netlify_get_formsList form submissions
netlify_install_extensionInstall a Netlify extension
netlify_get_teamGet team and billing info

CLI Integration

Installation

Bash
npm install -g netlify-cli

Authentication

Bash
# Interactive login (browser OAuth)
netlify login

# Token-based (for CI)
export NETLIFY_AUTH_TOKEN=...

Key Commands

Bash
# Initialize / link a site
netlify init
netlify link

# Deploy (draft)
netlify deploy

# Deploy to production
netlify deploy --prod

# Open site dashboard
netlify open

# Run dev server (with Functions/Edge Functions)
netlify dev

# Invoke a serverless function locally
netlify functions:invoke my-function --payload '{"key":"value"}'

# Manage environment variables
netlify env:set MY_VAR "my-value"
netlify env:list
netlify env:unset MY_VAR

# View build and deploy logs
netlify status
netlify logs:deploy

# Pull environment to local file
netlify env:import .env

Environment Variables

Bash
# Required for MCP and CLI
NETLIFY_AUTH_TOKEN=...          # From app.netlify.com/user/applications

# Optional project-specific
NETLIFY_SITE_ID=...             # From site settings or `netlify link`

# Variables set for your deployed site
DATABASE_URL=postgresql://...
NEXT_PUBLIC_API_URL=https://api.example.com

Automation Workflows

Claude Code Hook: Lint Before Deploy

.claude/settings.json:

JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'netlify deploy --prod'; then npm run lint && npm run test; fi"
          }
        ]
      }
    ]
  }
}

Slash Command: Deploy to Netlify

.claude/commands/netlify-deploy.md:

Markdown
Deploy the current project to Netlify production.

Run the following steps:
1. Use Bash to run `npm run build` and confirm it succeeds
2. Use Bash to run `netlify deploy --prod --dir=dist` (adjust dir as needed)
3. Report the deploy URL and any warnings
4. If deploy fails, use Bash to run `netlify logs:deploy` and report errors

Usage: /project:netlify-deploy

GitHub Actions: Preview + Production Deploy

YAML
# .github/workflows/netlify.yml
name: Netlify Deploy
on:
  pull_request:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: npm ci && npm run build

      - name: Deploy Preview
        if: github.event_name == 'pull_request'
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
        run: |
          npm install -g netlify-cli
          deploy_url=$(netlify deploy --dir=dist --json | jq -r '.deploy_url')
          echo "Preview: $deploy_url"

      - name: Deploy Production
        if: github.ref == 'refs/heads/main'
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
        run: netlify deploy --prod --dir=dist

Edge Function Example

Edge functions are great for running logic close to the user before a request reaches your site — here is how the auth example below fits into a request:

netlify/edge-functions/auth.ts:

TypeScript
import type { Config, Context } from "@netlify/edge-functions";

export default async function handler(req: Request, context: Context) {
  const token = req.headers.get("Authorization");
  if (!token || !token.startsWith("Bearer ")) {
    return new Response("Unauthorized", { status: 401 });
  }
  return context.next();
}

export const config: Config = {
  path: "/api/*",
};

Serverless Functions

Edge functions run light logic at the CDN edge; serverless functions are full Node.js handlers for heavier work — talking to a database, calling the Daraja STK Push API, signing tokens, or handling M-Pesa callbacks. They live in netlify/functions/ and use the same web-standard Request → Response signature as edge functions, but run in a regional Node runtime with the full npm ecosystem available.

Function Example

netlify/functions/stk-push.mts:

TypeScript
import type { Config, Context } from "@netlify/functions";

export default async (req: Request, context: Context) => {
  if (req.method !== "POST") {
    return new Response("Method Not Allowed", { status: 405 });
  }

  const { phone, amount } = await req.json();

  // Heavy lifting belongs here: DB writes, Daraja token + STK Push, etc.
  // const token = await getDarajaToken();
  // const result = await initiateStkPush({ phone, amount, token });

  return new Response(JSON.stringify({ ok: true, phone, amount }), {
    status: 200,
    headers: { "content-type": "application/json" },
  });
};

export const config: Config = {
  path: "/api/stk-push",
};

Install the types once: npm install @netlify/functions. The .mts extension opts into ES modules; netlify/functions/stk-push.mts, netlify/functions/stk-push/stk-push.mts, and netlify/functions/stk-push/index.mts all define a function named stk-push.

How to Invoke

  • With config.path (recommended): the function answers at the clean route you set, e.g. https://your-site.netlify.app/api/stk-push. Named params like path: "/order/:id" arrive on context.params.
  • Without config: it falls back to the default route https://your-site.netlify.app/.netlify/functions/stk-push.
  • Locally: netlify dev serves functions on localhost:8888; or call one directly with netlify functions:invoke stk-push --payload '{"phone":"254708374149","amount":1}'.

[functions] Config

The default directory is netlify/functions. Override or tune it in netlify.toml:

TOML
[functions]
  directory = "netlify/functions"
  node_bundler = "esbuild"

Gotcha: Edge vs Serverless

Reach for the right runtime — they are not interchangeable:

Edge functions run on Deno at the CDN edge (no full Node API, no node_modules bundling), so M-Pesa/Daraja calls, Postgres clients, and Node-only SDKs belong in serverless functions. Use edge functions only for fast request manipulation (auth gates, redirects, geo, A/B) close to the user.


Common Use Cases

Use CaseApproach
Deploy on mergeGitHub Actions + netlify deploy --prod
Preview URLs for PRsnetlify deploy (no --prod) in PR workflow
Edge function authnetlify/edge-functions/ directory
Form submissionsMCP netlify_get_forms
Environment managementMCP netlify_set_env_var / CLI env:set
Extension managementMCP netlify_install_extension

Troubleshooting

IssueFix
netlify: command not foundnpm install -g netlify-cli
Not linked to a siteRun netlify link in project root
Build fails in CICheck NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID secrets
Edge function not triggeringVerify config.path matches the route
Functions timeoutIncrease timeout in netlify.toml under [functions]

netlify.toml example:

TOML
[build]
  command = "npm run build"
  publish = "dist"

[functions]
  node_bundler = "esbuild"

[[edge_functions]]
  path = "/api/*"
  function = "auth"