n8n Workflow Templates for Claude Code
Import these ready-to-use workflow templates directly into your n8n instance to quickly implement Claude Code automation. Each template includes the complete JSON export and setup instructions.
π Quick Start Templates
Template 1: Automated Code Review Bot
Description: Automatically review pull requests using Claude Code when theyβre opened or updated.
{
"name": "Claude Code Review Bot",
"nodes": [
{
"parameters": {
"authentication": "oAuth2",
"resource": "pull",
"operation": "get",
"owner": "={{ $json.repository.owner.login }}",
"repository": "={{ $json.repository.name }}",
"pullRequestNumber": "={{ $json.pull_request.number }}"
},
"id": "a1b2c3d4",
"name": "Get PR Details",
"type": "n8n-nodes-base.github",
"typeVersion": 1,
"position": [450, 300]
},
{
"parameters": {
"httpMethod": "POST",
"path": "github-pr-review",
"responseMode": "responseNode",
"options": {}
},
"id": "e5f6g7h8",
"name": "GitHub PR Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "github-pr-webhook"
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3000/claude-execute",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"prompt\": \"Review this pull request for:\\n- Code quality and best practices\\n- Security vulnerabilities\\n- Performance issues\\n- Test coverage\\n\\nPR Title: {{ $('Get PR Details').item.json.title }}\\n\\nChanges:\\n{{ $('Get PR Details').item.json.body }}\\n\\nProvide specific, actionable feedback.\",\n \"mode\": \"review\",\n \"context\": {\n \"files_changed\": {{ $('Get PR Details').item.json.changed_files }},\n \"additions\": {{ $('Get PR Details').item.json.additions }},\n \"deletions\": {{ $('Get PR Details').item.json.deletions }}\n }\n}"
},
"id": "i9j0k1l2",
"name": "Claude Review",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [650, 300]
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "review",
"operation": "create",
"owner": "={{ $('GitHub PR Webhook').item.json.repository.owner.login }}",
"repository": "={{ $('GitHub PR Webhook').item.json.repository.name }}",
"pullRequestNumber": "={{ $('GitHub PR Webhook').item.json.pull_request.number }}",
"event": "COMMENT",
"body": "=## π€ Claude Code Review\\n\\n{{ $('Claude Review').item.json.output }}\\n\\n---\\n*Generated by Claude Code Integration*"
},
"id": "m3n4o5p6",
"name": "Post Review Comment",
"type": "n8n-nodes-base.github",
"typeVersion": 1,
"position": [850, 300]
}
],
"connections": {
"GitHub PR Webhook": {
"main": [
[
{
"node": "Get PR Details",
"type": "main",
"index": 0
}
]
]
},
"Get PR Details": {
"main": [
[
{
"node": "Claude Review",
"type": "main",
"index": 0
}
]
]
},
"Claude Review": {
"main": [
[
{
"node": "Post Review Comment",
"type": "main",
"index": 0
}
]
]
}
}
}Setup Instructions:
- Import the workflow into n8n
- Configure GitHub OAuth credentials
- Set up the webhook URL in your GitHub repository settings
- Update the Claude endpoint URL if different from
localhost:3000 - Test with a sample PR
Template 2: Daily Standup Report Generator
Description: Generate daily standup reports by analyzing Git commits and project activity.
{
"name": "Daily Standup Generator",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 24
}
]
}
},
"id": "schedule1",
"name": "Daily Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [250, 300]
},
{
"parameters": {
"command": "=git log --since=\"24 hours ago\" --pretty=format:\"%h - %an - %s\" --abbrev-commit"
},
"id": "exec1",
"name": "Get Recent Commits",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [450, 200]
},
{
"parameters": {
"resource": "issue",
"operation": "getAll",
"owner": "={{ $vars.GITHUB_OWNER }}",
"repository": "={{ $vars.GITHUB_REPO }}",
"returnAll": false,
"limit": 20,
"filters": {
"state": "open",
"sort": "updated"
}
},
"id": "github1",
"name": "Get Open Issues",
"type": "n8n-nodes-base.github",
"typeVersion": 1,
"position": [450, 400]
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3000/claude-execute",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"prompt\": \"Generate a daily standup report based on:\\n\\nRecent Commits:\\n{{ $('Get Recent Commits').item.json.stdout }}\\n\\nOpen Issues:\\n{{ $('Get Open Issues').all().map(item => `- ${item.json.title} (#${item.json.number})`).join('\\n') }}\\n\\nFormat the report with:\\n1. Yesterday's accomplishments\\n2. Today's plans\\n3. Any blockers\\n4. Key metrics\",\n \"mode\": \"report\"\n}"
},
"id": "claude1",
"name": "Generate Standup",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [650, 300]
},
{
"parameters": {
"authentication": "oAuth2",
"text": "=π
*Daily Standup Report*\\n\\n{{ $('Generate Standup').item.json.output }}",
"otherOptions": {}
},
"id": "slack1",
"name": "Post to Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [850, 300]
}
],
"connections": {
"Daily Trigger": {
"main": [
[
{
"node": "Get Recent Commits",
"type": "main",
"index": 0
},
{
"node": "Get Open Issues",
"type": "main",
"index": 0
}
]
]
},
"Get Recent Commits": {
"main": [
[
{
"node": "Generate Standup",
"type": "main",
"index": 0
}
]
]
},
"Get Open Issues": {
"main": [
[
{
"node": "Generate Standup",
"type": "main",
"index": 0
}
]
]
},
"Generate Standup": {
"main": [
[
{
"node": "Post to Slack",
"type": "main",
"index": 0
}
]
]
}
}
}Template 3: Bug Fix Automation Pipeline
Description: Automatically attempt to fix bugs reported in issues using Claude Code.
{
"name": "Automated Bug Fixer",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "bug-report",
"responseMode": "responseNode"
},
"id": "webhook1",
"name": "Bug Report Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "bug-report-hook"
},
{
"parameters": {
"content": "=## π Bug Analysis\\n\\n**Issue**: {{ $json.issue.title }}\\n**Description**: {{ $json.issue.body }}\\n**Labels**: {{ $json.issue.labels.map(l => l.name).join(', ') }}"
},
"id": "note1",
"name": "Bug Details",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [250, 100]
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3000/claude-execute",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"prompt\": \"Analyze this bug report and suggest a fix:\\n\\nTitle: {{ $json.issue.title }}\\nDescription: {{ $json.issue.body }}\\n\\nProvide:\\n1. Root cause analysis\\n2. Suggested fix with code\\n3. Test cases to verify the fix\",\n \"mode\": \"fix\",\n \"workingDirectory\": \"{{ $vars.PROJECT_PATH }}\"\n}"
},
"id": "claude2",
"name": "Analyze Bug",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [450, 300]
},
{
"parameters": {
"jsCode": "// Parse Claude's response and extract code fixes\nconst response = $input.first().json.output;\nconst codeBlocks = response.match(/```[\\w]*\\n([\\s\\S]*?)\\n```/g) || [];\n\nconst fixes = codeBlocks.map((block, index) => {\n const code = block.replace(/```[\\w]*\\n|\\n```/g, '');\n const language = block.match(/```(\\w+)/) ? block.match(/```(\\w+)/)[1] : 'javascript';\n \n return {\n json: {\n index,\n language,\n code,\n description: `Fix ${index + 1}`\n }\n };\n});\n\nreturn fixes.length > 0 ? fixes : [{json: {error: 'No code fixes found'}}];"
},
"id": "code1",
"name": "Extract Fixes",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [650, 300]
},
{
"parameters": {
"branchName": "=fix/{{ $('Bug Report Webhook').item.json.issue.number }}-{{ $('Bug Report Webhook').item.json.issue.title.toLowerCase().replace(/[^a-z0-9]/g, '-').substring(0, 30) }}",
"commitMessage": "=fix: {{ $('Bug Report Webhook').item.json.issue.title }}\\n\\nResolves #{{ $('Bug Report Webhook').item.json.issue.number }}"
},
"id": "git1",
"name": "Create Fix Branch",
"type": "n8n-nodes-base.git",
"typeVersion": 1,
"position": [850, 300]
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "pull",
"operation": "create",
"owner": "={{ $vars.GITHUB_OWNER }}",
"repository": "={{ $vars.GITHUB_REPO }}",
"title": "=π€ Auto-fix: {{ $('Bug Report Webhook').item.json.issue.title }}",
"body": "=## Automated Fix for #{{ $('Bug Report Webhook').item.json.issue.number }}\\n\\n### Analysis\\n{{ $('Analyze Bug').item.json.output }}\\n\\n### Changes Made\\nThis PR was automatically generated by Claude Code to fix the reported issue.\\n\\n**Note**: Please review and test before merging.",
"head": "=fix/{{ $('Bug Report Webhook').item.json.issue.number }}-{{ $('Bug Report Webhook').item.json.issue.title.toLowerCase().replace(/[^a-z0-9]/g, '-').substring(0, 30) }}",
"base": "main"
},
"id": "pr1",
"name": "Create PR",
"type": "n8n-nodes-base.github",
"typeVersion": 1,
"position": [1050, 300]
}
],
"connections": {
"Bug Report Webhook": {
"main": [
[
{
"node": "Analyze Bug",
"type": "main",
"index": 0
}
]
]
},
"Analyze Bug": {
"main": [
[
{
"node": "Extract Fixes",
"type": "main",
"index": 0
}
]
]
},
"Extract Fixes": {
"main": [
[
{
"node": "Create Fix Branch",
"type": "main",
"index": 0
}
]
]
},
"Create Fix Branch": {
"main": [
[
{
"node": "Create PR",
"type": "main",
"index": 0
}
]
]
}
}
}Template 4: Documentation Auto-Generator
Description: Automatically generate and update documentation when code changes.
{
"name": "Auto Documentation Generator",
"nodes": [
{
"parameters": {
"events": [
"push"
],
"owner": "={{ $vars.GITHUB_OWNER }}",
"repository": "={{ $vars.GITHUB_REPO }}",
"path": "src/**/*.{js,ts,jsx,tsx}"
},
"id": "trigger1",
"name": "Code Change Trigger",
"type": "n8n-nodes-base.githubTrigger",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3000/claude-execute",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"prompt\": \"Analyze these code changes and generate/update documentation:\\n\\nChanged Files:\\n{{ $json.commits[0].modified.join('\\n') }}\\n\\nGenerate:\\n1. Function documentation\\n2. API documentation\\n3. Usage examples\\n4. Update README if needed\",\n \"mode\": \"document\",\n \"context\": {\n \"repository\": \"{{ $json.repository.full_name }}\",\n \"commit\": \"{{ $json.after }}\"\n }\n}"
},
"id": "claude3",
"name": "Generate Docs",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [450, 300]
},
{
"parameters": {
"operation": "append",
"fileName": "=./docs/API_{{ $now.format('YYYY-MM-DD') }}.md",
"fileContent": "={{ $json.output }}"
},
"id": "file1",
"name": "Save Documentation",
"type": "n8n-nodes-base.fileSystem",
"typeVersion": 1,
"position": [650, 300]
},
{
"parameters": {
"command": "=cd {{ $vars.PROJECT_PATH }} && git add docs/* && git commit -m \"docs: auto-update documentation\" && git push"
},
"id": "git2",
"name": "Commit Docs",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [850, 300]
}
],
"connections": {
"Code Change Trigger": {
"main": [
[
{
"node": "Generate Docs",
"type": "main",
"index": 0
}
]
]
},
"Generate Docs": {
"main": [
[
{
"node": "Save Documentation",
"type": "main",
"index": 0
}
]
]
},
"Save Documentation": {
"main": [
[
{
"node": "Commit Docs",
"type": "main",
"index": 0
}
]
]
}
}
}Template 5: Test Generation Pipeline
Description: Automatically generate tests for new or modified functions.
{
"name": "Automated Test Generator",
"nodes": [
{
"parameters": {
"path": "=./src",
"recursive": true,
"options": {
"usePolling": true,
"interval": 5000
}
},
"id": "watch1",
"name": "Watch Code Changes",
"type": "n8n-nodes-base.fileWatcher",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"fileName": "={{ $json.file }}",
"options": {}
},
"id": "read1",
"name": "Read File",
"type": "n8n-nodes-base.readFile",
"typeVersion": 1,
"position": [450, 300]
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3000/claude-execute",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"prompt\": \"Generate comprehensive unit tests for this code:\\n\\nFile: {{ $('Watch Code Changes').item.json.file }}\\n\\nCode:\\n{{ $json.data }}\\n\\nGenerate tests using the project's testing framework with:\\n- Happy path tests\\n- Edge cases\\n- Error scenarios\\n- Mock dependencies\",\n \"mode\": \"test\"\n}"
},
"id": "claude4",
"name": "Generate Tests",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [650, 300]
},
{
"parameters": {
"fileName": "={{ $('Watch Code Changes').item.json.file.replace('/src/', '/tests/').replace('.js', '.test.js').replace('.ts', '.test.ts') }}",
"fileContent": "={{ $json.output }}",
"options": {
"createDirectories": true
}
},
"id": "write1",
"name": "Save Test File",
"type": "n8n-nodes-base.writeFile",
"typeVersion": 1,
"position": [850, 300]
},
{
"parameters": {
"command": "=npm test {{ $('Save Test File').item.json.fileName }}"
},
"id": "test1",
"name": "Run Tests",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [1050, 300]
}
],
"connections": {
"Watch Code Changes": {
"main": [
[
{
"node": "Read File",
"type": "main",
"index": 0
}
]
]
},
"Read File": {
"main": [
[
{
"node": "Generate Tests",
"type": "main",
"index": 0
}
]
]
},
"Generate Tests": {
"main": [
[
{
"node": "Save Test File",
"type": "main",
"index": 0
}
]
]
},
"Save Test File": {
"main": [
[
{
"node": "Run Tests",
"type": "main",
"index": 0
}
]
]
}
}
}π¨ Custom Node Template
Create a custom n8n node for Claude Code:
// ClaudeCode.node.ts
import {
IExecuteFunctions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
NodeOperationError,
} from 'n8n-workflow';
export class ClaudeCode implements INodeType {
description: INodeTypeDescription = {
displayName: 'Claude Code',
name: 'claudeCode',
icon: 'file:claude.svg',
group: ['transform'],
version: 1,
subtitle: '={{ $parameter.operation }}',
description: 'Interact with Claude Code for AI-powered development',
defaults: {
name: 'Claude Code',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'claudeCodeApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Generate Code',
value: 'generate',
description: 'Generate new code based on requirements',
},
{
name: 'Review Code',
value: 'review',
description: 'Review existing code for improvements',
},
{
name: 'Fix Issues',
value: 'fix',
description: 'Fix bugs or issues in code',
},
{
name: 'Generate Tests',
value: 'test',
description: 'Generate tests for existing code',
},
{
name: 'Document Code',
value: 'document',
description: 'Generate documentation for code',
},
],
default: 'generate',
},
{
displayName: 'Prompt',
name: 'prompt',
type: 'string',
typeOptions: {
rows: 5,
},
default: '',
required: true,
description: 'The instruction or request for Claude Code',
},
{
displayName: 'Additional Options',
name: 'additionalOptions',
type: 'collection',
placeholder: 'Add Option',
default: {},
options: [
{
displayName: 'Context',
name: 'context',
type: 'string',
typeOptions: {
rows: 3,
},
default: '',
description: 'Additional context for the operation',
},
{
displayName: 'Working Directory',
name: 'workingDirectory',
type: 'string',
default: '',
description: 'Directory to execute operations in',
},
{
displayName: 'Max Tokens',
name: 'maxTokens',
type: 'number',
default: 4000,
description: 'Maximum tokens for response',
},
{
displayName: 'Temperature',
name: 'temperature',
type: 'number',
default: 0.7,
typeOptions: {
minValue: 0,
maxValue: 1,
numberStepSize: 0.1,
},
description: 'Creativity of responses (0-1)',
},
],
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: INodeExecutionData[] = [];
const credentials = await this.getCredentials('claudeCodeApi');
for (let i = 0; i < items.length; i++) {
try {
const operation = this.getNodeParameter('operation', i) as string;
const prompt = this.getNodeParameter('prompt', i) as string;
const additionalOptions = this.getNodeParameter('additionalOptions', i, {}) as any;
const requestBody = {
operation,
prompt,
...additionalOptions,
};
const response = await this.helpers.requestWithAuthentication.call(
this,
'claudeCodeApi',
{
method: 'POST',
url: `${credentials.baseUrl}/execute`,
body: requestBody,
json: true,
},
);
returnData.push({
json: {
...items[i].json,
claudeResponse: response,
},
pairedItem: i,
});
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
pairedItem: i,
});
continue;
}
throw error;
}
}
return [returnData];
}
}π§ Environment Variables Template
Create a .env template for your n8n instance:
# n8n Configuration
N8N_PORT=5678
N8N_PROTOCOL=http
N8N_HOST=localhost
WEBHOOK_URL=http://localhost:5678/
# Claude Code Configuration
CLAUDE_CODE_ENDPOINT=http://localhost:3000
CLAUDE_API_KEY=your-anthropic-api-key
# GitHub Configuration (for templates)
GITHUB_OWNER=your-github-username
GITHUB_REPO=your-repo-name
GITHUB_TOKEN=your-github-token
# Project Paths
PROJECT_PATH=/path/to/your/project
DOCS_PATH=/path/to/your/docs
# Database (for n8n)
DB_TYPE=sqlite
DB_SQLITE_DATABASE=/home/node/.n8n/database.sqlite
# Executions
EXECUTIONS_PROCESS=main
EXECUTIONS_TIMEOUT=3600
EXECUTIONS_TIMEOUT_MAX=7200
# Security
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your-secure-password
# Metrics (optional)
N8N_METRICS=true
N8N_METRICS_PREFIX=n8n_π¦ Quick Deploy Script
#!/bin/bash
# deploy-n8n-claude.sh
echo "π Deploying n8n with Claude Code Integration"
# Check prerequisites
command -v docker >/dev/null 2>&1 || { echo "Docker required but not installed. Aborting." >&2; exit 1; }
command -v node >/dev/null 2>&1 || { echo "Node.js required but not installed. Aborting." >&2; exit 1; }
# Create directories
mkdir -p n8n-claude-integration/{workflows,credentials,nodes}
# Start Claude webhook server
cat > n8n-claude-integration/claude-server.js << 'EOF'
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
app.post('/claude-execute', async (req, res) => {
const { prompt, workingDirectory, mode } = req.body;
try {
const command = `claude "${prompt.replace(/"/g, '\\"')}"`;
exec(command, {
cwd: workingDirectory || process.cwd(),
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
timeout: 300000 // 5 minutes
}, (error, stdout, stderr) => {
if (error) {
return res.status(500).json({
error: stderr || error.message,
mode,
timestamp: new Date().toISOString()
});
}
res.json({
success: true,
output: stdout,
mode,
timestamp: new Date().toISOString()
});
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
const PORT = process.env.CLAUDE_PORT || 3000;
app.listen(PORT, () => {
console.log(`Claude webhook server running on port ${PORT}`);
});
EOF
# Install dependencies
cd n8n-claude-integration
npm init -y
npm install express
# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n-claude
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_PORT=5678
- N8N_PROTOCOL=http
- N8N_HOST=localhost
- WEBHOOK_URL=http://localhost:5678/
- GENERIC_TIMEZONE=America/New_York
- TZ=America/New_York
volumes:
- ./n8n-data:/home/node/.n8n
- ./workflows:/home/node/workflows
- ./custom-nodes:/home/node/.n8n/custom
networks:
- n8n-claude-network
claude-webhook:
build: .
container_name: claude-webhook
restart: unless-stopped
ports:
- "3000:3000"
environment:
- CLAUDE_PORT=3000
volumes:
- ./:/app
- /var/run/docker.sock:/var/run/docker.sock
command: node /app/claude-server.js
networks:
- n8n-claude-network
networks:
n8n-claude-network:
driver: bridge
EOF
# Create Dockerfile for Claude webhook
cat > Dockerfile << 'EOF'
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "claude-server.js"]
EOF
# Start services
echo "Starting services..."
docker-compose up -d
echo "β
n8n with Claude Code integration deployed!"
echo "π n8n UI: http://localhost:5678"
echo "π Claude webhook: http://localhost:3000"
echo ""
echo "Import the workflow templates from the JSON files above to get started!"π Additional Resources
- n8n Integration Overview
- Advanced Integration Patterns
- Workflow Patterns
- n8n Template Library
- n8n Community Forum
Source: https://n8n.io/workflows/ Last Updated: 2025-07-21