Netlify + Claude Code Integration Guide
What is Netlify?
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.
███╗ ██╗███████╗████████╗██╗ ██╗███████╗██╗ ██╗
████╗ ██║██╔════╝╚══██╔══╝██║ ██║██╔════╝╚██╗ ██╔╝
██╔██╗ ██║█████╗ ██║ ██║ ██║█████╗ ╚████╔╝
██║╚██╗██║██╔══╝ ██║ ██║ ██║██╔══╝ ╚██╔╝
██║ ╚████║███████╗ ██║ ███████╗██║██║ ██║
╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═╝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
| Resource | URL |
|---|---|
| Netlify Docs | https://docs.netlify.com |
| Netlify MCP Server | https://docs.netlify.com/build/build-with-ai/netlify-mcp-server/ |
| Netlify CLI Reference | https://docs.netlify.com/cli/get-started/ |
| Edge Functions | https://docs.netlify.com/edge-functions/overview/ |
| Netlify Functions | https://docs.netlify.com/functions/overview/ |
MCP Server Setup
Official Netlify MCP Server
The official Netlify MCP server is at GitHub: netlify/netlify-mcp.
# Add via Claude Code CLI (npx transport)
claude mcp add netlify -- npx -y netlify-mcp.mcp.json Configuration
{
"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
| Tool | Description |
|---|---|
netlify_create_site | Create a new Netlify site |
netlify_list_sites | List all sites in your account |
netlify_deploy | Trigger a deploy for a site |
netlify_get_deploy | Get deploy status and logs |
netlify_set_env_var | Set an environment variable |
netlify_list_env_vars | List all environment variables |
netlify_get_forms | List form submissions |
netlify_install_extension | Install a Netlify extension |
netlify_get_team | Get team and billing info |
CLI Integration
Installation
npm install -g netlify-cliAuthentication
# Interactive login (browser OAuth)
netlify login
# Token-based (for CI)
export NETLIFY_AUTH_TOKEN=...Key Commands
# 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 .envEnvironment Variables
# 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.comAutomation Workflows
Claude Code Hook: Lint Before Deploy
.claude/settings.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:
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 errorsUsage: /project:netlify-deploy
GitHub Actions: Preview + Production Deploy
# .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=distEdge 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:
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:
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 likepath: "/order/:id"arrive oncontext.params. - Without
config: it falls back to the default routehttps://your-site.netlify.app/.netlify/functions/stk-push. - Locally:
netlify devserves functions onlocalhost:8888; or call one directly withnetlify functions:invoke stk-push --payload '{"phone":"254708374149","amount":1}'.
[functions] Config
The default directory is netlify/functions. Override or tune it in netlify.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 Case | Approach |
|---|---|
| Deploy on merge | GitHub Actions + netlify deploy --prod |
| Preview URLs for PRs | netlify deploy (no --prod) in PR workflow |
| Edge function auth | netlify/edge-functions/ directory |
| Form submissions | MCP netlify_get_forms |
| Environment management | MCP netlify_set_env_var / CLI env:set |
| Extension management | MCP netlify_install_extension |
Troubleshooting
| Issue | Fix |
|---|---|
netlify: command not found | npm install -g netlify-cli |
| Not linked to a site | Run netlify link in project root |
| Build fails in CI | Check NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID secrets |
| Edge function not triggering | Verify config.path matches the route |
| Functions timeout | Increase timeout in netlify.toml under [functions] |
netlify.toml example:
[build]
command = "npm run build"
publish = "dist"
[functions]
node_bundler = "esbuild"
[[edge_functions]]
path = "/api/*"
function = "auth"