{
  "id": "4Q8wkpV1YDNRwsQC",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Google Search Console MCP",
  "tags": [
    {
      "id": "1o9SYcsyY3Rtn8Dj",
      "name": "gsc-mcp",
      "createdAt": "2026-07-25T12:15:20.667Z",
      "updatedAt": "2026-07-25T12:15:20.667Z"
    }
  ],
  "nodes": [
    {
      "id": "a47fb8a7-dc6e-4119-91a8-3ddf8a639f22",
      "name": "GSC MCP Server",
      "type": "@n8n/n8n-nodes-langchain.mcpTrigger",
      "position": [
        -432,
        -3168
      ],
      "parameters": {
        "path": "gsc-mcp"
      },
      "typeVersion": 2
    },
    {
      "id": "d5a2659a-1156-4ae7-9fde-4527022fc912",
      "name": "gsc_list_sites",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -2080,
        -2176
      ],
      "parameters": {
        "url": "https://www.googleapis.com/webmasters/v3/sites",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "List all Google Search Console properties (sites) the connected account can access. Returns each property URL and its permission level. Takes no input.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "9e8683b3-fce6-4a3f-bb98-e84863abb5dd",
      "name": "gsc_query_search_analytics",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        1184,
        -2144
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/ or sc-domain:example.com\")) }}/searchAnalytics/query",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ (function(){ var dims = ($fromAI(\"dimensions\", \"Comma-separated dimensions to group by (query, page, country, device, date, searchAppearance). Empty = totals only.\") || \"\").split(\",\").map(function(s){ return s.trim(); }).filter(function(x){ return x; }); var body = { startDate: $fromAI(\"startDate\", \"Start date YYYY-MM-DD\"), endDate: $fromAI(\"endDate\", \"End date YYYY-MM-DD\"), rowLimit: Number($fromAI(\"rowLimit\", \"Max rows to return, default 25, max 25000 - keep small to save tokens\", \"number\")) || 25, startRow: Number($fromAI(\"startRow\", \"Row offset for pagination, default 0\", \"number\")) || 0, dataState: \"final\" }; if (dims.length) { body.dimensions = dims; } var fd = $fromAI(\"filterDimension\", \"Optional server-side filter dimension: query, page, country, or device (empty for none)\"); var fe = $fromAI(\"filterExpression\", \"Optional filter value to match, used with filterDimension\"); if (fd && fe) { var op = $fromAI(\"filterOperator\", \"Filter operator: contains, equals, notContains, includingRegex, excludingRegex (default contains)\") || \"contains\"; body.dimensionFilterGroups = [{ filters: [{ dimension: fd, operator: op, expression: fe }] }]; } return JSON.stringify(body); })() }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "Query Google Search Console Search Analytics. Returns clicks, impressions, CTR, avg position. Inputs: siteUrl; startDate & endDate (YYYY-MM-DD); dimensions (comma-separated: query, page, country, device, date, searchAppearance; empty = totals); rowLimit (default 25 - keep small to save tokens); startRow (paging offset). OPTIONAL server-side filter: set filterDimension (query/page/country/device) + filterExpression + filterOperator (contains/equals/notContains/includingRegex/excludingRegex) so Google returns only matching rows (e.g. brand queries, or one page's queries). NOTE: Google CANNOT filter by position/CTR/impressions (metrics) - to find e.g. position 10-20 or low CTR, request the rows and filter them in your own analysis.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "9f83b9c5-be6e-4afb-a46f-c6ead5e57f58",
      "name": "gsc_inspect_url",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        912,
        -2144
      ],
      "parameters": {
        "url": "https://searchconsole.googleapis.com/v1/urlInspection/index:inspect",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ inspectionUrl: $fromAI(\"inspectionUrl\", \"The fully-qualified URL to inspect, e.g. https://example.com/page\"), siteUrl: $fromAI(\"siteUrl\", \"The GSC property the URL belongs to, e.g. https://example.com/ or sc-domain:example.com\") }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "Inspect a URL with the Google Search Console URL Inspection API. Returns index status, coverage state, last crawl time, canonical URLs, mobile usability and rich-results verdicts.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "afddb4e1-8bc2-4b9b-8b27-5a426f0c129d",
      "name": "gsc_get_site",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1952,
        -2176
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/ or sc-domain:example.com\")) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "Get details for a single Google Search Console property, including the account's permission level. Input: siteUrl.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "b0428ca0-a1a1-4742-a914-fe76da54fd18",
      "name": "gsc_add_site",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1824,
        -2176
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property to add, e.g. https://example.com/ or sc-domain:example.com\")) }}",
        "method": "PUT",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE: Add (and begin verification of) a property in Google Search Console. Input: siteUrl. Requires write permission on the account.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "aa25facd-4f88-4d49-99cb-6e3d85f7fd95",
      "name": "gsc_delete_site",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1696,
        -2176
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property to remove, e.g. https://example.com/ or sc-domain:example.com\")) }}",
        "method": "DELETE",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE: Remove a property from this Search Console account. Input: siteUrl. Removes the account's access to the property.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "82c25b62-1fa7-491a-ad88-8fe55ff2d7b8",
      "name": "gsc_list_sitemaps",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -496,
        -2112
      ],
      "parameters": {
        "url": "={{ (function(){ var si = $fromAI(\"sitemapIndex\", \"Optional. A sitemap INDEX url (e.g. https://example.com/sitemap_index.xml) to list ITS child sitemaps. Leave empty to list the property's top-level sitemaps.\"); var base = \"https://www.googleapis.com/webmasters/v3/sites/\" + encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/ or sc-domain:example.com\")) + \"/sitemaps\"; return si ? base + \"?sitemapIndex=\" + encodeURIComponent(si) : base; })() }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "List sitemaps for a property. Call with only siteUrl to get top-level sitemaps (each sitemap index + its status: errors, warnings, lastDownloaded, contents). To get the CHILD/sub-sitemaps of an index, call again with sitemapIndex set to that index's URL. Combine both to present the full main+children tree with per-sitemap status.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "d8b1debc-8886-42ed-a901-e6784b1b7341",
      "name": "gsc_get_sitemap",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -336,
        -2112
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/\")) }}/sitemaps/{{ encodeURIComponent($fromAI(\"sitemapUrl\", \"Full sitemap URL, e.g. https://example.com/sitemap.xml\")) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "Get details for one submitted sitemap (status, contents, errors, warnings). Inputs: siteUrl, sitemapUrl (full sitemap URL).",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "48b380c3-b94f-476e-8723-a374d883bbaa",
      "name": "gsc_submit_sitemap",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -176,
        -2112
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/\")) }}/sitemaps/{{ encodeURIComponent($fromAI(\"sitemapUrl\", \"Full sitemap URL to submit, e.g. https://example.com/sitemap.xml\")) }}",
        "method": "PUT",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE: Submit a sitemap to Google for a property. Inputs: siteUrl, sitemapUrl. Works for both the main sitemap index AND individual child/sub-sitemaps. Re-submitting an existing sitemap is safe and idempotent, and forces a fresh crawl.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "458b5060-c0a5-4661-b408-749f21adad97",
      "name": "gsc_delete_sitemap",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        0,
        -2112
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($fromAI(\"siteUrl\", \"The GSC property, e.g. https://example.com/\")) }}/sitemaps/{{ encodeURIComponent($fromAI(\"sitemapUrl\", \"Full sitemap URL to delete, e.g. https://example.com/sitemap.xml\")) }}",
        "method": "DELETE",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE: Remove a submitted sitemap (index OR child/sub-sitemap) from a property. Inputs: siteUrl, sitemapUrl. PROTOCOL: before deleting, first call gsc_list_sitemaps (and drill into the index for its children) to show the user what exists, then confirm the exact sitemapUrl to delete. Note: deleting a child still referenced by the sitemap index may be re-discovered by Google on the next index read.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "f58f8319-9b11-452b-835d-701b096da8d8",
      "name": "gsc_indexing_publish",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        224,
        -2144
      ],
      "parameters": {
        "url": "https://indexing.googleapis.com/v3/urlNotifications:publish",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ url: $fromAI(\"url\", \"The URL to notify Google about\"), type: $fromAI(\"type\", \"Notification type: URL_UPDATED or URL_DELETED\") }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE: Notify Google (Indexing API) that a URL was updated or deleted. Inputs: url, type (URL_UPDATED or URL_DELETED). Requires the Indexing API enabled and the service account added as an Owner of the property.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "39457f00-a289-4ffc-8620-3292e1d5e7fc",
      "name": "gsc_indexing_get_metadata",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        608,
        -2144
      ],
      "parameters": {
        "url": "=https://indexing.googleapis.com/v3/urlNotifications/metadata?url={{ encodeURIComponent($fromAI(\"url\", \"The URL to check indexing metadata for\")) }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "Get the latest Indexing API notification metadata for a URL (the last update/delete Google received). Input: url. Requires the Indexing API enabled and the service account added as an Owner.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "4452e20a-476e-4250-8b5c-e630a07ba1ef",
      "name": "gsc_indexing_batch_publish",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        416,
        -2144
      ],
      "parameters": {
        "url": "https://indexing.googleapis.com/batch",
        "body": "={{ (function(){ var b = \"gsc_batch_boundary\"; var NL = String.fromCharCode(13,10); var t = $fromAI(\"type\", \"Notification type applied to ALL urls: URL_UPDATED (new/changed page) or URL_DELETED (removed page)\"); var urls = ($fromAI(\"urls\", \"Comma-separated list of URLs to notify Google about (max 100)\") || \"\").split(\",\").map(function(s){ return s.trim(); }).filter(function(x){ return x; }); var parts = urls.map(function(u, i){ var payload = JSON.stringify({ url: u, type: t }); return \"--\" + b + NL + \"Content-Type: application/http\" + NL + \"Content-ID: <item\" + (i + 1) + \">\" + NL + NL + \"POST /v3/urlNotifications:publish\" + NL + \"Content-Type: application/json\" + NL + NL + payload + NL; }); return parts.join(\"\") + \"--\" + b + \"--\"; })() }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "raw",
        "authentication": "predefinedCredentialType",
        "rawContentType": "multipart/mixed; boundary=gsc_batch_boundary",
        "toolDescription": "WRITE (bulk): Notify Google's Indexing API about MANY URLs at once (up to 100) in one batch request. Inputs: urls (comma-separated list of URLs, max 100) and type (URL_UPDATED for new/changed pages, or URL_DELETED to remove). Requires the Indexing API enabled + the service account as a property Owner. Note: the Indexing API is officially intended for JobPosting/BroadcastEvent pages.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "74705130-0764-4b03-bffe-b7d5523ab57d",
      "name": "gsc_get_verification_token",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1536,
        -2176
      ],
      "parameters": {
        "url": "https://www.googleapis.com/siteVerification/v1/token",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ verificationMethod: $fromAI(\"method\", \"Verification method: FILE, META, or DNS_TXT\"), site: { type: $fromAI(\"siteType\", \"SITE for a URL-prefix property (https://example.com/), or INET_DOMAIN for a domain property (example.com)\"), identifier: $fromAI(\"identifier\", \"Site identifier: full URL ending in / for SITE, or bare domain for INET_DOMAIN\") } }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "Get a Google site-ownership verification token. Inputs: siteType (SITE = URL-prefix like https://example.com/ ; INET_DOMAIN = domain like example.com), identifier, method. METHOD RULES: INET_DOMAIN (domain) supports ONLY DNS_TXT; SITE (URL-prefix) supports META, FILE, or DNS_TXT. Returns {method, token}. Where the user must place it: DNS_TXT -> add as a DNS TXT record on the domain (NOT the page head); META -> paste the returned meta tag into the homepage <head>; FILE -> upload an HTML file named/containing the token at the site root. After it is placed, call verify_site with the SAME siteType, identifier and method.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "78fd614d-e617-4591-ab7a-9c1ca3525001",
      "name": "gsc_verify_site",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1376,
        -2176
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/siteVerification/v1/webResource?verificationMethod={{ encodeURIComponent($fromAI(\"method\", \"The SAME verification method used with get_verification_token: FILE, META, or DNS_TXT\")) }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ site: { type: $fromAI(\"siteType\", \"SITE or INET_DOMAIN\"), identifier: $fromAI(\"identifier\", \"Full URL ending in / for SITE, or bare domain for INET_DOMAIN\") } }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "Verify site ownership AFTER the token (from get_verification_token) has been placed on the site. Inputs: siteType (SITE or INET_DOMAIN), identifier, method (the SAME method used for get_verification_token; remember INET_DOMAIN supports only DNS_TXT). On success the SERVICE ACCOUNT becomes a verified owner -- this is for AUTOMATION (lets this MCP operate on the site, including the Indexing API). It does NOT give any human dashboard access; a person must add/verify themselves in the Search Console UI. Returns the webResource {id, site, owners}.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "d3e42946-c3f3-410e-bde7-0c4043fa1494",
      "name": "gsc_list_owners",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -1072,
        -2160
      ],
      "parameters": {
        "url": "https://www.googleapis.com/siteVerification/v1/webResource",
        "options": {},
        "authentication": "predefinedCredentialType",
        "toolDescription": "List the VERIFICATION owners of each site/domain the service account has verified. This is Google's site-OWNERSHIP list, which is NOT the same as Search Console 'Users and permissions'. Returns each property's owners plus its webResource id. ALWAYS call this before set_owners to get the exact id and the CURRENT complete owners list. Also use it to confirm the service account is an owner of a site (required for the Indexing API). NOTE: Search Console Full/Restricted USERS cannot be listed via any API -- this returns verification owners only.",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "c2c67e97-68b8-47b8-91fa-8663f445b1da",
      "name": "gsc_set_owners",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        -800,
        -2144
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/siteVerification/v1/webResource/{{ $fromAI(\"id\", \"The webResource id of the target property, copied exactly from list_owners\") }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ id: $fromAI(\"id\", \"The webResource id of the target property, copied exactly from list_owners\"), site: { type: $fromAI(\"siteType\", \"SITE or INET_DOMAIN\"), identifier: $fromAI(\"identifier\", \"Full URL ending in / for SITE, or bare domain for INET_DOMAIN\") }, owners: ($fromAI(\"owners\", \"COMPLETE comma-separated list of ALL owner emails to KEEP. Include every current owner from list_owners, plus or minus your one change. Any email omitted will be REMOVED.\") || \"\").split(\",\").map(function(s){ return s.trim(); }).filter(function(x){ return x; }) }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "toolDescription": "WRITE (owners): Overwrite the COMPLETE verified-owners list of a property (Google site-OWNERSHIP list). Use to (a) ADD an owner (a person or the service account), or (b) REMOVE an owner. GRANTING ACCESS: adding a person's email makes them a delegated OWNER; that person then gets full Search Console access by opening THEIR OWN Search Console > Add property > entering the site URL, which AUTO-VERIFIES instantly (no file/tag needed since they are already an owner) and shows as Owner in the dashboard. So this DOES grant real dashboard access (OWNER level). Note: Search Console Full/Restricted USER levels are a separate system with no API. REMOVAL: works for delegated owners; a VERIFIED owner that still has a verification token on the site (meta/HTML/GA/GTM/DNS) CANNOT be removed until that token is taken off the site (Google blocks it). MANDATORY SAFE PROTOCOL: (1) ALWAYS call list_owners immediately before, to get the property id and CURRENT full owners list. (2) To ADD: owners = every current owner + the new email. To REMOVE: owners = every current owner EXCEPT the one to remove. (3) NEVER send a partial list -- ANY omitted owner is permanently removed. Inputs: id (from list_owners), siteType, identifier, owners (complete comma-separated list).",
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        },
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "5f4205c3-d70b-4788-9d87-b76ed9b2bea3",
      "name": "gsc_pagespeed_analyze",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        1472,
        -2144
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={{ encodeURIComponent($fromAI(\"url\", \"The full page URL to analyze, e.g. https://example.com/page\")) }}&strategy={{ $fromAI(\"strategy\", \"mobile or desktop (default mobile)\") || \"mobile\" }}",
        "fields": "id,loadingExperience,lighthouseResult.categories.performance.score",
        "options": {},
        "authentication": "predefinedCredentialType",
        "fieldsToInclude": "selected",
        "toolDescription": "Analyze a page's speed + Core Web Vitals via Google PageSpeed Insights. Inputs: url (full page URL), strategy (mobile or desktop, default mobile). Returns real-user Core Web Vitals (LCP, INP, CLS) and a performance score. Public API - no Search Console auth needed. Response is trimmed to the key metrics to save tokens.",
        "optimizeResponse": true,
        "nodeCredentialType": "googleOAuth2Api"
      },
      "credentials": {
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "904d1976-2902-4a74-9b5d-8cef32cd1967",
      "name": "Group: Site management",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        -2480
      ],
      "parameters": {
        "color": 7,
        "width": 948,
        "height": 500,
        "content": "## Site management\nAdd, verify & manage properties.\n\n\u2022 gsc_list_sites \u2014 all properties you can access (+ permission)\n\u2022 gsc_get_site \u2014 details + permission for one property\n\u2022 gsc_add_site \u2014 add a new property (unverified) \u270d\ufe0f\n\u2022 gsc_delete_site \u2014 remove a property from the account \u270d\ufe0f\n\u2022 gsc_get_verification_token \u2014 FILE/META/DNS_TXT token to prove ownership\n\u2022 gsc_verify_site \u2014 verify ownership after placing the token \u2192 Owner \u270d\ufe0f"
      },
      "typeVersion": 1
    },
    {
      "id": "d8de4b68-49f7-43fb-a7ef-e746e0bde11c",
      "name": "Group: Ownership & access",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        -2480
      ],
      "parameters": {
        "color": 7,
        "width": 644,
        "height": 506,
        "content": "##  Ownership & access\nWho owns a property (owner = full dashboard access).\n\n\u2022 gsc_list_owners \u2014 verification owners + webResource id per property\n\u2022 gsc_set_owners \u2014 overwrite the owners list to ADD/REMOVE an owner \u270d\ufe0f\n\nTip: an added person opens THEIR Search Console \u2192 Add property \u2192 it auto-verifies them as Owner."
      },
      "typeVersion": 1
    },
    {
      "id": "c94f29ec-8c11-470f-951f-ae141c5ead74",
      "name": "Group: Sitemaps",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -2480
      ],
      "parameters": {
        "color": 7,
        "width": 692,
        "height": 512,
        "content": "##  Sitemaps\nSubmit & monitor sitemaps (index + children).\n\n\u2022 gsc_list_sitemaps \u2014 top-level OR an index's child sitemaps + status\n\u2022 gsc_get_sitemap \u2014 full status of ONE sitemap (errors, warnings, contents)\n\u2022 gsc_submit_sitemap \u2014 submit/re-submit, forces a fresh crawl \u270d\ufe0f\n\u2022 gsc_delete_sitemap \u2014 remove a sitemap submission \u270d\ufe0f"
      },
      "typeVersion": 1
    },
    {
      "id": "ea9163f6-83ab-4058-8429-dde131721525",
      "name": "Group: Indexing API",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -2480
      ],
      "parameters": {
        "color": 7,
        "width": 628,
        "height": 512,
        "content": "##  Indexing\nPush (re)crawl / removal notices to Google.\nNeeds the account to be an Owner + the indexing scope.\n\n\u2022 gsc_indexing_publish \u2014 notify Google ONE URL updated/deleted \u270d\ufe0f\n\u2022 gsc_indexing_batch_publish \u2014 bulk, up to 100 URLs at once \u270d\ufe0f\n\u2022 gsc_indexing_get_metadata \u2014 last indexing notice for a URL (404 = none yet)"
      },
      "typeVersion": 1
    },
    {
      "id": "b019a912-846d-4776-8ff4-c355a57663d1",
      "name": "Group: Inspection & Analytics",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -2480
      ],
      "parameters": {
        "color": 7,
        "width": 940,
        "height": 512,
        "content": "##  Inspection & Analytics\nPerformance + index status + speed.\n\n\u2022 gsc_inspect_url \u2014 index status, coverage, canonical, mobile, rich results\n\u2022 gsc_query_search_analytics \u2014 clicks/impr/CTR/position by query/page/country/device/date; server-side filters + paging\n\u2022 gsc_pagespeed_analyze \u2014 Core Web Vitals + performance score (mobile/desktop)"
      },
      "typeVersion": 1
    },
    {
      "id": "251bfb31-9a51-43a7-8378-650e001f8dc2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2768,
        -3376
      ],
      "parameters": {
        "width": 560,
        "height": 1504,
        "content": "# \ud83d\udd0d Google Search Console MCP - Full SEO Toolkit\n\nTurn n8n into a **Google Search Console MCP server**. Connect Claude / Cursor / any\nMCP client and get **18 SEO tools** \u2014 search analytics, URL inspection, sitemaps,\nthe Indexing API, site verification, ownership management, and PageSpeed / Core Web\nVitals \u2014 all under your own Google account.\n\n## \u2699\ufe0f How it works\n1. The **MCP Server Trigger** exposes this workflow as an MCP endpoint (one URL).\n2. Every tool is an **HTTP Request Tool** calling a Google API, all using **one**\n   Google credential.\n3. Point your MCP client at the endpoint URL \u2192 all 18 tools appear automatically.\n\n## \ud83d\udee0\ufe0f Setup (~10 min)\n1. **Google Cloud** \u2192 enable these APIs: Google Search Console API,\n   Web Search Indexing API, Site Verification API, PageSpeed Insights API.\n2. **Create a credential** \u2014 either a **Google OAuth2** credential (acts as you \u2192\n   you see everything in your own Search Console) or a **Service Account** (headless).\n   Scopes required:\n   \u2022 https://www.googleapis.com/auth/webmasters\n   \u2022 https://www.googleapis.com/auth/indexing\n   \u2022 https://www.googleapis.com/auth/siteverification\n   \u2022 openid   \u2190 needed for the PageSpeed tool\n3. **Select that credential** on every tool node (they all share one).\n4. Make your account / service account an **Owner** of the property\n   (required for the Indexing API).\n5. **Publish**, open the **MCP Server Trigger**, copy the **MCP URL**, add it in\n   your MCP client. Done.\n\n## \ud83e\uddf0 The 18 tools\n\ud83c\udfe0 Site management \u2014 list_sites, get_site, add_site, delete_site,\n     get_verification_token, verify_site\n\ud83d\udc65 Ownership & access \u2014 list_owners, set_owners\n\ud83d\uddfa\ufe0f Sitemaps \u2014 list_sitemaps, get_sitemap, submit_sitemap, delete_sitemap\n\u26a1 Indexing API \u2014 indexing_publish, indexing_batch_publish, indexing_get_metadata\n\ud83d\udd0d Inspection & Analytics \u2014 inspect_url, query_search_analytics (dimension filters +\n     paging), pagespeed_analyze (Core Web Vitals)\n\n## \ud83d\udcdd Good to know\n\u2022 Google can't filter analytics by position/CTR (they're metrics) \u2014 request rows and\n  filter those in your analysis (e.g. \"position 10\u201320\").\n\u2022 Indexing API is officially for JobPosting/BroadcastEvent; for normal pages it acts\n  as a recrawl nudge.\n\u2022 Search Console \"Full/Restricted USERS\" have no API \u2014 only OWNERS are API-manageable.\n\u2022 Adding an owner grants real access: they open their own Search Console \u2192 Add\n  property \u2192 it auto-verifies them as Owner.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "279efea9-a64c-4fdf-852b-e86b96466c29",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -3056
      ],
      "parameters": {
        "width": 704,
        "height": 464,
        "content": "# Tutorial and Setup Guide\n\n@[youtube](UA_4rYF33k8)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "fb1fb944-445b-42b4-95c5-5ed7aa6cee9d",
  "nodeGroups": [],
  "connections": {
    "gsc_add_site": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_get_site": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_list_sites": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_set_owners": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_delete_site": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_get_sitemap": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_inspect_url": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_list_owners": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_verify_site": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_list_sitemaps": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_delete_sitemap": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_submit_sitemap": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_indexing_publish": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_pagespeed_analyze": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_indexing_get_metadata": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_get_verification_token": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_indexing_batch_publish": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "gsc_query_search_analytics": {
      "ai_tool": [
        [
          {
            "node": "GSC MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}