Google Search Console

io.github.ni-c由 GitHub 账号 ni-c 发布v0.3.0更新于 Oct 25, 2026

MCP server for Google Search Console: properties, sitemaps, search analytics and URL inspection

概览

AI 生成的概览

本地运行的 Google Search Console MCP 服务器:管理资源与所有权、站点地图、搜索效果分析和网址检查。

可以做什么
  • 列出、添加和删除 Search Console 资源,并查看资源缺少哪一步设置
  • 获取验证令牌、验证或取消验证所有权、更新所有者列表
  • 列出、查看、提交和删除站点地图,单次最多可提交 50 个
  • 查询效果报告(点击、展示、点击率、排名),支持维度、筛选和相对时间段
  • 检查单个或多个网址的索引状态、规范网址、抓取时间和富媒体搜索结果,并可请求重新索引
适用场景
适合让助手读取或配置你自有网站的 Search Console 数据:查看索引状态、拉取搜索表现、提交站点地图,或免去手动四步完成域名验证。
运行要求
需要 Node.js 24 或更新版本,或使用容器镜像。需要 Google 凭据:服务账号密钥(GSC_SERVICE_ACCOUNT_KEY 或 GSC_SERVICE_ACCOUNT_KEY_FILE)、OAuth2 三项(GSC_CLIENT_ID、GSC_CLIENT_SECRET、GSC_REFRESH_TOKEN),或 GOOGLE_APPLICATION_CREDENTIALS。需在 Google Cloud 项目中启用 Search Console API,并另行启用 Site Verification API 和 Indexing API。需要访问 Google 的网络。
安装前请注意
需要 Google 凭据:服务账号密钥、OAuth2 客户端密钥与刷新令牌,或应用默认凭据。写入类工具会改动真实数据:删除资源或站点地图、放弃所有权,而 update_site_owners 会整体替换所有者列表,一次调用即可移除其他所有所有者。危险操作会请求人工确认,客户端不支持时返回令牌。可用 GSC_READ_ONLY 或 GSC_ALLOWED_SITES 限制范围。来自 Google 的数据被标记为不可信。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Google Search Console,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

google-search-console-mcp

[CI] [OpenSSF Scorecard] [Socket Badge] [Glama score]
[npm version] [container image] [HTTP via mcp-hub]
[docs] [sponsor]

A Model Context Protocol (MCP) server for Google Search Console, the service that tells you how Google sees your site — this reads it and sets it up.

Lets MCP clients like Claude Code, Claude Desktop or Codex create a property and prove ownership of it, submit and refresh sitemaps, ask what any URL's index status is, and query the whole Performance report — with the irreversible operations put to a person first and the write tools switchable off entirely.

21 tools is the ceiling, not the floor: GSC_ALLOW_TOOLS=essential registers a curated five instead, and a model picks the right tool far more reliably from five than from 21 — see choosing which tools load.

[An MCP client talks to google-search-console-mcp over stdio; the server calls the Search Console, Site Verification and Indexing APIs over HTTPS.]

[Listing the tools, narrowing them to the essential preset, and the startup abort a mistyped tool name produces]

What makes it different

It can actually create a working property. Getting one takes four steps in a fixed order — obtain a verification token, place it in DNS or on the page, verify ownership, add the property — and nothing in Google's APIs enforces that order. Calling sites.add first succeeds and leaves a property that appears in every listing and answers 403 for every piece of data, which looks like a permissions bug and is not. setup_site reports which step is missing and hands over the exact DNS record to paste. Servers that expose sites.add alone can only add properties somebody already verified by hand.

Three APIs, not one. Search Console v1 is ten methods and does not include ownership. Site Verification is a separate service with its own scope, its own host and an incompatible way of naming the same site — sc-domain:example.com there is {type: INET_DOMAIN, identifier: example.com}, and passing the property spelling straight through is accepted and verifies a domain literally called sc-domain:example.com. The Indexing API is a third. All three are covered, and the translation between them is in src/site-identity.ts.

