The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Claude Config Sync Webhook",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "github-app-installation",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-node",
"name": "GitHub App Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
3264,
752
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"id": "installation-event",
"leftValue": "={{ $json.headers['x-github-event'] }}",
"rightValue": "installation",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "installation-repositories-event",
"leftValue": "={{ $json.headers['x-github-event'] }}",
"rightValue": "installation_repositories",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "issues-event",
"leftValue": "={{ $json.headers['x-github-event'] }}",
"rightValue": "issues",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "or"
},
"options": {}
},
"id": "filter-events",
"name": "Filter Events",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [
4160,
656
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "action-created",
"leftValue": "={{ $json.body.action }}",
"rightValue": "created",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "action-added",
"leftValue": "={{ $json.body.action }}",
"rightValue": "added",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "action-edited-dashboard",
"leftValue": "={{ $json.body.action === 'edited' && ($json.body.issue?.title || '').includes('Claude Config Sync Dashboard') && ($json.body.issue?.body || '').includes('[x] **Request sync now**') }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "or"
},
"options": {}
},
"id": "filter-actions",
"name": "Filter Actions",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [
4384,
656
]
},
{
"parameters": {
"jsCode": "// Extract target repos based on event type\nconst event = $input.first().json.headers['x-github-event'];\nconst body = $input.first().json.body;\nlet target_repos = '';\n\nif (event === 'installation' && body.action === 'created') {\n // New installation - repos in body.repositories\n const repos = body.repositories || [];\n target_repos = repos.map(r => r.full_name).join(',');\n} else if (event === 'installation_repositories' && body.action === 'added') {\n // Repos added to installation - repos in body.repositories_added\n const repos = body.repositories_added || [];\n target_repos = repos.map(r => r.full_name).join(',');\n} else if (event === 'issues' && body.action === 'edited') {\n // Dashboard sync request - single repo\n target_repos = body.repository.full_name;\n}\n\nreturn [{ json: { target_repos, headers: $input.first().json.headers, body } }];"
},
"id": "extract-target-repos",
"name": "Extract Target Repos",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
4608,
656
]
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "workflow",
"owner": {
"__rl": true,
"value": "YOUR_GITHUB_USERNAME",
"mode": "name"
},
"repository": {
"__rl": true,
"value": "claude-config",
"mode": "name"
},
"workflowId": {
"__rl": true,
"mode": "filename",
"value": "sync-to-repos.yaml"
},
"ref": {
"__rl": true,
"value": "main",
"mode": "name"
},
"inputs": "={{ JSON.stringify({ target_repos: $json.target_repos }) }}"
},
"id": "trigger-workflow",
"name": "Trigger Workflow Dispatch",
"type": "n8n-nodes-base.github",
"typeVersion": 1.1,
"position": [
4832,
656
],
"credentials": {
"githubOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "noData",
"options": {
"responseCode": 200
}
},
"id": "respond-200",
"name": "Respond 200 OK",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3936,
656
],
"typeVersion": 1.4
},
{
"parameters": {
"respondWith": "noData",
"options": {
"responseCode": 401
}
},
"id": "respond-401",
"name": "Respond 401 Unauthorized",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3936,
848
],
"typeVersion": 1.4
},
{
"parameters": {
"action": "hmac",
"type": "SHA256",
"value": "={{ JSON.stringify($json.body) }}",
"dataPropertyName": "=signature-256",
"secret": "YOUR_GITHUB_WEBHOOK_SECRET"
},
"id": "compute-hmac",
"name": "Compute HMAC256",
"type": "n8n-nodes-base.crypto",
"position": [
3488,
752
],
"typeVersion": 1
},
{
"parameters": {
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "validate-signature",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json['signature-256'] }}",
"rightValue": "={{ $json.headers['x-hub-signature-256'].split('=').pop() }}"
}
]
},
"options": {}
},
"id": "validate-hmac",
"name": "Validate HMAC256",
"type": "n8n-nodes-base.if",
"position": [
3712,
752
],
"typeVersion": 2.2
},
{
"parameters": {
"errorMessage": "HMAC256 signature doesn't match provided signature. Make sure that the GitHub webhook secret is identical to the secret stored in the 'Compute HMAC256' node."
},
"id": "stop-error",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
4160,
848
],
"typeVersion": 1
}
],
"connections": {
"GitHub App Webhook": {
"main": [
[
{
"node": "Compute HMAC256",
"type": "main",
"index": 0
}
]
]
},
"Filter Events": {
"main": [
[
{
"node": "Filter Actions",
"type": "main",
"index": 0
}
]
]
},
"Filter Actions": {
"main": [
[
{
"node": "Extract Target Repos",
"type": "main",
"index": 0
}
]
]
},
"Extract Target Repos": {
"main": [
[
{
"node": "Trigger Workflow Dispatch",
"type": "main",
"index": 0
}
]
]
},
"Trigger Workflow Dispatch": {
"main": [
[]
]
},
"Respond 200 OK": {
"main": [
[
{
"node": "Filter Events",
"type": "main",
"index": 0
}
]
]
},
"Compute HMAC256": {
"main": [
[
{
"node": "Validate HMAC256",
"type": "main",
"index": 0
}
]
]
},
"Validate HMAC256": {
"main": [
[
{
"node": "Respond 200 OK",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond 401 Unauthorized",
"type": "main",
"index": 0
}
]
]
},
"Respond 401 Unauthorized": {
"main": [
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
githubOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow ensures your Claude AI configurations remain perfectly synchronised across multiple GitHub repositories, saving you hours of manual updates and reducing errors in deployment. It is ideal for developers and teams managing AI-driven projects who rely on Claude's settings for consistent performance. The key step involves receiving a webhook from GitHub, extracting the affected repositories, and dispatching targeted updates via GitHub's workflow API, all secured with HMAC256 cryptographic verification to prevent unauthorised access.
Use this workflow when you need automated, secure syncing of configuration changes triggered by GitHub events, such as pushes or merges in shared repos. Avoid it for one-off manual adjustments or environments without GitHub webhooks enabled, as it requires proper app installation. Common variations include adapting the filters for specific event types or integrating additional crypto checks for enhanced security.
About this workflow
Claude Config Sync Webhook. Uses github, respondToWebhook, crypto, stopAndError. Webhook trigger; 10 nodes.
Source: https://github.com/anthony-spruyt/claude-config/blob/1bc9e3fb701a848fc5c983ebc1987aeaf9b99100/.n8n/github-app-webhook-to-workflow-dispatch.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Ensure that the calls to the workflow's webhook are (a) originating from the correct GitHub repository and (b) haven't been tampered with. When a secret is provided in a GitHub webhook configuration,
🔥 n8n Members Sale – n8n Community Members Get ideoGener8r for Just $10! (Reg. $15) Use Coupon Code: (Valid for n8n community members)
This n8n workflow template uses community nodes and is only compatible with the self-hosted version of n8n.
AIDP - Main Workflow v3. Uses executeCommand, github, jira. Webhook trigger; 12 nodes.
AIDP - Main Workflow v7. Uses executeCommand, github, jira. Webhook trigger; 12 nodes.