{
  "id": "Y6oy5VN_oASw3lZR2RpMk",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Agent to respond to github repo issues",
  "tags": [],
  "nodes": [
    {
      "id": "1e461404-a788-40d5-8c41-e2f24e062cd0",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        272,
        624
      ],
      "parameters": {
        "options": {
          "temperature": 0.5
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3ff48ae4-f4a8-4ed4-a878-caf91b19338d",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        544,
        624
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"owner\": \"GitHub repository owner username\",\n\t\"repo\": \"GitHub repository name\",\n\t\"branch_name\": \"Source branch name for the pull request\",\n\t\"base_branch\": \"Target branch name (usually main or master)\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "a79a9efb-4269-44ad-a33b-3cb0d9f1a54b",
      "name": "Check for Repository error",
      "type": "n8n-nodes-base.if",
      "position": [
        992,
        272
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "335ff773-f79e-4c59-99bd-7f617bc00b06",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.message }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0c9f5f07-8059-48d7-aa97-9ea45d64dd8d",
      "name": "MCP Server Trigger for Github",
      "type": "@n8n/n8n-nodes-langchain.mcpTrigger",
      "position": [
        128,
        -352
      ],
      "parameters": {
        "path": "a2c1b2dd-32ed-463a-97c0-0f7139719c3c"
      },
      "typeVersion": 2
    },
    {
      "id": "c96743bb-f689-4aa4-a365-35c2b918b9be",
      "name": "create_github_pr",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        464,
        -80
      ],
      "parameters": {
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "Y6oy5VN_oASw3lZR2RpMk",
          "cachedResultUrl": "/workflow/Y6oy5VN_oASw3lZR2RpMk",
          "cachedResultName": "My workflow"
        },
        "description": "Creates a GitHub Pull Request. IMPORTANT: You must provide the full repository owner and name (e.g., 'AhmedSAAhmed/Example-Auth-service') even if you have a local git context, so the backend API can route the request correctly.",
        "workflowInputs": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8def05a1-46d6-42d7-8039-a25340c0438f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -720,
        -320
      ],
      "parameters": {
        "width": 576,
        "height": 800,
        "content": "## How it works\n\nA GitHub issue triggers the MCP server.\n\nMCP forwards the issue context to this workflow.\n\nRepository details are extracted using AI.\n\nCommits from the target branch are fetched.\n\nCommit messages are summarized into intent.\n\nAn LLM generates a PR title and description.\n\nA pull request is created via GitHub API.\n\n## Setup steps\n\nEnable MCP and connect it to your GitHub repo.\n\nConfigure GitHub API credentials with PR access.\n\nSet default base branch, for example main.\n\nConnect an LLM, such as Google Gemini.\n\nEnsure the sub-workflow is callable and active.\n\n## Customization\n\nModify prompts to align with your issue template.\n\nEnforce branch or naming rules before PR creation.\n\nAdd guards to skip draft or WIP issues."
      },
      "typeVersion": 1
    },
    {
      "id": "92915031-6779-4b8a-bef5-ba27acac07f5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 576,
        "content": "## MCP Issue Trigger\n\nListens for new or updated GitHub issues via MCP and starts the automation flow."
      },
      "typeVersion": 1
    },
    {
      "id": "89bb2592-02bd-4345-ae79-39bd4f8862a5",
      "name": "Subworkflow Entry Point",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -16,
        368
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "336cb283-c4ff-4c00-852e-d8d8a0ab1ed3",
      "name": "Extract Repo & Branch Context",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        320,
        368
      ],
      "parameters": {
        "text": "You are a data extraction assistant. Your task is to extract structured repository information from natural language queries about GitHub pull requests. Always provide all four fields: owner, repo, branch_name, and base_branch. Use the defaults provided when information is not explicitly mentioned in the query.",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "7f6cb32c-7363-4fa4-b01f-55ca9ee4344d",
      "name": "Fetch GitHub Issues",
      "type": "n8n-nodes-base.githubTool",
      "position": [
        112,
        -80
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "url",
          "value": "https://github.com/AhmedSAAhmed"
        },
        "resource": "repository",
        "returnAll": true,
        "repository": {
          "__rl": true,
          "mode": "url",
          "value": "https://github.com/AhmedSAAhmed/Dog-Classifier-CNN"
        },
        "authentication": "oAuth2",
        "descriptionType": "manual",
        "toolDescription": "Fetch GitHub issue details including the full comment thread, so Cursor can understand complete context and requirements from discussions.",
        "getRepositoryIssuesFilters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c4a0643f-433f-440e-a37b-edfe2ebd7c34",
      "name": "Repo or Branch Validation",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        784,
        368
      ],
      "parameters": {
        "url": "={{ 'https://api.github.com/repos/' + $json.output.owner + '/' + $json.output.repo + '/commits' }}",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "sha",
              "value": "={{ $json.output.branch_name }}"
            }
          ]
        },
        "nodeCredentialType": "githubApi"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "a2d1a0b6-f3d4-4dc1-83d2-9c68b05b89e6",
      "name": "Build Error Response",
      "type": "n8n-nodes-base.set",
      "position": [
        1424,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a2b9ef40-b4b2-41f6-b038-1d0a800fd3fa",
              "name": "result",
              "type": "string",
              "value": "=Error: I couldn't find the repository \"{{ $('Extract Repository Info').item.json.output.owner }}/{{ $('Extract Repository Info').item.json.output.repo }}\" or branch \"{{ $('Extract Repository Info').item.json.output.branch_name }}\". Please double-check the spelling or ensure the repo is public and the branch exists."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8703f716-6780-44ed-a195-c71e7ce3658c",
      "name": "Prepare PR Payload",
      "type": "n8n-nodes-base.set",
      "position": [
        1424,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9f397f03-26a2-4561-ad25-0251a43c21f3",
              "name": "owner",
              "type": "string",
              "value": "={{ $('Extract Repository Info').item.json.output.owner }}"
            },
            {
              "id": "a19746d8-c346-4c32-a2b5-91035fed234e",
              "name": "repo",
              "type": "string",
              "value": "={{ $('Extract Repository Info').item.json.output.repo }}"
            },
            {
              "id": "5425ce9e-24fa-4680-bd5c-a1e4955dfa56",
              "name": "branch_name",
              "type": "string",
              "value": "={{ $('Extract Repository Info').item.json.output.branch_name }}"
            },
            {
              "id": "3f5ae6c9-9d61-424a-9e31-dc29d35bd195",
              "name": "base_branch",
              "type": "string",
              "value": "={{ $('Extract Repository Info').item.json.output.base_branch }}"
            },
            {
              "id": "11cd1a81-d84d-4138-9c5c-d11a6231e7ff",
              "name": "message",
              "type": "string",
              "value": "={{ $json.commit.message }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e66b73c9-e51b-4db2-a63f-d665f152e516",
      "name": "Create Pull Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2192,
        288
      ],
      "parameters": {
        "url": "={{ 'https://api.github.com/repos/' + $('Extract Repository Info').item.json.output.owner + '/' + $('Extract Repository Info').item.json.output.repo + '/pulls' }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "title",
              "value": "={{ $('Generate PR Title & Description').item.json.text.split('Title:')[1].split('Description:')[0].trim() }}"
            },
            {
              "name": "head",
              "value": "={{ $('Extract Repository Info').item.json.output.branch_name }}"
            },
            {
              "name": "base",
              "value": "={{ $('Extract Repository Info').item.json.output.base_branch }}"
            },
            {
              "name": "body",
              "value": "={{ $('Generate PR Title & Description').item.json.text.split('Description:')[1].trim() }}"
            }
          ]
        },
        "nodeCredentialType": "githubApi"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "5607aebb-6cb5-43e3-8c3a-8034bca002c1",
      "name": "Generate PR Title & Description",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1840,
        288
      ],
      "parameters": {
        "text": "=Here are all the commit messages for this branch:\n{{ $('summarize_commits').first().json.concatenated_message }}\n\nPlease write a professional Pull Request:\n1. A Title that summarizes the overall goal of these changes (max 72 characters).\n2. A Description that lists the key changes in bullet points.\n\nIMPORTANT: Return ONLY plain text without any markdown formatting. Do not use asterisks (**), bold, italics, or any other markdown syntax.\n\nFormat your response as:\nTitle: [your title here]\nDescription:\n[your description here]",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "d32a4f90-f1f7-46a6-a64e-643ce2711624",
      "name": "Aggregate Commit Messages",
      "type": "n8n-nodes-base.summarize",
      "position": [
        1632,
        288
      ],
      "parameters": {
        "options": {},
        "fieldsToSummarize": {
          "values": [
            {
              "field": "message",
              "separateBy": "\n",
              "aggregation": "concatenate"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "e08a9e7a-7a99-4278-b80d-4c60fae0dbdb",
      "name": "LLM PR Writer Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1936,
        480
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ab4b402d-e845-4dfa-84da-ae6d02956754",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 1184,
        "height": 608,
        "content": "## Context & Intelligence\n\nReceives data from MCP, extracts repository and branch context, fetches commits, and prepares structured input for AI reasoning."
      },
      "typeVersion": 1
    },
    {
      "id": "55f95864-7bf0-48aa-b47f-3bf315649e9f",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 1232,
        "height": 608,
        "content": "## PR Generation & Execution\n\nTransforms commit context into a PR title and description, validates output, and creates the pull request via GitHub API."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "a5e92d5b-f4e0-43de-acce-d71e4d849e24",
  "connections": {
    "create_github_pr": {
      "ai_tool": [
        [
          {
            "node": "MCP Server Trigger for Github",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Fetch GitHub Issues": {
      "ai_tool": [
        [
          {
            "node": "MCP Server Trigger for Github",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "LLM PR Writer Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate PR Title & Description",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Build Error Response": {
      "main": [
        [
          {
            "node": "Aggregate Commit Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Subworkflow Entry Point": {
      "main": [
        [
          {
            "node": "Extract Repo & Branch Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Extract Repo & Branch Context",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Extract Repo & Branch Context",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Commit Messages": {
      "main": [
        [
          {
            "node": "Generate PR Title & Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Repo or Branch Validation": {
      "main": [
        [
          {
            "node": "Check for Repository error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Repository error": {
      "main": [
        [
          {
            "node": "Prepare PR Payload",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Repo & Branch Context": {
      "main": [
        [
          {
            "node": "Repo or Branch Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate PR Title & Description": {
      "main": [
        [
          {
            "node": "Create Pull Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}