The numbers are right. Search analytics come back as a table with totals where CTR is computed from the totals rather than averaged across rows, and average position is weighted by impressions. Unweighted, a thousand rare queries ranking 80th drag a property's real average of 12 up into the nineties. The result also says plainly that the rows do not sum to the property total when the query dimension is used — Google withholds rare queries for anonymity, commonly a third or more of all impressions, and a total printed without that caveat is a number people will quote.

It knows where these APIs are sharp. The trailing slash on https://example.com/ is mandatory and its absence is a 403; a domain property and a URL-prefix property for the same site are different properties with different data, so a bare hostname is refused rather than guessed at; days are counted in Pacific Time, so a last7days computed in UTC asks for a day Google has no data for; the hour dimension silently returns nothing without dataState: HOURLY_ALL; Google omits empty arrays entirely, so a fresh credential's property list arrives as {}; and the Indexing API returns 200 for any owned URL while only acting on JobPosting and BroadcastEvent pages.

Requirements

  • Node.js 24 or newer (or the container image)
  • A Google credential — a service account key, an OAuth2 refresh token, or application default credentials
  • The APIs you intend to use enabled in a Google Cloud project: Search Console API, and separately Site Verification API and Indexing API

Configuration

The server starts without credentials and lists its tools; every call then fails with setup instructions rather than a Google error. That is deliberate, so registries and sandbox inspectors can introspect it.

VariableDescription
GSC_SERVICE_ACCOUNT_KEYService account key as raw JSON, or base64-encoded JSON
GSC_SERVICE_ACCOUNT_KEY_FILEPath to a service account key file. Alternative to the above — setting both is an error
GSC_CLIENT_IDOAuth2 client id
GSC_CLIENT_SECRETOAuth2 client secret
GSC_REFRESH_TOKENOAuth2 refresh token. All three OAuth2 variables are required together
GOOGLE_APPLICATION_CREDENTIALSApplication default credentials, used when no GSC_ credential is set
GSC_SITE_URLDefault property, e.g. sc-domain:example.com or https://example.com/. Makes site_url optional everywhere
GSC_ALLOWED_SITESComma-separated properties this server may touch at all; anything else is refused
GSC_READ_ONLYtrue (or 1/yes) registers only the twelve read tools
GSC_ALLOW_TOOLSComma-separated tool names, a list_* prefix, or essential
GSC_DENY_TOOLSSame shape, subtracted from whatever the allow list left
ELICITATIONfalse replaces the approval dialog with the two-call token. Not prefixed

Credentials are tried in that order — explicit beats ambient. A partial OAuth triple is a startup error rather than a reason to fall through to application default credentials, because that fallback would quietly run the server as whatever account the machine is logged into.

Which credential

A service account is the recommended one: it sees only the properties you explicitly add it to, and revoking it does not touch anyone's Google account. Add its client_email under Settings → Users and permissions in Search Console, or give it ownership with verify_site. Note that the Indexing API requires owner, not full user.

An OAuth2 refresh token acts as the person who consented and sees everything they see. Its scopes were fixed at consent time and cannot be widened later.

Choosing which tools load

Every visible tool costs context on every request, and a model picks the right one far more reliably from five than from 21. Two variables narrow the list:

sh
GSC_ALLOW_TOOLS=essential          # the curated fiveGSC_ALLOW_TOOLS='list_*,get_site'  # exact names, or one trailing *GSC_DENY_TOOLS='delete_*'          # subtracted from whatever allow left

essential is list_sites, get_site, list_sitemaps, query_search_analytics and inspect_url — everything needed to look at a property, and nothing that changes it.

An entry that matches no tool stops the server with the list of real names. An ignored typo would otherwise leave a tool missing from tools/list with nothing pointing at the cause, and nobody traces an absence back to an environment variable.

