{
  "nodes": [
    {
      "id": "4da746fd-039b-4ef9-852d-452c85395737",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2144,
        1392
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-5.2"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "f43ee019-a741-48b5-9ef6-e2f1215019c4",
      "name": "MCP Client",
      "type": "n8n-nodes-mcp.mcpClientTool",
      "position": [
        2320,
        1392
      ],
      "parameters": {},
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "2e4272a3-565c-47ce-921a-626f115c384a",
      "name": "\ud83d\udd52 Trigger: Run Daily/Weekly",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1680,
        1120
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ce2dfc65-306b-4cdf-a454-02256a2ca77b",
      "name": "\ud83d\udcdd Input: Keyword & Domain",
      "type": "n8n-nodes-base.set",
      "position": [
        1888,
        1120
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "95b1399f-4709-46e0-89a9-cbf17ce9c06c",
              "name": "keyword",
              "type": "string",
              "value": "best running shoes"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8c2ea3aa-7e92-4b65-a8fe-5c30887f09aa",
      "name": "\ud83e\udd16 SERP Scraper Agent (MCP)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2160,
        1120
      ],
      "parameters": {
        "text": "=Based on the following keyword, provide me ranking of the 1st 5 website.\nkeyword: {{ $json.keyword }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "43cb6ff6-db25-480d-aa0d-a56c3c22c3e9",
      "name": "\ud83e\udde0 Format SERP Results",
      "type": "n8n-nodes-base.code",
      "position": [
        2640,
        1120
      ],
      "parameters": {
        "jsCode": "// Get the SERP list from the incoming item\nconst serpList = items[0].json.output;\n\n// Emit each result as a separate item\nreturn serpList.map(result => {\n  return {\n    json: result\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "62ad8ab7-3f3a-41f8-b4af-24638a3b8597",
      "name": "\ud83d\udcca Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2864,
        1120
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $json.url }}",
            "Rank": "={{ $json.rank }}",
            "Title": "={{ $json.title }}",
            "Description": "={{ $json.description }}"
          },
          "schema": [
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rank",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Rank",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p64unH_JjzG978cAxPZC4kSZmoXgvYTA-Q7qdfnxr8Y/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1p64unH_JjzG978cAxPZC4kSZmoXgvYTA-Q7qdfnxr8Y",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p64unH_JjzG978cAxPZC4kSZmoXgvYTA-Q7qdfnxr8Y/edit?usp=drivesdk",
          "cachedResultName": "Website Ranking"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "a8822139-bda2-4899-9f2e-a378e50ea41f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1664,
        0
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 1320,
        "content": "## \ud83d\udfe6 **Section 1: Input & Trigger Configuration**\n\n### \ud83d\udd52 **Trigger: Run Daily/Weekly**\n\n\ud83d\udd27 **Node Name:** `Trigger: Run Daily/Weekly`\n\ud83d\udca1 **What it does:**\nThis node automatically starts your workflow on a set schedule. You can run it:\n\n* Daily to monitor SEO fluctuations\n* Weekly to track long-term trends\n\n\ud83d\udccc **Why it's useful:**\nNo manual work is needed. Just set it once and it keeps your ranking logs up to date.\n\n---\n\n### \ud83d\udcdd **Input: Keyword & Domain**\n\n\ud83d\udd27 **Node Name:** `Input: Keyword & Domain`\n\ud83d\udca1 **What it does:**\nHere you provide the **search keyword** (like `\"best running shoes\"`) and optionally the **domain name** (like `\"yourwebsite.com\"`) to monitor.\n\n\ud83d\udccc **Why it's useful:**\nYou can change or extend keywords anytime without changing the rest of the workflow. Great for campaign flexibility.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "41f47cd9-fb56-49fb-9186-a4375cdb15ff",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        48
      ],
      "parameters": {
        "color": 3,
        "width": 340,
        "height": 1280,
        "content": "## \ud83d\udfe8 **Section 2: Smart SERP Scraping with AI Agent**\n\n### \ud83e\udd16 **SERP Scraper Agent (MCP)**\n\n\ud83d\udd27 **Node Name:** `SERP Scraper Agent (MCP)`\n\ud83d\udca1 **What it does:**\nThis is your smart agent that uses **Bright Data's MCP (Mobile Carrier Proxy)** to simulate real user behavior and scrape **Google Search Results** accurately.\n\nIt connects to:\n\n#### \ud83e\udde0 **AI Brain**\n\n\ud83d\udd27 **Sub-node:** `OpenAI Chat Model`\n\ud83c\udfaf Understands the keyword, crafts a natural query prompt, and makes sure the search context is accurate.\n\n#### \ud83c\udf10 **MCP SERP Fetcher**\n\n\ud83d\udd27 **Sub-node:** `MCP Client`\n\ud83d\udef0\ufe0f Actually performs the search on Google and fetches the **top 5 results** anonymously through real mobile-like connections (bypassing CAPTCHAs & blocks).\n\n#### \ud83e\uddfe **SERP Output Formatter**\n\n\ud83d\udd27 **Sub-node:** `Structured Output Parser`\n\ud83e\uddf9 Cleans up the scraped data and structures it into useful fields:\n\n* `rank`\n* `title`\n* `url`\n* `description`\n\n\ud83d\udccc **Why it's useful:**\nTraditional scrapers break often. This smart setup ensures highly accurate, undetectable scraping that adapts to changes in search results.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f4e02404-0d7f-4393-a9cc-4d0c90fa4779",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2608,
        224
      ],
      "parameters": {
        "color": 5,
        "width": 400,
        "height": 1100,
        "content": "## \ud83d\udfe9 **Section 3: Rank Logging and Reporting**\n\n### \ud83e\udde0 **Parse SERP Results**\n\n\ud83d\udd27 **Node Name:** `Parse SERP Results`\n\ud83d\udca1 **What it does:**\nThis **Code node** takes the structured list of top 5 results and **splits them into individual records**, one per website.\n\n\ud83d\udccc **Why it's useful:**\nIt prepares the data so each row can be logged separately in your spreadsheet, which makes filtering, charting, and comparison super easy.\n\n---\n\n### \ud83d\udcca **Log to Google Sheets**\n\n\ud83d\udd27 **Node Name:** `Log to Google Sheets`\n\ud83d\udca1 **What it does:**\nAppends each parsed search result (rank, title, URL, description) into your tracking spreadsheet.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "112fbd74-4180-463f-9e5c-1f0cca9e6a29",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3104,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 240,
        "content": "## I\u2019ll receive a tiny commission if you join Bright Data through this link\u2014thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"
      },
      "typeVersion": 1
    },
    {
      "id": "5b0903aa-8610-4c56-9f50-705c398059f7",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 4,
        "width": 1300,
        "height": 320,
        "content": "=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
      },
      "typeVersion": 1
    },
    {
      "id": "86659e9f-049a-444f-9a23-a8cf43ba9fe3",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        352
      ],
      "parameters": {
        "color": 4,
        "width": 1289,
        "height": 2558,
        "content": "## \ud83d\udd0d **Workflow: Monitor Keyword Rankings with AI & Bright Data MCP**\n\nTrack where your website ranks on Google for specific keywords, using AI-powered scraping and structured logging in Google Sheets.\n\n---\n\n## \ud83d\udfe6 **Section 1: Input & Trigger Configuration**\n\n### \ud83d\udd52 **Trigger: Run Daily/Weekly**\n\n\ud83d\udd27 **Node Name:** `Trigger: Run Daily/Weekly`\n\ud83d\udca1 **What it does:**\nThis node automatically starts your workflow on a set schedule. You can run it:\n\n* Daily to monitor SEO fluctuations\n* Weekly to track long-term trends\n\n\ud83d\udccc **Why it's useful:**\nNo manual work is needed. Just set it once and it keeps your ranking logs up to date.\n\n---\n\n### \ud83d\udcdd **Input: Keyword & Domain**\n\n\ud83d\udd27 **Node Name:** `Input: Keyword & Domain`\n\ud83d\udca1 **What it does:**\nHere you provide the **search keyword** (like `\"best running shoes\"`) and optionally the **domain name** (like `\"yourwebsite.com\"`) to monitor.\n\n\ud83d\udccc **Why it's useful:**\nYou can change or extend keywords anytime without changing the rest of the workflow. Great for campaign flexibility.\n\n---\n\n## \ud83d\udfe8 **Section 2: Smart SERP Scraping with AI Agent**\n\n### \ud83e\udd16 **SERP Scraper Agent (MCP)**\n\n\ud83d\udd27 **Node Name:** `SERP Scraper Agent (MCP)`\n\ud83d\udca1 **What it does:**\nThis is your smart agent that uses **Bright Data's MCP (Mobile Carrier Proxy)** to simulate real user behavior and scrape **Google Search Results** accurately.\n\nIt connects to:\n\n#### \ud83e\udde0 **AI Brain**\n\n\ud83d\udd27 **Sub-node:** `OpenAI Chat Model`\n\ud83c\udfaf Understands the keyword, crafts a natural query prompt, and makes sure the search context is accurate.\n\n#### \ud83c\udf10 **MCP SERP Fetcher**\n\n\ud83d\udd27 **Sub-node:** `MCP Client`\n\ud83d\udef0\ufe0f Actually performs the search on Google and fetches the **top 5 results** anonymously through real mobile-like connections (bypassing CAPTCHAs & blocks).\n\n#### \ud83e\uddfe **SERP Output Formatter**\n\n\ud83d\udd27 **Sub-node:** `Structured Output Parser`\n\ud83e\uddf9 Cleans up the scraped data and structures it into useful fields:\n\n* `rank`\n* `title`\n* `url`\n* `description`\n\n\ud83d\udccc **Why it's useful:**\nTraditional scrapers break often. This smart setup ensures highly accurate, undetectable scraping that adapts to changes in search results.\n\n---\n\n## \ud83d\udfe9 **Section 3: Rank Logging and Reporting**\n\n### \ud83e\udde0 **Parse SERP Results**\n\n\ud83d\udd27 **Node Name:** `Parse SERP Results`\n\ud83d\udca1 **What it does:**\nThis **Code node** takes the structured list of top 5 results and **splits them into individual records**, one per website.\n\n\ud83d\udccc **Why it's useful:**\nIt prepares the data so each row can be logged separately in your spreadsheet, which makes filtering, charting, and comparison super easy.\n\n---\n\n### \ud83d\udcca **Log to Google Sheets**\n\n\ud83d\udd27 **Node Name:** `Log to Google Sheets`\n\ud83d\udca1 **What it does:**\nAppends each parsed search result (rank, title, URL, description) into your tracking spreadsheet.\n\n\ud83d\udccc **Why it's useful:**\nYou now have a full historical record of how rankings change day by day, week by week. This is great for:\n\n* SEO audits\n* Campaign reporting\n* Alerting when a competitor outranks you\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8901fcde-42d7-4c71-a5b0-7d43a445819e",
      "name": "Auto-fixing Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
      "position": [
        2448,
        1392
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "8ee47ad5-5035-446a-8dc8-7839b6e1e099",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2432,
        1600
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-5.2"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "6f2f0d2b-4aa2-41fc-9cb3-97072108b018",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2592,
        1600
      ],
      "parameters": {
        "jsonSchemaExample": "[\n  {\n    \"rank\": 1,\n    \"title\": \"Runner's World\",\n    \"url\": \"https://www.runnersworld.com/gear/a19663621/best-running-shoes/\",\n    \"description\": \"A comprehensive guide on the best running shoes, recommending models like Brooks Ghost and Nike Pegasus for new runners.\"\n  },\n  {\n    \"rank\": 2,\n    \"title\": \"RunRepeat\",\n    \"url\": \"https://runrepeat.com/catalog/running-shoes\",\n    \"description\": \"Offers running shoe reviews with ratings for various models such as Nike Pegasus 41 and Hoka Mach 6.\"\n  },\n  {\n    \"rank\": 3,\n    \"title\": \"Believe in the Run\",\n    \"url\": \"https://believeintherun.com/shoe-reviews/best-running-shoes-2025/\",\n    \"description\": \"Features an in-depth guide to the best running shoes of 2025 across different categories.\"\n  },\n  {\n    \"rank\": 4,\n    \"title\": \"The Run Testers\",\n    \"url\": \"https://theruntesters.com/running-shoes/the-best-running-shoes-to-buy/\",\n    \"description\": \"Reviews the best running shoes available, highlighting their performance and value.\"\n  },\n  {\n    \"rank\": 5,\n    \"title\": \"Men's Health\",\n    \"url\": \"https://www.menshealth.com/fitness/a64476227/running-shoes-editors-picks/\",\n    \"description\": \"Provides a selection of top running shoes recommended by Men's Health editors.\"\n  }\n]\n"
      },
      "typeVersion": 1.2
    }
  ],
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "\ud83e\udd16 SERP Scraper Agent (MCP)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udde0 Format SERP Results": {
      "main": [
        [
          {
            "node": "\ud83d\udcca Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Auto-fixing Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "\ud83e\udd16 SERP Scraper Agent (MCP)",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Input: Keyword & Domain": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 SERP Scraper Agent (MCP)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 SERP Scraper Agent (MCP)": {
      "main": [
        [
          {
            "node": "\ud83e\udde0 Format SERP Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd52 Trigger: Run Daily/Weekly": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Input: Keyword & Domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}