This workflow corresponds to n8n.io template #13362 — we link there as the canonical source.
This workflow follows the Chainllm → Form Trigger recipe pattern — see all workflows that pair these two integrations.
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": "Transform GitHub repositories into architecture blueprints with AI",
"nodes": [
{
"id": "c239fbe4-e34f-445f-9292-141699a76a9a",
"name": "Receive GitHub URL",
"type": "n8n-nodes-base.webhook",
"onError": "continueRegularOutput",
"position": [
-2704,
208
],
"parameters": {
"path": "repo-blueprint",
"options": {
"ignoreBots": false
},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "f6117e39-bbea-4b8b-af81-9d11dea411d6",
"name": "Blueprint Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
-2704,
512
],
"parameters": {
"path": "repo-blueprint-form",
"options": {
"buttonLabel": "Generate Blueprint"
},
"formTitle": "Repo Blueprint Architect",
"formFields": {
"values": [
{
"fieldLabel": "GitHub Repository URL",
"placeholder": "https://github.com/owner/repo",
"requiredField": true
}
]
},
"responseMode": "responseNode",
"formDescription": "Enter a public GitHub repository URL to generate an evidence-based system architecture blueprint with Mermaid.js diagrams."
},
"typeVersion": 2.1
},
{
"id": "0da401d5-5bd5-4d5c-8bd4-56c0231278e6",
"name": "Parse Owner and Repo",
"type": "n8n-nodes-base.code",
"position": [
-2432,
208
],
"parameters": {
"jsCode": "const input = $input.first().json;\nconst url = input.body?.github_url || input.body?.repository_url || input['GitHub Repository URL'];\n\nif (!url) {\n throw new Error('Missing GitHub URL. Send body.github_url or body.repository_url (webhook) or fill the form field.');\n}\n\nconst match = url.match(/github\\.com\\/([^\\/]+)\\/([^\\/\\.]+)/);\n\nif (!match) {\n throw new Error(`Invalid GitHub URL: ${url}`);\n}\n\nreturn [{\n json: {\n github_url: url,\n owner: match[1],\n repo: match[2]\n }\n}];"
},
"typeVersion": 2
},
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Fetch Repo Metadata",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2160,
208
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.v3+json"
},
{
"name": "User-Agent",
"value": "n8n-repo-blueprint"
}
]
},
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "fcdd844d-d327-45b1-b319-6b2fb78da8b6",
"name": "Fetch Repo Tree",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1888,
208
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/git/trees/{{ $json.default_branch || 'main' }}?recursive=1",
"options": {},
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.v3+json"
},
{
"name": "User-Agent",
"value": "n8n-repo-blueprint"
}
]
},
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "84d7cac3-bcb0-4c99-9778-8382f43a4699",
"name": "Identify Key Files",
"type": "n8n-nodes-base.code",
"position": [
-1616,
208
],
"parameters": {
"jsCode": "const treeData = $input.first().json;\nconst tree = treeData.tree || [];\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\n\nconst filteredTree = tree.filter(item => {\n const p = item.path.toLowerCase();\n return !p.includes('node_modules') &&\n !p.includes('.git/') &&\n !p.includes('package-lock.json') &&\n !p.includes('yarn.lock') &&\n !p.includes('dist/') &&\n !p.includes('build/') &&\n !p.includes('__pycache__') &&\n !p.includes('.egg-info');\n});\n\nlet fileTreeStr = filteredTree\n .filter(item => item.type === 'blob')\n .map(item => item.path)\n .join('\\n');\nif (fileTreeStr.length > 40000) {\n fileTreeStr = fileTreeStr.substring(0, 40000) + '\\n... [TREE TRUNCATED]';\n}\n\nconst keyPatterns = [\n /^main\\.py$/i,\n /^app\\.py$/i,\n /^index\\.(js|ts|tsx)$/i,\n /^server\\.(js|ts)$/i,\n /^package\\.json$/i,\n /^requirements\\.txt$/i,\n /^pyproject\\.toml$/i,\n /^Cargo\\.toml$/i,\n /^go\\.mod$/i,\n /^setup\\.py$/i,\n /^setup\\.cfg$/i,\n /^docker-compose\\.ya?ml$/i,\n /^Dockerfile$/i,\n /^Makefile$/i,\n /^config\\/.*\\.(ya?ml|json|toml)$/i,\n /^src\\/index\\.(js|ts|tsx)$/i,\n /^src\\/main\\.(py|js|ts|rs)$/i,\n /^src\\/app\\.(py|js|ts)$/i,\n /^\\.github\\/workflows\\/.*\\.ya?ml$/i,\n /^streamlit_app\\.py$/i,\n /^train.*\\.py$/i,\n /^model.*\\.py$/i,\n /^predict.*\\.py$/i,\n /^Pipfile$/i,\n /^environment\\.ya?ml$/i\n];\n\nconst keyFiles = filteredTree\n .filter(item => item.type === 'blob')\n .filter(item => keyPatterns.some(pattern => pattern.test(item.path)))\n .map(item => item.path)\n .slice(0, 12);\n\nconst totalFiles = filteredTree.filter(i => i.type === 'blob').length;\nconst totalDirs = filteredTree.filter(i => i.type === 'tree').length;\n\nif (keyFiles.length === 0) {\n return [{\n json: { owner, repo, filePath: null, fileTreeStr, totalFiles, totalDirs }\n }];\n}\n\nreturn keyFiles.map(filePath => ({\n json: { owner, repo, filePath, fileTreeStr, totalFiles, totalDirs }\n}));"
},
"typeVersion": 2
},
{
"id": "9ed95dfa-5a0d-4f76-ab11-e8a25f3fb18b",
"name": "Fetch Key File Contents",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1344,
208
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/{{ $json.filePath }}",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.v3+json"
},
{
"name": "User-Agent",
"value": "n8n-repo-blueprint"
}
]
},
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "076af1fe-6bfe-49ab-8500-cd1b2f3db975",
"name": "Prepare LLM Input",
"type": "n8n-nodes-base.code",
"position": [
-1088,
208
],
"parameters": {
"jsCode": "const items = $input.all();\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\nconst metadata = $('Fetch Repo Metadata').first().json;\nconst description = metadata.description || '';\nconst topics = (metadata.topics || []).join(', ');\nconst language = metadata.language || '';\nconst fileTreeStr = $('Identify Key Files').first().json.fileTreeStr;\nconst totalFiles = $('Identify Key Files').first().json.totalFiles;\nconst totalDirs = $('Identify Key Files').first().json.totalDirs;\n\nconst fileContents = items\n .filter(item => item.json.content && item.json.path)\n .map(item => {\n try {\n const decoded = Buffer.from(item.json.content, 'base64').toString('utf-8');\n const truncated = decoded.length > 3000\n ? decoded.substring(0, 3000) + '\\n... [TRUNCATED]'\n : decoded;\n return `--- FILE: ${item.json.path} ---\\n${truncated}\\n`;\n } catch(e) {\n return `--- FILE: ${item.json.path} --- [BINARY/UNREADABLE]\\n`;\n }\n })\n .join('\\n');\n\nconst prompt = `Repository: ${owner}/${repo}\\nDescription: ${description || 'No description provided'}\\nTopics: ${topics || 'None'}\\nPrimary Language: ${language || 'Unknown'}\\nTotal files: ${totalFiles} | Total directories: ${totalDirs}\\n\\n=== FULL FILE TREE ===\\n${fileTreeStr}\\n\\n=== KEY FILE CONTENTS ===\\n${fileContents}`;\n\nreturn [{\n json: {\n owner,\n repo,\n llmInput: prompt,\n fileTreeStr,\n totalFiles,\n totalDirs\n }\n}];"
},
"typeVersion": 2
},
{
"id": "b2f94c0e-b70b-4a2a-8cea-2a9863d78ce0",
"name": "Analyze Architecture",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
-816,
208
],
"parameters": {
"text": "={{ $json.llmInput }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a Senior Software Architect performing a forensic, evidence-only code analysis. You describe ONLY what exists in the repository evidence below. You NEVER speculate or assume.\n\nABSOLUTE RULES \u2014 VIOLATION MEANS FAILURE:\n1. ONLY reference technologies found in the file tree or file contents provided.\n2. Check dependency files (requirements.txt, package.json, Cargo.toml, go.mod, pyproject.toml) \u2014 list ONLY libraries found there.\n3. No Dockerfile in tree \u2192 DO NOT mention Docker.\n4. No .tf files in tree \u2192 DO NOT mention Terraform.\n5. No .github/workflows/ in tree \u2192 DO NOT mention CI/CD.\n6. Read entry-point files (main.py, app.py, index.js) to understand the project's ACTUAL purpose and domain.\n7. Every claim must trace to a specific file in the evidence.\n\nTOKEN EFFICIENCY: Concise. Bullets over paragraphs. No filler. Every sentence must add information.\n\nMERMAID SYNTAX RULES (violations break rendering):\n1. Node IDs: ONLY alphanumeric (A, B, SVC1). No special chars, spaces, or hyphens.\n2. Labels: ALWAYS in double quotes: A[\"Service\"].\n3. Reserved words (end, graph, subgraph, style, click, class, default): NEVER as node IDs.\n4. Edge labels in double quotes: A -->|\"data\"| B\n5. Every subgraph closes with end on its own line.\n6. Use flowchart TD (NOT graph TD).\n7. No emoji or unicode in Mermaid code.\n\nDark-theme hex styles:\n- Frontend: style ID fill:#1f6feb,stroke:#58a6ff,color:#fff\n- Backend: style ID fill:#238636,stroke:#3fb950,color:#fff\n- Database: style ID fill:#da3633,stroke:#f85149,color:#fff\n- External: style ID fill:#8b949e,stroke:#c9d1d9,color:#fff\n\nUse subgraph blocks to group by layer. Shapes: [\"Service\"] for services, [(\"Database\")] for databases.\n\nOUTPUT FORMAT (strict \u2014 nothing outside these sections):\n\n## Project Purpose\n[1-2 sentences: what this project does, with its specific domain, based on code evidence.]\n\n## Technical Stack\n- **Language**: [from file extensions]\n- **Framework**: [from dependency files ONLY]\n- **Key Dependencies**: [from requirements.txt/package.json/etc.]\n- **Infrastructure**: [ONLY if config files exist in tree \u2014 omit entire line if none]\n\n## Architecture Blueprint\n```mermaid\nflowchart TD\n[diagram reflecting ACTUAL file structure \u2014 subgraphs by layer]\n```\n\n## Request Flow\n```mermaid\nsequenceDiagram\n[based on ACTUAL code paths \u2014 min 3 participants]\n```\n\n## Evidence-Based Risks\n1. [Risk traceable to specific file/pattern]\n2. [Risk traceable to specific file/pattern]\n3. [Risk traceable to specific file/pattern]"
}
]
},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "ce51847f-7c5f-494f-975b-e8ea545cd50c",
"name": "Claude 3.5 Sonnet",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
-816,
432
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "claude-sonnet-4-5-20250929"
},
"options": {
"temperature": 0.1,
"maxTokensToSample": 3000
}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Fix Markdown",
"type": "n8n-nodes-base.code",
"position": [
-544,
208
],
"parameters": {
"jsCode": "const input = $input.first().json;\nlet md = input.text || '';\n\n// Fix: Ensure space after # headers\nmd = md.replace(/^(#{1,6})([^\\s#])/gm, '$1 $2');\n\n// Fix: Ensure blank line before headers\nmd = md.replace(/([^\\n])\\n(#{1,6}\\s)/g, '$1\\n\\n$2');\n\n// Fix: Ensure blank line before code blocks\nmd = md.replace(/([^\\n])\\n```/g, '$1\\n\\n```');\n\n// Fix: Ensure blank line after code blocks\nmd = md.replace(/```\\n([^\\n`])/g, '```\\n\\n$1');\n\n// Fix: Remove trailing whitespace on lines\nmd = md.replace(/[ \\t]+$/gm, '');\n\nreturn [{\n json: {\n ...input,\n text: md\n }\n}];"
},
"typeVersion": 2
},
{
"id": "18443356-0962-445c-9f53-daf3e95505ed",
"name": "Generate Dashboard HTML",
"type": "n8n-nodes-base.code",
"position": [
-272,
208
],
"parameters": {
"jsCode": "const analysisOutput = $input.first().json.text || '';\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\nconst description = $('Fetch Repo Metadata').first().json.description || '';\nconst totalFiles = $('Prepare LLM Input').first().json.totalFiles;\nconst totalDirs = $('Prepare LLM Input').first().json.totalDirs;\nconst defaultBranch = $('Fetch Repo Metadata').first().json.default_branch || 'main';\nconst now = new Date().toISOString().split('T')[0];\n\nconst mermaidBlocks = [];\nconst mermaidRegex = /```mermaid\\n([\\s\\S]*?)```/g;\nlet m;\nwhile ((m = mermaidRegex.exec(analysisOutput)) !== null) {\n mermaidBlocks.push(m[1].trim());\n}\n\nconst markdown = `# System Blueprint: ${owner}/${repo}\\n\\n> ${description || 'Architecture analysis'}\\n>\\n> Auto-generated on ${now} by Repo-to-Blueprint Architect\\n\\n${analysisOutput.trim()}\\n\\n---\\n\\n## Repository Stats\\n| Metric | Value |\\n|--------|-------|\\n| Total Files | ${totalFiles} |\\n| Total Directories | ${totalDirs} |\\n| Generated | ${now} |\\n| Source | [${owner}/${repo}](https://github.com/${owner}/${repo}) |\\n\\n---\\n\\n*Generated by Repo-to-Blueprint Architect via n8n*\\n`;\n\nconst mermaidPreview = mermaidBlocks.length > 0 ? mermaidBlocks[0].substring(0, 1500) : '[No diagram]';\n\nreturn [{\n json: {\n owner,\n repo,\n markdownContent: markdown,\n mermaidCode: mermaidPreview,\n diagramCount: mermaidBlocks.length,\n commitMessage: `docs: update system blueprint (${now})`,\n defaultBranch\n }\n}];"
},
"typeVersion": 2
},
{
"id": "5301aa8f-fce4-42e8-8334-3339e873dfc3",
"name": "Fetch Existing README",
"type": "n8n-nodes-base.httpRequest",
"position": [
0,
208
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/README_ARCH.md?ref={{ $json.defaultBranch }}",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.v3+json"
},
{
"name": "User-Agent",
"value": "n8n-repo-blueprint"
}
]
},
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "f006ed96-6ef9-4bc8-96bb-0fac76993db0",
"name": "Prepare Push Data",
"type": "n8n-nodes-base.code",
"position": [
272,
208
],
"parameters": {
"jsCode": "const dashData = $('Generate Dashboard HTML').first().json;\nconst existing = $input.first().json;\n\nconst content = Buffer.from(dashData.markdownContent).toString('base64');\n\nconst body = {\n message: dashData.commitMessage,\n content: content,\n branch: dashData.defaultBranch\n};\n\nif (existing.sha) {\n body.sha = existing.sha;\n}\n\nreturn [{\n json: {\n owner: dashData.owner,\n repo: dashData.repo,\n pushBodyStr: JSON.stringify(body),\n isUpdate: !!existing.sha,\n diagramCount: dashData.diagramCount,\n mermaidCode: dashData.mermaidCode\n }\n}];"
},
"typeVersion": 2
},
{
"id": "e5558bb5-6670-4824-864c-696360085f67",
"name": "Push README_ARCH.md",
"type": "n8n-nodes-base.httpRequest",
"position": [
544,
208
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/README_ARCH.md",
"method": "PUT",
"options": {},
"jsonBody": "={{ $json.pushBodyStr }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.github.v3+json"
},
{
"name": "User-Agent",
"value": "n8n-repo-blueprint"
}
]
},
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "f9b37d10-b08d-4689-9332-c3cdc1e0d2a0",
"name": "Notify on Update",
"type": "n8n-nodes-base.slack",
"position": [
816,
48
],
"parameters": {
"text": "=:{{ $('Prepare Push Data').first().json.isUpdate ? 'arrows_counterclockwise' : 'blueprint' }}: *System Blueprint {{ $('Prepare Push Data').first().json.isUpdate ? 'Updated' : 'Created' }}*\n\n*Repository:* <https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}|{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}>\n*Blueprint:* <https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/blob/{{ $('Generate Dashboard HTML').first().json.defaultBranch }}/README_ARCH.md|View README_ARCH.md>\n*Diagrams:* {{ $('Prepare Push Data').first().json.diagramCount }} generated\n*Stats:* {{ $('Prepare LLM Input').first().json.totalFiles }} files | {{ $('Prepare LLM Input').first().json.totalDirs }} dirs\n\n```{{ $('Prepare Push Data').first().json.mermaidCode }}```",
"select": "channel",
"resource": "message",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"operation": "post",
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4,
"continueOnFail": true
},
{
"id": "8e995431-419c-4d45-b349-368f72ec21c7",
"name": "Send Success Page",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1088,
48
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "text/html; charset=utf-8"
}
]
}
},
"respondWith": "text",
"responseBody": "=<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Blueprint Generated</title><style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#0d1117;color:#c9d1d9;display:flex;align-items:center;justify-content:center;min-height:100vh}.card{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:3rem;max-width:520px;text-align:center;box-shadow:0 8px 32px rgba(0,0,0,.4)}h1{color:#58a6ff;font-size:1.8rem;margin-bottom:1rem}.icon{font-size:3.5rem;margin-bottom:1rem}p{margin:.7rem 0;color:#8b949e;line-height:1.6}.repo{color:#c9d1d9;font-weight:600}.btn{display:inline-block;background:#238636;color:#fff;padding:.75rem 2rem;border-radius:8px;margin-top:1.5rem;font-size:1rem;text-decoration:none;transition:background .2s}.btn:hover{background:#2ea043}.footer{margin-top:2rem;font-size:.75rem;color:#484f58}</style></head><body><div class='card'><div class='icon'>✅</div><h1>Blueprint Generated!</h1><p>Architecture analysis complete for<br><span class='repo'>{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}</span></p><p>{{ $('Prepare Push Data').first().json.diagramCount }} diagram(s) generated and pushed.</p><a class='btn' href='https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/blob/{{ $('Generate Dashboard HTML').first().json.defaultBranch }}/README_ARCH.md' target='_blank'>View README_ARCH.md →</a><div class='footer'>Powered by Repo-to-Blueprint Architect</div></div></body></html>"
},
"typeVersion": 1.5
},
{
"id": "s0000000-0000-0000-0000-000000000000",
"name": "Sticky Note - Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2784,
-384
],
"parameters": {
"width": 3960,
"height": 416,
"content": "## How it works\n\nThis workflow analyzes any public GitHub repository and generates an evidence-based architecture blueprint with Mermaid.js diagrams.\n\n1. A GitHub URL is submitted via the web form or webhook API\n2. The workflow fetches repository metadata, the full file tree, and contents of key files (package.json, main.py, Dockerfiles, etc.)\n3. Claude AI (Sonnet 4.5, temperature 0.1) analyzes ONLY the evidence \u2014 strict anti-hallucination rules prevent it from inventing technologies not found in the code\n4. A Markdown blueprint with architecture diagrams and risk analysis is assembled, validated, and pushed as `README_ARCH.md` to the repository\n5. A Slack notification is sent and the form user receives a styled success page\n\n## Setup steps\n\n1. **GitHub API** \u2014 Create a Personal Access Token with `repo` scope. Add as \"GitHub API\" credential\n2. **Anthropic API** \u2014 Get an API key from console.anthropic.com. Add as \"Anthropic API\" credential\n3. **Slack** *(optional)* \u2014 Create a Slack Bot Token with `chat:write` scope. Add as \"Slack API\" credential and update the channel ID in the Notify node\n4. **Activate** \u2014 Toggle the workflow active. Use the Form URL in your browser or POST `{\"github_url\": \"https://github.com/owner/repo\"}` to the webhook"
},
"typeVersion": 1
},
{
"id": "s1000001-0000-0000-0000-000000000001",
"name": "Sticky Note - Input",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2816,
80
],
"parameters": {
"color": 6,
"width": 580,
"height": 560,
"content": "## Input\nTwo entry points: web form for browser users, webhook POST for API calls. Both feed into the URL parser."
},
"typeVersion": 1
},
{
"id": "s1000002-0000-0000-0000-000000000002",
"name": "Sticky Note - Evidence",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2208,
80
],
"parameters": {
"color": 6,
"width": 1292,
"height": 320,
"content": "## Evidence gathering\nFetches repo metadata, file tree, and key file contents. This evidence is the only input to the AI."
},
"typeVersion": 1
},
{
"id": "s1000003-0000-0000-0000-000000000003",
"name": "Sticky Note - AI",
"type": "n8n-nodes-base.stickyNote",
"position": [
-896,
80
],
"parameters": {
"color": 6,
"width": 588,
"height": 500,
"content": "## AI analysis\nClaude Sonnet 4.5 analyzes only what exists in the code. Anti-hallucination rules enforced. Markdown auto-fixed."
},
"typeVersion": 1
},
{
"id": "s1000004-0000-0000-0000-000000000004",
"name": "Sticky Note - Delivery",
"type": "n8n-nodes-base.stickyNote",
"position": [
-288,
48
],
"parameters": {
"color": 6,
"width": 1560,
"height": 352,
"content": "## Delivery\nAssembles blueprint, pushes to repo, notifies Slack, and returns a success page."
},
"typeVersion": 1
}
],
"settings": {
"executionOrder": "v1",
"saveExecutionProgress": true,
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all"
},
"connections": {
"Fix Markdown": {
"main": [
[
{
"node": "Generate Dashboard HTML",
"type": "main",
"index": 0
}
]
]
},
"Blueprint Form": {
"main": [
[
{
"node": "Parse Owner and Repo",
"type": "main",
"index": 0
}
]
]
},
"Fetch Repo Tree": {
"main": [
[
{
"node": "Identify Key Files",
"type": "main",
"index": 0
}
]
]
},
"Notify on Update": {
"main": [
[
{
"node": "Send Success Page",
"type": "main",
"index": 0
}
]
]
},
"Claude 3.5 Sonnet": {
"ai_languageModel": [
[
{
"node": "Analyze Architecture",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Prepare LLM Input": {
"main": [
[
{
"node": "Analyze Architecture",
"type": "main",
"index": 0
}
]
]
},
"Prepare Push Data": {
"main": [
[
{
"node": "Push README_ARCH.md",
"type": "main",
"index": 0
}
]
]
},
"Identify Key Files": {
"main": [
[
{
"node": "Fetch Key File Contents",
"type": "main",
"index": 0
}
]
]
},
"Receive GitHub URL": {
"main": [
[
{
"node": "Parse Owner and Repo",
"type": "main",
"index": 0
}
]
]
},
"Fetch Repo Metadata": {
"main": [
[
{
"node": "Fetch Repo Tree",
"type": "main",
"index": 0
}
]
]
},
"Push README_ARCH.md": {
"main": [
[
{
"node": "Notify on Update",
"type": "main",
"index": 0
}
]
]
},
"Analyze Architecture": {
"main": [
[
{
"node": "Fix Markdown",
"type": "main",
"index": 0
}
]
]
},
"Parse Owner and Repo": {
"main": [
[
{
"node": "Fetch Repo Metadata",
"type": "main",
"index": 0
}
]
]
},
"Fetch Existing README": {
"main": [
[
{
"node": "Prepare Push Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch Key File Contents": {
"main": [
[
{
"node": "Prepare LLM Input",
"type": "main",
"index": 0
}
]
]
},
"Generate Dashboard HTML": {
"main": [
[
{
"node": "Fetch Existing README",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
anthropicApigithubApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Requirements: GitHub API token ( scope), Anthropic API key (Claude Sonnet 4.5), Slack Bot Token (optional)
Source: https://n8n.io/workflows/13362/ — 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.
Content - Newsletter Agent. Uses formTrigger, chainLlm, outputParserStructured, httpRequest. Event-driven trigger; 87 nodes.
Content - Write Best Tools In Category Article. Uses formTrigger, httpRequest, slack, chainLlm. Event-driven trigger; 41 nodes.
This workflow automates the full machine learning lifecycle end-to-end using Claude AI as the intelligent decision-maker at every stage. Send one HTTP request with a dataset URL and a business goal —
Transform simple ideas into viral-ready Bigfoot vlogs! This automated workflow creates charming 8-scene video content featuring "Sam" the Bigfoot - a lovable, outdoorsy character inspired by popular Y
Automatically reads every reply to your cold email campaigns in Instantly.ai, uses Claude AI to understand the intent, and takes the right action . No need ofmanual inbox checking needed. A lead repli