If you run several of these servers at once, mcp-hub is the other answer — its /hub endpoint replaces every server's tools with six meta-tools.

Narrowing the list also narrows the credential: the OAuth scopes this server requests are derived from the tools that are actually registered, so a server denied the Indexing tools never asks for the Indexing scope.

Installation

Claude Code

sh
claude mcp add google-search-console -- npx -y @ni-c/google-search-console-mcp

Claude Desktop

json
{  "mcpServers": {    "google-search-console": {      "command": "npx",      "args": ["-y", "@ni-c/google-search-console-mcp"],      "env": {        "GSC_SERVICE_ACCOUNT_KEY_FILE": "/path/to/key.json",        "GSC_SITE_URL": "sc-domain:example.com"      }    }  }}

Codex

toml
[mcp_servers.google-search-console]command = "npx"args = ["-y", "@ni-c/google-search-console-mcp"]
[mcp_servers.google-search-console.env]GSC_SERVICE_ACCOUNT_KEY_FILE = "/path/to/key.json"GSC_SITE_URL = "sc-domain:example.com"

Docker

sh
docker run --rm -i \  -v /path/to/key.json:/key.json:ro \  -e GSC_SERVICE_ACCOUNT_KEY_FILE=/key.json \  -e GSC_SITE_URL=sc-domain:example.com \  ghcr.io/ni-c/google-search-console-mcp

Through mcp-hub

A client that cannot spawn a local process — ChatGPT connectors, Claude on the web, Cursor, LibreChat — reaches google-search-console-mcp through mcp-hub: one container serves many stdio MCP servers over Streamable HTTP, with an OAuth 2.1 login behind a single password and long-lived tokens for the clients that cannot do OAuth. Its /hub endpoint puts every server behind six meta-tools, so one connector reaches all of them without N×tool schemas in the model's context, and it speaks both protocol revisions — a question this server asks travels through it to the person at the far end.

Its /config/mcp.json uses Claude Code's format, so the entry is the one you already have:

json
{  "mcpServers": {    "google-search-console": {      "command": "npx",      "args": ["-y", "@ni-c/google-search-console-mcp"],      "env": {        "GSC_SERVICE_ACCOUNT_KEY": "…",        "GSC_SITE_URL": "sc-domain:example.com"      }    }  }}

allowTools and denyTools there are the hub's own per-server filter, which is not the same thing as *_ALLOW_TOOLS in env — the difference, and the mistake it invites, are in the client guide.

Tools

site_url is optional on every tool that takes it when GSC_SITE_URL is set.

Every tool declares an outputSchema and answers with structuredContent alongside the text block, so a client can use the result without parsing prose. query_search_analytics keeps its rendered table in the text block and puts the rows themselves in the structured half; six tools that answered with a sentence now answer with fields too.

Every tool that reports Google's data carries untrusted: true and source: "search-console" as fields. "It is only search data" is exactly the wrong intuition: a search query is a string a member of the public typed into Google, and a page title comes from the crawled site. Six tools are without the marker, because their answer is a property this server was given and a fact it established: add_site, delete_site, submit_sitemap, submit_sitemaps, delete_sitemap and unverify_site.

Properties and ownership

ToolWhat it does
setup_siteReports which of the four setup steps a property is missing, with the DNS record or meta tag to place. Changes nothing
list_sitesEvery property this credential can see, with its permission level
get_siteOne property — the way to settle which of the two spellings exists
add_siteAdds a property. Does not verify ownership
delete_site 👤Removes a property and its history
list_verified_sitesSites this credential has proven ownership of, with all owners
get_verified_siteOne of them by its opaque resource id
get_verification_tokenThe token, and exactly where to put it. Claims nothing
verify_siteChecks for the placed token and records ownership
unverify_site 👤Gives up ownership
update_site_ownersReplaces the owner list. method: "patch" uses PATCH, which behaves identically

Sitemaps

ToolWhat it does
list_sitemapsSubmitted sitemaps, with download times, URL counts and errors
get_sitemapOne sitemap — where a submission's errors actually appear
submit_sitemapSubmits or refreshes one. There is no separate update call
submit_sitemapsUp to 50 in one call, with per-entry results
delete_sitemap 👤Removes one

Search analytics and indexing

ToolWhat it does
query_search_analyticsThe Performance report: clicks, impressions, CTR and position by any dimensions, with filters and relative periods
inspect_urlWhat Google knows about one URL — index status, canonicals, crawl time, rich results
inspect_urlsUp to 20 URLs, condensed to verdicts
get_indexing_statusIndexing API notification history for a URL
request_indexingNotifies Google a URL changed. Only acts on JobPosting and BroadcastEvent pages

Not exposed, on purpose

urlTestingTools.mobileFriendlyTest is still in Google's discovery document and the service behind it was switched off in December 2023. A tool for it could only ever return an error, so there is not one.

Safety

Four operations ask a person. delete_site, delete_sitemap, unverify_site and update_site_owners raise a real dialog through MCP elicitation where the client supports it — one the model cannot answer on its behalf. Where it does not, they refuse the first call and return a short-lived token bound to those exact arguments, and say so rather than implying somebody approved. Either way the approval is bound to the property, so one issued for one cannot be replayed against another. update_site_owners is in that list because the list it takes is the complete owner list afterwards — one well-formed call removes everyone else, and nothing here can put them back. ELICITATION=false takes the fallback path deliberately; it never removes the guard. See Asking a person.

Everything from the APIs is marked untrusted. Search queries are strings the public typed into Google; page titles and crawl diagnostics come from whoever runs the crawled site. Someone who wants a model to act on their instructions can put them in a page title and wait to be crawled. The two sentences of a confirmation prompt are built only from values the server derived; a sitemap URL or an owner list is quoted below them as data.

The allowlist has no exemptions. GSC_ALLOWED_SITES is enforced wherever a tool names a property, and separately on the two shapes that do not name one: the Indexing API tools match the page URL against the list the way Search Console scopes a property, and the verification tools resolve their opaque resource id to a property before acting on it. Both listings filter to the allowlist and say how many entries they withheld.

Read-only goes below the tool layer. GSC_READ_ONLY=true does not register the write tools and requests webmasters.readonly instead of webmasters, so a write is impossible even if a tool tried.

Credentials never leak into output. They are deleted from the environment after start-up, never sent to a redirect target, and a rejected value is described rather than echoed — including when it is a key pasted into GSC_ALLOW_TOOLS, GSC_SITE_URL or ELICITATION by mistake, and including the access token itself, which is checked before it becomes a header.

What Google sends is held to a shape. The status of a response is decided before its body is read, every field a result promises is checked at the boundary — a row that is not an object is dropped, a null site block is not a site, an empty 200 is an empty record — and text is stripped of control characters on the way out. Results are budgeted in both channels, caller strings have ceilings, and a batch call stops after two minutes and says how far it got. See Security.

Documentation

The full guide, tool reference and security notes live at google-search-console-mcp.ni-c.de (source in docs/).

Development

sh
npm installnpm test            # no network — every test runs against a stubbed fetchnpm run lintnpm run build

See CONTRIBUTING.md.

Releasing

Update CHANGELOG.md, bump the version in package.json and server.json, then push a signed tag:

sh
git tag -s v0.1.0 -m 'v0.1.0' && git push origin main v0.1.0

release.yml runs the suite, publishes to npm with provenance through a trusted publisher, pushes the multi-arch image to GHCR and updates the MCP registry entry.

Contributing

Issues, discussions and pull requests are welcome — see CONTRIBUTING.md. For vulnerabilities please use private reporting rather than a public issue; the policy is in SECURITY.md.

License

MIT © Willi Thiel

来源:README.md,提交 b8a39ab

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.3.0最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分