mcpField
S
SEO Console

SEO Console

本地服务
seo-console.verdelic.com商业与营销05 周前更新

关于 SEO Console

面向 SEO 和产品发现数据分析的 MCP 服务,汇集 Search Console、PageSpeed、应用商店、Google Ads、WordPress.org 与 Core Web Vitals 工具。部分审计和关键词功能无需 Google 服务账号;工具也可通过命令行运行,快照可用于后续比较。

主要功能

  1. 01查询 Search Console 与 PageSpeed 数据
  2. 02审计页面 SEO 并获取关键词建议
  3. 03查询应用商店与 WordPress.org 信息
  4. 04访问 Google Ads 与 Core Web Vitals 数据
  5. 05保存并比较多来源数据快照

适用场景

  1. 01检查网站 SEO 问题并规划改进
  2. 02比较应用商店列表的阶段性变化
  3. 03分析搜索表现与真实用户网页指标

MCP 相关

以 stdio MCP 服务暴露 SEO 与产品发现相关工具;也提供命令行运行方式。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ibrahimhajjaj-seo-console": {
"command": "npx",
"args": [
"-y",
"seo-console-mcp"
]
}
}
}
启动命令npx -y seo-console-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmseo-console-mcp0.18.2

工具

43

收录的工具列表 · 更新于 2 周前

参数类型必填说明
typeenum否结果类型。discover 是 Discover 信息流,googleNews 是 Google News 应用和 news.google.com,不是 Search 中的“新闻”标签页。两者支持的维度都少于网页搜索:均不报告查询维度web | image | video | news | discover | googleNews
endDatestring否结束日期,格式为 YYYY-MM-DD;默认为今天
siteUrlstring是Search Console 属性,例如 https://example.com/ 或 sc-domain:example.com
rowLimitinteger否返回的最大行数
startRowinteger否要从大型结果中分页时使用的起始行,行号从 0 开始
dataStateenum否full 表示已完成的数据(默认,延迟约 2–3 天);all 表示包含近期的部分数据full | all
startDatestring否开始日期,格式为 YYYY-MM-DD;默认为 28 天前
dimensionsarray否用于对结果分组的维度
maxTableRowsinteger否限制文本表格中显示的行数;结构化行始终完整。0 = 仅显示摘要。
aggregationTypeenum否Search Console 对行进行聚合的方式auto | byProperty | byPage
dimensionFilterGroupsarray否Search Console 维度筛选条件

详细介绍

seo-mcp

seo-mcp 是一个基于 stdio 的 Model Context Protocol 服务,适用于 Google Search Console、PageSpeed Insights 和页面 SEO 审核。它为 MCP 客户端提供 43 个工具,覆盖已验证的 Search Console 资源,以及用户发现产品的其他渠道:App Store、Google Play、WordPress.org、Google Ads 和真实用户 Core Web Vitals;同时,无需 Google 服务账号凭据,也可以使用 HTML 审核、PageSpeed、IndexNow、关键词建议和 WordPress.org 工具。每个工具也都可以从命令行运行,因此可以将结果写入文件,而不是放入模型的上下文中;snapshot 会在同一时刻记录 Search Console、App Store、Google Play 和 WordPress.org 的数据,供后续运行进行差异比较。

https://github.com/user-attachments/assets/66bbd628-d267-421f-9400-633b696bbd53

要求

  • Node.js 20.18.1 或更高版本
  • 仅在使用设置向导时需要 gcloud

其他所需内容取决于你使用哪些工具。设置向导涵盖 Search Console 和 PageSpeed;App Store、Google Play 和 Chrome UX Report 工具各自需要你自行创建凭据。

工具所需内容获取方式
seo_audit、audit_site、(不带 siteUrl 的)keyword_ideas、wporg_plugin无公共端点
pagespeed可选的 SEO_MCP_PAGESPEED_KEY设置向导 --pagespeed-key,或 Google Cloud API 密钥
crux_field_data、crux_historySEO_MCP_CRUX_KEY(或可能调用 CrUX API 时使用 PageSpeed 密钥)Google Cloud API 密钥
indexnow_submitSEO_MCP_INDEXNOW_KEY你托管在 /<key>.txt 的任意密钥
Search Console 工具、snapshot 属性服务账号密钥使用设置向导,然后将该账号添加到资源
snapshot、list_snapshots、compare_snapshots可选的 SEO_MCP_SNAPSHOT_DIR快照文件的存放位置,默认为 ~/.config/seo-mcp/snapshots
verifyCLOUDFLARE_API_TOKENCloudflare,Zone.DNS:Edit
app_store_listing、app_store_discovery、app_store_reviewsSEO_MCP_ASC_KEY_PATH、SEO_MCP_ASC_KEY_ID、SEO_MCP_ASC_ISSUER_IDApp Store Connect 团队密钥;任意可读取应用的角色均可
app_store_sales上述内容,以及 SEO_MCP_ASC_VENDOR_NUMBER使用 Admin、Finance 或 Sales and Reports 角色创建的团队密钥
play_store_statsSEO_MCP_PLAY_BUCKET、SEO_MCP_PLAY_CREDENTIALS对报告存储桶具有读取权限的服务账号
play_vitalsSEO_MCP_PLAY_CREDENTIALS在 Play Console 中获邀且拥有应用质量访问权限的服务账号
ads_ 工具GOOGLE_ADS_DEVELOPER_TOKEN、GOOGLE_ADS_CLIENT_ID、GOOGLE_ADS_CLIENT_SECRET、GOOGLE_ADS_REFRESH_TOKEN、GOOGLE_ADS_CUSTOMER_IDGoogle Ads 开发者令牌,以及带有刷新令牌的 OAuth 客户端

安装和构建

npm install
npm run build

使用以下命令运行本地服务:

node /absolute/path/to/seo-mcp/dist/index.js

该软件包以 seo-console-mcp 的名称发布在 npm 上;安装后会提供名为 seo-mcp 的命令。MCP 客户端可以通过以下方式启动它:

npx -y seo-console-mcp

运行中的服务仅使用 stdout 传输 MCP 通信协议。诊断信息会写入 stderr。

设置向导

从本地检出目录运行:

npm run setup

或使用 npx:

npx -y seo-console-mcp setup

如需指定项目或自定义密钥位置,以便在无人值守的情况下选择项目:

seo-mcp setup --project my-seo-project --key /absolute/path/seo-mcp.key.json

向导还提供可选的 PageSpeed Insights API 密钥,可提高配额。此选项为自愿选择:使用 --pagespeed-key 可在不提示的情况下创建密钥,使用 --no-pagespeed-key 可明确跳过提示。非交互式运行会跳过此步骤,除非提供了 --pagespeed-key。

向导可安全地重复运行。它会:

  1. 检查是否存在 gcloud。如果不存在,则会打印手动操作说明,并成功退出,不做任何更改。
  2. 使用当前已通过身份验证的账号,或运行 gcloud auth login。
  3. 使用当前项目、指定的 --project,或提示输入项目 ID。如果项目不存在,则会创建并选中该项目。
  4. 启用 searchconsole.googleapis.com、pagespeedonline.googleapis.com 和 siteverification.googleapis.com。
  5. 复用或创建 seo-mcp 服务账号。
  6. 复用现有密钥或创建 seo-mcp.key.json。
  7. 可选:创建仅限 PageSpeed Insights 使用的项目级 API 密钥。
  8. 打印所需的 Search Console 权限设置步骤,以及可直接复制的客户端配置。

向导绝不会打印服务账号密钥内容。请求创建 PageSpeed 密钥且创建成功时,向导会在最终客户端配置中打印一次该密钥。生成的 *.key.json 文件名已添加到 Git 忽略列表。

授予服务账号 Search Console 访问权限

Search Console API 没有用于向资源添加用户的端点,因此服务账号必须成为域名本身的已验证所有者。可以通过两种方式实现。

自动化(Cloudflare DNS)

如果域名的 DNS 托管在 Cloudflare 上,verify 会完成整个流程:向 Google 请求验证令牌,通过 Cloudflare API 写入 TXT 记录,等待验证完成,然后注册资源。

export CLOUDFLARE_API_TOKEN=...   # a token scoped to Zone.DNS:Edit for the zone
seo-mcp verify getpsst.app another-domain.com

也可以通过 --cf-token 传入令牌,通过 --credentials 指定密钥路径(否则会使用 GOOGLE_APPLICATION_CREDENTIALS / SEO_MCP_CREDENTIALS)。此命令是幂等的:TXT 记录会保留(Google 会重新检查),因此对同一域名重复运行是安全的。请勿删除 DNS 中的记录,否则会失去所有权。

verify 会从 CLOUDFLARE_API_TOKEN 或 CF_API_TOKEN(或 --cf-token)读取令牌,绝不会存储或记录该令牌,因此任何能够导出环境变量的密钥存储都可以使用。令牌需要具备 Zone -> DNS -> Edit 和 Zone -> Zone -> Read 权限(即“Edit zone DNS”模板),并限制在要验证的区域范围内。为避免令牌出现在 shell 历史记录中:

macOS(Keychain):

security add-generic-password -a "$USER" -s cloudflare-dns-edit -l "Cloudflare DNS Edit" -U -w   # store once, hidden prompt
CLOUDFLARE_API_TOKEN=$(security find-generic-password -s cloudflare-dns-edit -w) seo-mcp verify example.com

Linux(libsecret 或 pass):

secret-tool store --label="Cloudflare DNS Edit" service cloudflare-dns-edit   # store once, hidden prompt
CLOUDFLARE_API_TOKEN=$(secret-tool lookup service cloudflare-dns-edit) seo-mcp verify example.com

Windows(PowerShell SecretManagement):

Set-Secret -Name cloudflare-dns-edit -Secret (Read-Host -AsSecureString)   # store once, hidden prompt
$env:CLOUDFLARE_API_TOKEN = Get-Secret -Name cloudflare-dns-edit -AsPlainText; seo-mcp verify example.com
手动操作

在 Search Console 界面中将服务账号添加为所有者:

Search Console -> your property -> Settings -> Users and permissions -> Add user
  seo-mcp@PROJECT_ID.iam.gserviceaccount.com  ->  Owner

请使用向导打印的准确服务账号邮箱。由于 submit_sitemap 是写入操作,因此需要所有者访问权限。

Google Cloud 手动备用方案

如果无法使用 gcloud,请手动创建凭据,或在安装 gcloud 后运行以下命令:

gcloud auth login
gcloud projects create YOUR_PROJECT_ID
gcloud config set project YOUR_PROJECT_ID
gcloud services enable searchconsole.googleapis.com pagespeedonline.googleapis.com siteverification.googleapis.com
gcloud iam service-accounts create seo-mcp --display-name="SEO MCP"
gcloud iam service-accounts keys create ./seo-mcp.key.json \
  --iam-account=seo-mcp@YOUR_PROJECT_ID.iam.gserviceaccount.com

如果项目已存在,请跳过 gcloud projects create。然后授予服务账号 Search Console 访问权限(见上文),并在 MCP 客户端中配置密钥的绝对路径。

身份验证

Search Console 工具使用 google.auth.GoogleAuth,并启用以下两个范围:

  • https://www.googleapis.com/auth/webmasters
  • https://www.googleapis.com/auth/webmasters.readonly

凭据查找顺序如下:

  1. --credentials /absolute/path/key.json
  2. SEO_MCP_CREDENTIALS
  3. GOOGLE_APPLICATION_CREDENTIALS
  4. 如果 ~/.config/seo-mcp/seo-mcp.key.json(或 $XDG_CONFIG_HOME/seo-mcp/...)存在,则使用该文件。这是设置向导写入的默认位置,因此标准安装无需配置。

例如:

node dist/index.js --credentials /absolute/path/seo-mcp.key.json

pagespeed 是公开工具,不使用服务账号。如需提高 PageSpeed Insights 配额,请设置 SEO_MCP_PAGESPEED_KEY,或将 apiKey 传递给该工具。seo_audit、audit_site 和 indexnow_submit 也无需 Google 凭据;indexnow_submit 改为通过 key 或 SEO_MCP_INDEXNOW_KEY 接收 IndexNow 密钥。只有在传入 siteUrl 以进行 Search Console 交叉引用时,keyword_ideas 才需要这些凭据。App Store Sales 和 Trends 会读取 SEO_MCP_ASC_VENDOR_NUMBER。Chrome UX Report 工具会读取 SEO_MCP_CRUX_KEY;如果同一个密钥获准调用 chromeuxreport.googleapis.com,则会回退使用 SEO_MCP_PAGESPEED_KEY。snapshot、list_snapshots 和 compare_snapshots 会将文档保存在 SEO_MCP_SNAPSHOT_DIR 中,默认路径为 ~/.config/seo-mcp/snapshots,且无法在该目录之外读写。Requirements 下方的表格列出了每个工具所需的内容。

安全模型

  • 验证域名会将服务账号设为已验证所有者。所有者可以更改 Search Console 设置并提交移除(取消编入索引)请求,因此即使这里的大多数工具只执行读取操作,也应将密钥视为敏感凭据。
  • 将密钥保留在本地。 它位于 GOOGLE_APPLICATION_CREDENTIALS 指定的路径中(建议执行 chmod 600)。切勿将其打包到已发布的软件包、容器镜像或 CI 密钥存储中。如果密钥泄露,任何持有者都能控制所有已验证资源。
  • 不要从 DNS 中移除 google-site-verification TXT 记录。 Google 会重新检查该记录;删除后会撤销所有权。
  • 不会记录任何密钥。 向导和 verify 只会打印凭据路径,绝不会打印密钥或令牌的内容。
  • 撤销很简单。 可在 Search Console 界面中放弃所有权(或调用 siteVerification.webResource.delete),并使用 gcloud iam service-accounts keys delete 轮换密钥。
  • seo_audit 只会抓取公开主机。 系统会解析目标 URL 和每次重定向,并在其指向环回地址、私有地址、链路本地地址或其他非公开地址时拒绝访问,因此无法诱导模型抓取内部服务或云元数据。连接时会再次验证地址(套接字会绑定到已验证的地址),因此 DNS 重绑定主机无法在验证时提供公开地址、连接时却改用私有地址。设置 SEO_MCP_ALLOW_PRIVATE_HOSTS=1 可审计你信任的内部或暂存主机。这不能替代网络层隔离;如果要在能够访问内部服务的主机上审计不受信任的 URL,请在具有出口流量控制的环境中运行该服务。

Claude Code 插件

此仓库也是一个 Claude Code 插件,其中打包了 MCP 服务,并基于它添加了三个斜杠命令。在 Claude Code 中:

/plugin marketplace add ibrahimhajjaj/seo-console-mcp
/plugin install seo-console@verdelic

它会注册 MCP 服务(通过 npx -y seo-console-mcp),并添加:

  • /seo-console:triage <siteUrl>:全面排查属性,并提供按优先级排序的行动计划
  • /seo-console:content <siteUrl>:根据 Search Console 数据,确定要创建或改进的内容
  • /seo-console:launch <siteUrl>:检查上线前/上线时的 SEO 准备情况

服务会自动在默认位置查找服务账号密钥(~/.config/seo-mcp/seo-mcp.key.json,设置向导会将密钥写入此处),因此标准安装无需配置。如果密钥位于其他位置,请在 Claude Code 运行环境中设置 GOOGLE_APPLICATION_CREDENTIALS(如果需要更高的 PageSpeed 配额,也请设置 SEO_MCP_PAGESPEED_KEY)。seo_audit 和 pagespeed 工具无需任何凭据即可使用。

若要从本地检出版本试用,无需使用插件市场:claude --plugin-dir .。

Claude Code(仅 MCP 服务)

为当前用户注册本地构建版本:

claude mcp add --scope user seo-mcp --env GOOGLE_APPLICATION_CREDENTIALS=/abs/path/seo-mcp.key.json -- node /abs/path/seo-mcp/dist/index.js

必须使用 -- 分隔符。它用于分隔 Claude Code 选项和 MCP 服务命令。

也可以使用 npx(无需本地构建):

claude mcp add --scope user seo-mcp --env GOOGLE_APPLICATION_CREDENTIALS=/abs/path/seo-mcp.key.json -- npx -y seo-console-mcp

用户级作用域会使该服务在你的所有项目中可用。如果要通过当前项目的 .mcp.json 共享注册信息,请使用 --scope project。

项目 .mcp.json:

{
  "mcpServers": {
    "seo-mcp": {
      "type": "stdio",
      "command": "node",
      "args": ["/abs/path/seo-mcp/dist/index.js"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "/abs/path/seo-mcp.key.json"
      }
    }
  }
}

Claude Desktop

将相同的服务条目添加到 Claude Desktop 配置文件的 mcpServers 下,然后重启 Claude Desktop:

{
  "mcpServers": {
    "seo-mcp": {
      "command": "node",
      "args": ["/abs/path/seo-mcp/dist/index.js"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "/abs/path/seo-mcp.key.json"
      }
    }
  }
}

若要在没有本地构建的情况下运行,请使用 "command": "npx" 和 "args": ["-y", "seo-console-mcp"]。

资源

seo://properties 会以 JSON 格式返回服务账号可访问的 Google Search Console 属性。每次读取时都会调用 Search Console,因此结果始终是最新的。

提示词

MCP 客户端会将这些提示词作为常见 SEO 工作流的起点,供用户选择:

  • seo_triage:确认属性、分析近期表现和机会、审计网站,并制定兼顾影响与投入的行动计划。
  • content_opportunities:将有证据支持的建议归类为要创建的内容和要改进的现有内容。
  • launch_seo_check:生成上线前技术准备情况和索引准备情况的通过/不通过清单。

工具

每个工具都会使用 Zod 验证输入。工具失败时会返回 MCP 错误结果,而不会终止服务。如果有可用信息,错误结果会包含 Google API 的状态、消息和原因。遇到 Search Console 403 错误时,还会说明如何授予服务账号属性访问权限。

list_properties

列出服务账号可访问的所有 Google Search Console 属性,并返回每个属性的精确 siteUrl 和 permissionLevel。无需输入。与 pagespeed、seo_audit、audit_site 和 indexnow_submit 不同,此工具需要服务账号凭据。

此工具不接受任何参数。

search_analytics

调用 searchanalytics.query,并返回精简的排名表和结构化行。

{
  "siteUrl": "sc-domain:example.com",
  "startDate": "2026-06-01",
  "endDate": "2026-06-28",
  "dimensions": ["query", "page"],
  "rowLimit": 100,
  "maxTableRows": 25,
  "dimensionFilterGroups": [
    {
      "groupType": "and",
      "filters": [
        { "dimension": "query", "operator": "contains", "expression": "seo" }
      ]
    }
  ],
  "type": "web"
}
参数类型必填默认值描述
siteUrl字符串是Search Console 资源,例如 https://example.com/ 或 sc-domain:example.com
startDate字符串否开始日期,格式为 YYYY-MM-DD;默认为 28 天前
endDate字符串否结束日期,格式为 YYYY-MM-DD;默认为今天
dimensions以下选项之一的列表:query、page、country、device、date、searchAppearance否["query"]用于对结果分组的维度
rowLimit数字否25返回的最大行数
startRow数字否0分页浏览大型结果时的起始行(从 0 开始计数)
maxTableRows数字否25文本表格中显示的行数上限;结构化行始终完整。0 = 仅显示摘要。
dimensionFilterGroupsJSON 列表否Search Console 维度筛选条件
type以下选项之一:web、image、video、news、discover、googleNews否结果类型。discover 是 Discover 信息流,googleNews 是 Google News 应用和 news.google.com,而不是 Search 中的“新闻”标签页。两者支持的维度都少于 web,且都不报告 query 维度
dataState以下选项之一:full、all否full = 已最终确定的数据(默认值,延迟约 2–3 天);all = 包含近期的部分数据
aggregationType以下选项之一:auto、byProperty、byPage否Search Console 汇总行的方式

maxTableRows 只限制文本表格;结构化行仍保持完整,因此设为 0 时会返回总计,但不显示表格,而不是返回空结果。discover 和 googleNews 支持的维度少于 web:两者都不报告 query 维度。

keyword_ideas

通过 Google Autocomplete 扩展种子词,并按发现类别返回规范化且去重的关键词创意。此功能使用公开的自动补全端点,无需额外的 API 密钥;除非提供 siteUrl,否则无需 Google 凭据即可使用。提供 Search Console 资源后,它会标注已获得排名的创意,并显示所选回溯时间范围内的平均排名、点击次数和展示次数。

{
  "seed": "technical seo",
  "siteUrl": "sc-domain:example.com",
  "language": "en",
  "country": "us",
  "expansions": ["alphabet", "questions", "prepositions", "comparisons"],
  "days": 90,
  "limit": 100
}
参数类型必填默认值描述
seed字符串是要扩展的种子关键词
siteUrl字符串否可选的 Search Console 资源,用于识别已获得排名的查询
language字符串否"en"作为 hl 传入的自动补全界面语言
country字符串否作为 gl 传入的自动补全国家/地区
expansions以下选项之一的列表:alphabet、questions、prepositions、comparisons否["alphabet","questions","prepositions","comparisons"]除种子词本身外要运行的建议扩展类别
days数字否90Search Console 回溯时间范围(天)
limit数字否100返回的关键词创意数量上限

默认会运行全部四种扩展类别。days 默认为 90,上限为 480;limit 默认为 100,上限为 500。单个自动补全请求失败时会计入失败次数,但不会丢弃成功获取的建议。

search_opportunities

查找展示次数较高且有望提升排名的查询。按查询和页面分组,默认筛选排名在第 5 至第 20 位之间的结果,并按展示次数加权排名对机会排序。

{
  "siteUrl": "sc-domain:example.com",
  "startDate": "2026-06-01",
  "endDate": "2026-06-28",
  "minPosition": 5,
  "maxPosition": 20,
  "minImpressions": 100,
  "limit": 25
}
参数类型必填默认值描述
siteUrlstring是要分析的 Search Console 资源
startDatestring否起始日期,格式为 YYYY-MM-DD;默认使用最近 28 天的时间范围
endDatestring否结束日期,格式为 YYYY-MM-DD;默认使用今天
minPositionnumber否要纳入的最低平均排名;默认为 5
maxPositionnumber否要纳入的最高平均排名;默认为 20
minImpressionsnumber否所需的最低展示次数;默认为 10
limitnumber否返回的最多机会数;默认为 50
compare_search_periods

将选定时间范围与紧邻其前、时长相同的时间范围进行比较。按查询或页面分组,返回点击次数增幅最大和降幅最大的结果。

{
  "siteUrl": "sc-domain:example.com",
  "startDate": "2026-06-01",
  "endDate": "2026-06-28",
  "by": "query",
  "limit": 25
}
参数类型必填默认值描述
siteUrlstring是要分析的 Search Console 资源
startDatestring否起始日期,格式为 YYYY-MM-DD;默认使用最近 28 天的时间范围
endDatestring否结束日期,格式为 YYYY-MM-DD;默认使用今天
byone of query, page否"query"用于比较效果的维度
limitnumber否返回的点击次数增幅最大和降幅最大的结果数量;每类默认为 50
ctr_gaps

查找展示次数较高、但点击率(CTR)低于相同四舍五入排名位置行平均值的查询或页面。预估错失的点击次数有助于确定重写标题和描述的优先级。

{
  "siteUrl": "sc-domain:example.com",
  "by": "page",
  "minImpressions": 250,
  "limit": 25
}
参数类型必填默认值描述
siteUrlstring是要分析的 Search Console 资源
startDatestring否起始日期,格式为 YYYY-MM-DD;默认使用最近 28 天的时间范围
endDatestring否结束日期,格式为 YYYY-MM-DD;默认使用今天
byone of query, page否"query"用于识别点击率差距的维度
minImpressionsnumber否所需的最低展示次数;默认为 100
limitnumber否返回的最多差距数;默认为 50
query_cannibalization

查找有多个页面获得 Search Console 展示次数的查询。结果会将相互竞争的页面分组,并按总展示次数对各组排序。

{
  "siteUrl": "sc-domain:example.com",
  "startDate": "2026-06-01",
  "endDate": "2026-06-28",
  "minImpressions": 25
}
参数类型必填默认值描述
siteUrlstring是要分析的 Search Console 资源
startDatestring否起始日期,格式为 YYYY-MM-DD;默认使用最近 28 天的时间范围
endDatestring否结束日期,格式为 YYYY-MM-DD;默认使用今天
minImpressionsnumber否每个查询-页面行所需的最低展示次数;默认为 10
list_sitemaps

列出站点地图路径、提交/下载时间、待处理/索引标记、警告/错误数量以及内容数量。

{
  "siteUrl": "https://www.example.com/"
}
参数类型必填默认值描述
siteUrlstring是Search Console 资源
submit_sitemap

提交站点地图并刷新其当前状态。这是一项写入操作。如果提交成功但状态刷新失败,结果仍会确认 Google 已接受写入,并报告刷新警告。

{
  "siteUrl": "sc-domain:example.com",
  "feedpath": "https://www.example.com/sitemap.xml"
}
参数类型必填默认值描述
siteUrlstring是Search Console 资源
feedpathstring是要提交的站点地图绝对 URL
dryRunboolean否false如果为 true,则报告将要提交的内容,但不写入 Search Console
delete_sitemap

从 Search Console 属性中移除已提交的网站地图。这是一项写入操作。将 dryRun 设为 true,即可预览移除操作,而不更改 Search Console。

{
  "siteUrl": "sc-domain:example.com",
  "feedpath": "https://www.example.com/sitemap.xml",
  "dryRun": true
}
参数类型必填默认值说明
siteUrl字符串是Search Console 属性
feedpath字符串是要移除的网站地图的绝对 URL
dryRun布尔值否false如果为 true,则报告将移除的内容,但不写入 Search Console
inspect_url

返回索引覆盖情况、判定结果、robots 状态、索引状态、抓取时间、获取状态、Google 和用户指定的规范网址、移动设备易用性以及富媒体搜索结果状态。

{
  "siteUrl": "sc-domain:example.com",
  "inspectionUrl": "https://www.example.com/products/widget"
}
参数类型必填默认值说明
siteUrl字符串是包含待检查 URL 的 Search Console 属性
inspectionUrl字符串是要检查的完整 URL
index_coverage

获取网站地图,并使用 Google 的 URL Inspection API 检查其中数量有限的一组直接页面 URL。返回已编入索引、未编入索引和失败的数量,未编入索引的 URL 及其覆盖状态、每个 URL 的完整结果,以及结果是否被截断。不会继续跟进网站地图索引中的子网站地图。

{
  "siteUrl": "sc-domain:example.com",
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxUrls": 20,
  "concurrency": 3
}
参数类型必填默认值说明
siteUrl字符串是包含网站地图 URL 的 Search Console 属性
sitemapUrl字符串是要检查的完整网站地图 URL
maxUrls数字否20要检查的 URL 数量上限
concurrency数字否3并发 URL Inspection 请求数

maxUrls 默认为 20,硬性上限为 50。concurrency 默认为 3,硬性上限为 5。这些限制用于保护 URL Inspection API 配额;每个属性的配额约为每天 2,000 次查询、每分钟 600 次查询。

request_recrawl

使用 URL Inspection API 检查 URL;如果有些 URL 尚未编入索引,则重新提交覆盖这些 URL 的网站地图。这种重新提交是 Google 唯一支持的批量重新抓取信号:没有请求编入索引的 API,Search Console 界面中的“请求编入索引”按钮也没有可通过程序调用的对应功能。URL 来自 urls,或从 sitemapUrl 中读取;要重新提交的网站地图由 feedpath 指定,默认使用 sitemapUrl。这是一项写入操作。将 dryRun 设为 true,即可检查并报告结果,而不重新提交。

{
  "siteUrl": "sc-domain:example.com",
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxUrls": 20,
  "dryRun": true
}
参数类型必填默认值说明
siteUrl字符串是包含这些 URL 的 Search Console 属性
urls字符串列表否要检查的指定 URL;省略时从 sitemapUrl 中读取
sitemapUrl字符串否要从中读取 URL 的网站地图;也是默认重新提交的网站地图
feedpath字符串否发现未编入索引的 URL 时要重新提交的网站地图;默认为 sitemapUrl
maxUrls数字否20要检查的网站地图 URL 数量上限
concurrency数字否3并发 URL Inspection 请求数
dryRun布尔值否false如果为 true,则检查并报告结果,但不重新提交网站地图

此工具与 index_coverage 共用相同的限制(maxUrls 最多为 50,concurrency 最多为 5),因为两者使用同一 URL Inspection 配额。只有网站地图中的 lastmod 时间足够新,重新提交才会促使 Google 重新抓取页面,因此请确保已更改 URL 的 lastmod 准确无误。

indexnow_submit

单次调用最多向 IndexNow 端点提交 10,000 个有变更的 URL。参与的搜索引擎(Bing、Yandex、Naver、Seznam、Yep)会彼此共享提交内容。Google 不使用 IndexNow;如需让 Google 重新抓取,请使用 request_recrawl。这是写入操作,并支持 dryRun。无需 Google 凭据。

{
  "urls": ["https://www.example.com/new-page", "https://www.example.com/updated-page"],
  "key": "your-indexnow-key"
}
参数类型必填默认值描述
urls字符串列表是有变更的页面 URL;一次提交仅涵盖一个主机
key字符串否IndexNow 密钥;默认为 SEO_MCP_INDEXNOW_KEY。网站上必须托管一个文本文件,路径为 https:///.txt(或 keyLocation),且文件内容只能包含该密钥
keyLocation字符串否托管密钥文件的 URL(当其不在 https:///.txt 时使用)
endpoint以下之一:api.indexnow.org、www.bing.com、yandex.com、searchadvisor.naver.com、search.seznam.cz、indexnow.yep.com否"api.indexnow.org"要通知的 IndexNow 端点;参与的搜索引擎会共享提交内容
dryRun布尔值否false若为 true,则报告将要提交的内容,但不会通知端点

一次提交中的所有 URL 必须属于同一个主机。密钥可以是任意由字母、数字或连字符组成、长度为 8-128 个字符的值,通过 key 或 SEO_MCP_INDEXNOW_KEY 传入;并且必须托管为文本文件,文件内容必须恰好是该密钥,路径为 https://<host>/<key>.txt(或同一主机上的 keyLocation)。由于密钥文件 URL 通常包含密钥,因此工具输出中绝不会回显密钥或 keyLocation。endpoint 默认为 api.indexnow.org;向任意参与的端点提交,都能触达所有参与的搜索引擎。

pagespeed

返回可用时的 CrUX 实际用户数据,包括 LCP、CLS、INP 或 FID、FCP 和 TTFB。还会返回 Lighthouse 类别得分,以及最多十项节省效果最高的优化机会。

{
  "url": "https://www.example.com/",
  "strategy": "mobile",
  "category": ["performance", "seo", "accessibility", "best-practices"]
}
参数类型必填默认值描述
url字符串是要分析的公开页面 URL
strategy以下之一:mobile、desktop否"mobile"Lighthouse 设备策略
category以下之一的列表:performance、seo、accessibility、best-practices否["performance","seo","accessibility","best-practices"]要运行的 Lighthouse 类别
apiKey字符串否可选的 PageSpeed Insights API 密钥;默认为 SEO_MCP_PAGESPEED_KEY

strategy 默认为 mobile。默认会请求全部四个类别。apiKey 为可选项;对本次调用,它会覆盖 SEO_MCP_PAGESPEED_KEY。

seo_audit

抓取最多 10 MB 的 HTML,支持重定向,超时时间为 15 秒,并使用标识性用户代理。提取标题和描述长度、canonical、robots、H1 和标题大纲、Open Graph 和 Twitter 标签、JSON-LD 类型、图片替代文本覆盖情况、内部/外部链接、字数、语言和 viewport。它会标记缺失或重复的标题、缺失的描述、缺失或多个 H1、缺失的 canonical,以及缺失或无效的 JSON-LD。

{
  "url": "https://www.example.com/landing-page"
}
参数类型必填默认值描述
url字符串是要审计的公开页面 URL
audit_site

抓取站点地图,并以受限并发方式审计其中最多 50 个页面 URL。支持站点地图索引,最多抓取五个子站点地图。结果包含每个页面的简要检查结果、单独记录的页面抓取错误、各项共性问题的计数,以及明确的截断数量和跳过数量。无需 Google 凭据。

{
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxPages": 20,
  "concurrency": 5
}
参数类型必填默认值描述
sitemapUrl字符串是要审计的公开站点地图 URL
maxPages数字否20要审计的页面数上限
concurrency数字否5同时进行的页面抓取数上限

maxPages 默认为 20,concurrency 默认为 5。两者的最大值分别为 50 和 10。

server_version

当前响应的服务构建版本、运行路径,以及它是否来自 npx 缓存。无需凭据。

此工具不接受任何参数。

有四个值看起来与此相同,但其实不是:npm 所称的 latest、版本范围解析出的版本、插件清单声明的版本,以及实际运行的版本。前三者都可以读取,但都无法回答这个问题。检查命令行工具也不能替代,因为它是单独的进程,会单独解析,因此同一台机器上运行的构建版本也可能不同。

安装路径最能说明问题。npx 会重复使用缓存的构建版本,而不会重新解析版本范围,也不会报错,因此即使其他所有信号都显示为最新,服务仍可能落后于已发布版本;_npx 下的路径就是证据。

更新后、报告任何信息前,都要调用此工具。 npm view <pkg> version 会读取本地注册表缓存;成功发布后几分钟内,它仍可能返回先前的版本,而 dist-tags 和版本数组中已经包含新版本。这里有两个会话分别得出发布失败的结论,但实际上并没有失败,而且涉及不同的发布。读取注册表无法区分发布缓慢和发布失败;询问正在运行的进程则可以。

wporg_plugin

按 slug 查询 WordPress.org 插件,并返回活跃安装数、下载量、评分、支持主题和版本日期。它使用公开的 wp.org API,无需凭据或 API 密钥。对于过去几天内发布的插件,如果某个字段看起来为空,则会以 possiblyLagging: true 报告,因为 wp.org API 对新发布插件的数据更新可能滞后;该字段可能已经在页面上显示。

{ "slug": "akismet" }
参数类型必填默认值描述
slug字符串是WordPress.org 插件 slug,例如 akismet
downloadDays数字否30获取每日下载历史的天数;0 表示跳过
includeVersionDistribution布尔值否true同时获取各插件版本的活跃安装占比
play_store_stats

读取应用的 Google Play 批量报告,并返回活跃设备安装量,以及按流量来源和搜索词分组的商店详情页访客数和获客数。hasPlaySearchRows 会明确说明是否存在 Play 搜索流量,因为没有搜索流量本身也是一项发现,而不是错误。报告会延迟数天,因此 lastDatePresent 表示文件中实际包含的最后日期,而不是今天。

{ "packageName": "com.example.app", "month": "202608" }
参数类型必需默认值描述
packageNamestring是Android 包名,例如 app.getpsst
monthstring否报告月份,格式为 YYYYMM;默认为当前 UTC 月份。如果提供了 startDate 和 endDate,则忽略此参数
installsDimensionone of overview, country, language, device, os_version, carrier, app_version否"overview"要读取的安装报告。overview 未由 Google 记录,但实际存储桶中存在;其他值是有文档说明的细分维度
includelist of one of ratings, crashes, reviews否[]要读取的其他报告类别。文件缺失属于正常情况:只有存在可报告内容时,Google 才会生成报告
storePerformanceDimensionone of traffic_source, country否"traffic_source"要读取的商店表现细分维度
storePerformanceTotalsboolean否false改为读取 total_ 版本的报告。这是不同的报告,并非同一报告的汇总:它只包含获客数,不包含访客数和转化率;对于某些应用,它涵盖的日期少得多,并将每次获客都归到一个占位来源
ratingsDimensionone of country, language, device, os_version, carrier, app_version否"country"评分报告的维度
crashesDimensionone of device, os_version, app_version否"app_version"崩溃报告的维度
startDatestring否时间范围的起始日期,格式为 YYYY-MM-DD。与 endDate 一同提供时,会读取该范围涵盖的每个月份,并筛选出范围内的行
endDatestring否时间范围的结束日期,格式为 YYYY-MM-DD

将 SEO_MCP_PLAY_BUCKET 设置为报告存储桶(gs://pubsite_prod_... 和不带前缀的名称均可),并将 SEO_MCP_PLAY_CREDENTIALS 设置为具有该存储桶读取权限的服务账号密钥;如果未设置,则回退使用 GOOGLE_APPLICATION_CREDENTIALS。存储桶的读取权限与 play_vitals 所需的 Play Console 邀请权限是不同的授权。month 默认为当前 UTC 月份。

app_store_listing

通过 App Store Connect 读取 App Store 页面,并根据 Apple 的限制检查各语言区域的字段:名称 30 个字符、副标题 30 个字符、关键词 100 个字符、宣传文本 170 个字符。Apple 只会索引名称、副标题和关键词字段,因此会报告描述,但不会为其评分;字段只要超出限制 1 个字符,就会被静默丢弃,而不是遭到拒绝,因此每个字段都会与其限制一并报告。宣传文本会单独指出,因为这些字段中只有它可以在正式版本上线后更改,而无需审核。

应用可以同时拥有正式上线记录和可编辑记录,因此由 state 选择要读取的记录,结果会说明所用的记录和版本。如果你请求的记录不存在,结果会报告另一条记录并注明原因,而不会将其冒充为你请求的记录。

报告的状态取自 appVersionState,若该属性不可用,则回退到已弃用的 appStoreState。两者表达相同的状态,但写法不同:正式上线的页面在新属性中显示为 READY_FOR_DISTRIBUTION,而已弃用的属性中显示为 READY_FOR_SALE。此更改前后捕获的输出仅字符串不同,页面本身并未发生任何变化。

{ "bundleId": "com.example.app", "state": "live", "platform": "IOS", "storefronts": ["us", "gb"] }
参数类型必填默认值说明
appIdstring否App Store Connect 数字应用 ID;请提供此项或 bundleId
bundleIdstring否Bundle ID;未提供 appId 时会解析为应用 ID;请提供此项或 appId
platformone of IOS, MAC_OS, TV_OS, VISION_OS否"IOS"要读取版本的 App Store 平台
stateone of live, editable否"live"读取正式上线页面,或正在准备发布的可编辑页面
storefrontslist of string否["us"]用于查询公开评分的店面国家代码

请提供 appId 或 bundleId。将 SEO_MCP_ASC_KEY_PATH 设置为 .p8 私钥,将 SEO_MCP_ASC_KEY_ID 设置为其密钥 ID;对于团队密钥,还需设置 SEO_MCP_ASC_ISSUER_ID(个人密钥没有发行者 ID)。密钥及其签署的令牌都不会出现在输出中。

团队密钥可以访问团队中的所有应用,因此一个密钥即可用于所有应用。其权限取决于授予它的角色,而 Apple 不允许之后更改密钥角色:唯一可用的操作是 Revoke。App Manager 密钥可以读取页面,但无法读取 Sales and Trends 或分析报告,因此这些操作需要另行创建一个具有 Admin、Finance 或 Sales and Reports 角色的密钥,而不是升级现有密钥。

ratings 是一个列表,每个请求的店面对应一个条目,而不是以店面为键的对象:

{ "ratings": [{ "storefront": "us", "source": "itunes-lookup", "averageUserRating": 4.5, "userRatingCount": 12 }] }

星级评分并非来自 App Store Connect。它的 API 完全没有汇总评分资源,只有年龄分级,因此评分取自公开的 App Store 店面查询,而此工具的其他所有字段都来自 App Store Connect。两个来源报告同一个看起来无论如何都相同的数字,这就是为什么每个条目都带有 source。来自商店页面的评分与来自私有 API 的评分不可互换,不应将它们视为同一种衡量结果进行比较。

list_snapshots

列出快照目录中已有的快照文档,按时间从新到旧排序,并显示每个快照的采集时间、覆盖时间范围,以及包含的属性、应用、软件包和插件数量。

{ "limit": 50 }
参数类型必填默认值描述
limit数字否50返回的快照数量上限,按时间从新到旧排序

如果没人能说明哪些文件存在,那么快照对就毫无价值;否则,每个调用方都只能维护一份属于服务的目录索引。目录中不是快照文档的文件也会连同错误一并列出,而不是被隐藏,因此你期望找到的名称不会悄无声息地被视为不存在。目录不存在时会返回空列表,而不是失败:说明尚未采集任何内容。列表旁边会显示 total 和 truncated,因为命令行只会打印结构化数据部分;如果在 limit 处截断,却没有这些字段,就会让人误以为这就是全部历史记录。

snapshot

将四类数据采集到一个带时间戳的文档中:每个属性的 Search Console 总量和热门行、App Store 列表、Google Play 安装量和流量,以及 WordPress.org 统计数据。该文档不包含 Core Web Vitals 字段数据、Android vitals、App Store 销售数据和 App Store 评论;这些数据可通过 crux_field_data、play_vitals、app_store_sales 和 app_store_reviews 读取。此工具用于记录一系列数据中的某个时间点,因为这些控制台都不会保留历史记录供你日后比较差异。

Search Console 总量取自日期维度,绝不会通过对查询维度求和得出。Google 会隐去低流量查询,因此按查询维度求和会低估数据,而这部分差距日后会被误读为一次从未发生过的下降。

无法读取的数据面会在原位记录错误,并列入 surfacesWithErrors,绝不会被省略,因为数据面悄无声息地消失,日后就会被误读为数据降至零。某个数据面响应缓慢时,只会超时,不会导致整个文档失败。

{
  "properties": ["sc-domain:example.com"],
  "apps": ["1234567890"],
  "packages": ["com.example.app"],
  "slugs": ["akismet"],
  "windowDays": 28,
  "outPath": "2026-09-03.json"
}
参数类型必填默认值描述
properties字符串列表否[]要采集的 Search Console 属性
apps字符串列表否[]App Store 应用,每项为数字应用 ID 或 bundle ID
packages字符串列表否[]Google Play 软件包名称
slugs字符串列表否[]WordPress.org 插件 slug
windowDays数字否28Search Console 时间范围(天),截至今天
platformIOS、MAC_OS、TV_OS、VISION_OS 之一否"IOS"应用数据面的 App Store 平台
storefronts字符串列表否["us"]App Store 评分所用的店面国家/地区代码
outPath字符串否快照目录内的文件名或路径(SEO_MCP_SNAPSHOT_DIR,默认值为 ~/.config/seo-mcp/snapshots);必须以 .json 结尾,或传入 auto,让文件名采用采集时刻。除非 overwrite 为 true,否则不会覆盖已有文件
overwrite布尔值否false替换 outPath 中的已有文件;如果不启用,已有文件将保留并报告

传入 outPath,即可将文档写入 compare_snapshots 日后可读取的位置;也可以传入 outPath: "auto",让文件名采用采集时刻(2026-09-04T00-15Z.json)。这样无人值守运行时会生成一系列文件,而不会永远覆盖同一个文件。文件名必须位于快照目录内,该目录默认为 SEO_MCP_SNAPSHOT_DIR 或 ~/.config/seo-mcp/snapshots;如果路径解析后位于该目录之外,或不以 .json 结尾,则会被拒绝。除非传入 overwrite: true,否则已有文件会保留并报告。由于这个字符串由模型选择,目录就是安全边界,可防止工具调用截断机器上的其他文件。当某个时间范围内没有展示次数时,排名和 CTR 会设为 null,而不是 0,因此空时间范围不会被误判为相较于真实数据出现了断崖式下跌。

compare_snapshots

读取两个快照文档,并报告它们之间的变化:每个属性的点击量、展示次数和排名;展示次数高于下限的页面级和查询级变动项;安装量和评分变化;App Store 版本和本地化数量变化;每种语言环境的名称、副标题、关键词、推广文本和描述长度,以及哪些字段超出了字符数限制;Google Play 按访客数和获客量划分的流量来源;以及 WordPress.org 的五星评分直方图。

{ "from": "2026-08-06.json", "to": "2026-09-03.json", "minImpressions": 100 }
参数类型必填默认值描述
fromstring是快照目录中的快照文件名或路径;latest 表示磁盘上最新的快照,previous 表示它之前的快照
tostring是快照目录中的快照文件名或路径;latest 表示磁盘上最新的快照,previous 表示它之前的快照
minImpressionsnumber否100忽略两侧展示次数都低于此值的页面排名变动

from 和 to 会在与 snapshot 的 outPath 相同的快照目录中解析,因此此工具只读取快照。两者都可以使用 latest 或 previous 代替文件名;这是几乎所有调用者真正需要的比较,也是唯一一种无需先列出目录内容就能请求的比较。两者都会跳过无法解析的文件;如果磁盘上只有一个快照,却请求 previous,工具会说明这一点,而不是将文档与自身进行比较。

此工具只做运算,不作判断。它不会告诉你某项变化是好是坏,也不会说明变化的原因,因为差异数据无法支撑此类结论。任一侧失败或缺失的数据面都会标记为不可比较并注明名称,因此采集失败绝不会被误认为变化;如果文件不是快照文档,工具会拒绝处理,而不会只解析其中一部分。

即使快照是在某个字段开始被采集之前拍摄的,也仍可进行比较。如果某一侧没有该字段,返回的差值会是 null,而不是将其视为变化;如果某个应用对的两侧都没有按语言环境划分的长度数据,则会报告 localesComparable: false,而不是返回一份字符数全部为零的空列表。

app_store_reviews

读取 App Store 客户评价及其回复,并根据星级或店面筛选,按照 Apple 自身的分页游标翻页。

{ "bundleId": "com.example.app", "rating": [1, 2], "territory": "USA", "limit": 100 }
参数类型必填默认值描述
appIdstring否App Store Connect 数字应用 ID;请提供此参数或 bundleId
bundleIdstring否Bundle ID;请提供此参数或 appId
ratinglist of number否仅返回这些星级的评价
territorystring否仅返回来自此店面的评价
sortone of -createdDate, createdDate, rating, -rating否"-createdDate"排序顺序;默认按时间从新到旧
limitnumber否100跨页返回的评价数量上限
maxPagesnumber否5跟进的最大页数

此工具报告 meanOfFetched 和 histogramOfFetched,绝不报告“评分”。这些数据只反映本次调用返回的评价;如果页面经过筛选或截断,平均值就会变成一个数值相同但含义不同的数据。App Store Connect 根本没有汇总评分资源,这一点可在 Apple 自己的 OpenAPI 规范中核实:所有匹配“rating”的路径都是年龄分级。

app_store_discovery

读取 App Store 列表文本之外的页面内容:搜索关键词(Apple 按地区保存的实际索引关键词列表)、应用标签、产品页面优化实验、自定义产品页面、应用内活动、地区可用性和评论摘要。

{ "bundleId": "com.example.app", "locales": ["en-US", "ar-SA"], "platform": "IOS" }
参数类型必填默认值描述
appIdstring否App Store Connect 数字应用 ID;提供此项或 bundleId
bundleIdstring否Bundle ID;提供此项或 appId
includelist of one of searchKeywords, appTags, experiments, customProductPages, appEvents, availability, reviewSummarizations否[]要读取的发现页面;留空则读取全部
limitnumber否50每项资源的行数
localeslist of string否["en-US"]按地区提供资源(如 searchKeywords)使用的地区设置
platformone of IOS, MAC_OS, TV_OS, VISION_OS否"IOS"需要指定平台的资源所用的平台
includeRowsboolean否false除计数外还包含每一行原始数据;默认关闭,以便汇总调用保持精简

每项资源都有各自的必需参数:searchKeywords 需要同时提供平台和地区筛选条件;appAvailabilityV2 是一对一关系,完全不接受 limit。如果此密钥或应用无法提供某项资源,则会报告 available: false,而不会返回空列表,因为“没有实验”和“无法读取实验”是不同的答案。

crux_field_data

来自 Chrome UX Report 的真实用户 Core Web Vitals,针对某个来源或单个 URL 提供当前 28 天的现场数据记录,包括 p75 值和完整直方图分箱。

{ "origin": "https://example.com", "formFactor": "PHONE" }
参数类型必填默认值描述
originstring否来源,例如 https://example.com;汇总其下的所有页面。请提供 origin 或 url,但不能同时提供
urlstring否单个页面 URL。请提供 origin 或 url,但不能同时提供
formFactorone of PHONE, TABLET, DESKTOP否设备类别;省略则合并所有设备类型
metricslist of string否要请求的指标名称;省略则返回所有可用指标

这是现场数据,而非实验室测试;Lighthouse 审核请继续使用 pagespeed。Google 正在停止提供 PageSpeed 自身的真实场景数据,因此现场测量将转到这里。样本数量不足以匿名化的来源会返回 hasData: false 和说明,而不是报错或返回零,因为 LCP 为零会被误认为是灾难性回退。

crux_history

相同的现场指标,以每周序列形式呈现,包含约六个月的历史数据。

{ "origin": "https://example.com", "formFactor": "PHONE", "collectionPeriodCount": 25 }
参数类型必填默认值描述
originstring否来源,例如 https://example.com;汇总其下的所有页面。请提供 origin 或 url,但不能同时提供
urlstring否单个页面 URL。请提供 origin 或 url,但不能同时提供
formFactorone of PHONE, TABLET, DESKTOP否设备类别;省略则合并所有设备类型
metricslist of string否要请求的指标名称;省略则返回所有可用指标
collectionPeriodCountnumber否要返回的每周周期数,范围为 1 到 40。文档所述历史数据约为六个月;实际可用数据由 API 决定

每个周期都是以每周为步长的 28 天滚动窗口,因此相邻数据点有三周重叠,单周环比变化并非独立变化。样本数量不足的周期会在序列中保留为 null,而不会被丢弃,以确保数值与 collectionPeriods 保持对齐。

app_store_sales

读取 App Store Sales and Trends:按 SKU 汇总每日、各地区、各 App 的下载量。

{ "reportDate": "2026-08-30", "frequency": "DAILY", "reportType": "SALES", "reportSubType": "SUMMARY" }
参数类型必填默认值描述
reportDate字符串否报告日期。DAILY 和 WEEKLY 使用 YYYY-MM-DD(WEEKLY 表示该周的结束日期),MONTHLY 使用 YYYY-MM,YEARLY 使用 YYYY。默认采用该频率下最近一个完整周期
frequencyDAILY、WEEKLY、MONTHLY、YEARLY 之一否"DAILY"报告周期
reportTypeSALES、PRE_ORDER、SUBSCRIPTION、SUBSCRIPTION_EVENT、SUBSCRIBER、INSTALLS、FIRST_ANNUAL 之一否"SALES"Sales and Trends 报告类型
reportSubTypeSUMMARY、DETAILED、SUMMARY_INSTALL_TYPE、SUMMARY_TERRITORY、SUMMARY_CHANNEL 之一否"SUMMARY"报告子类型
version字符串否默认版本不被接受时使用的报告版本,例如 1_0 或 1_3
includeRows布尔值否false除按 SKU 汇总外,还包含报告中的每一行原始数据

设置 SEO_MCP_ASC_VENDOR_NUMBER;App Store Connect 会在 Payments and Financial Reports 下、法律实体名称旁显示供应商编号。Sales and Trends 需要具有 Admin、Finance 或 Sales and Reports 角色的团队密钥。每日报告会在次日生成,因此默认报告日期是前两天,而不是今天。reportDate 的格式须符合对应频率的要求:DAILY 和 WEEKLY 使用 YYYY-MM-DD,其中 WEEKLY 表示该周结束的星期日;MONTHLY 使用 YYYY-MM;YEARLY 使用 YYYY。省略该参数时,各频率都默认采用最近一个完整周期。

在没有销售的周期中,工具会返回 hasData: false 并附带说明,而不是报错,以免让销售平淡的一天看起来像集成故障。单位数据来自 Sales and Trends 管道,该管道与 App Analytics 相互独立,数据可能不一致。

play_vitals

从 Play Developer Reporting API 读取 Android vitals:崩溃率、ANR 率、错误计数和启动指标,支持按日或按小时查询,并可选择 versionCode 或 countryCode 等维度进行细分。

{ "packageName": "com.example.app", "metricSets": ["crashRate", "anrRate"], "days": 28 }
参数类型必填默认值描述
packageName字符串是Android 软件包名称
metricSetscrashRate、anrRate、errorCount、slowStartRate、excessiveWakeupRate 之一的列表否["crashRate","anrRate"]要查询的 Android vitals 指标集
aggregationPeriodDAILY、HOURLY 之一否"DAILY"DAILY 使用 America/Los_Angeles 时区报告,HOURLY 使用 UTC
days数字否28查询过去多少天的数据
dimensions字符串列表否[]用于细分的维度,例如 versionCode 或 countryCode
pageSize数字否1000每个指标集返回的行数
includeRows布尔值否false除计数外,还包含每一行原始数据;默认关闭,以保持汇总调用的结果精简

将服务账号密钥设置为 SEO_MCP_PLAY_CREDENTIALS;若未设置,则回退到 GOOGLE_APPLICATION_CREDENTIALS。还必须在 Play Console 的 Users and permissions 下邀请该账号,并授予查看应用信息和应用质量的权限。令牌会针对 playdeveloperreporting 范围生成,该授权与 play_store_stats 所需的 Cloud Storage 读取授权彼此独立。一个账号可以同时拥有这两种授权,但只有存储桶授权的密钥在此处会收到 403 错误。

查询时间范围会限制在 API 声明的数据最新日期内,因为 API 会拒绝晚于该日期的结束日期,而查询到今天总会失败。结果会注明数据的实际最新日期,因此可以区分“截至已知日期没有数据”和“当天数据尚未生成,因而没有数据行”。此 API 不包含获客或转化数据;这些数据可通过 play_store_stats 获取。

Google Ads

通过 API 而非控制台读取账户。控制台表格会分页,因此只根据首页屏幕读取的计数可能有误,却不易察觉:有一个关键字计数被读成了 2,实际答案是 5,因为表格显示了 10 行,而总共有 14 行。这些工具会返回所有行。

设置 GOOGLE_ADS_DEVELOPER_TOKEN、GOOGLE_ADS_CLIENT_ID、GOOGLE_ADS_CLIENT_SECRET、GOOGLE_ADS_REFRESH_TOKEN 和 GOOGLE_ADS_CUSTOMER_ID(连字符可选)。还有两项便利设置:GOOGLE_ADS_CLIENT_SECRET_PATH 会从 Google Cloud 提供的 OAuth 客户端 JSON 中读取客户端 ID 和密钥;GOOGLE_ADS_ENV_FILE 指向一个现有的 .env 格式文件,其中包含上述任意变量,这样已有的刷新令牌就可以直接从原处读取,无需复制。进程环境变量的优先级高于文件。GOOGLE_ADS_API_VERSION 可覆盖 API 版本。

ads_campaigns

指定时间段内的广告系列名称、状态、每日预算、展示次数、点击次数、费用和转化次数。

{ "days": 30 }
参数类型必填默认值描述
days数字否30往前报告多少天,截止到今天
ads_keywords

每个关键字及其状态、有效 CPC 出价、审核状态、投放状态和指标。

ELIGIBLE 不代表正在投放。 它表示关键字已获批准且具备投放资格,暂停的关键字也会报告此状态。因此会同时返回 status:否则,暂停关键字的行与正在投放的关键字完全相同;刚暂停了 3 个关键字的人可能会以为暂停操作没有生效。暂停的关键字会在备注中列出,而不是直接省略,因为静默删除行会造成更深一层的同类问题:你询问某个关键字是否在账户中,却得不到任何结果。传入 status 可按需筛选。

{ "days": 30 }
参数类型必填默认值描述
days数字否30往前报告多少天,截止到今天
statusENABLED、PAUSED、REMOVED 之一否限定为一种关键字状态。若省略,则返回所有关键字并注明其状态,因为静默省略行会让此工具的计数像控制台计数一样出错
ads_ads

每条广告及其广告强度、政策审核状态、投放状态和指标。

{ "days": 30 }
参数类型必填默认值描述
days数字否30往前报告多少天,截止到今天
ads_ad_copy

读取广告实际写了什么。ads_ads 提供 ID、强度、审核结果和状态;此工具提供文案,而文案是每个创意相关问题都需要的信息,也是这类问题否则只能在浏览器中查找的原因。

{ "adGroup": "brand-exact" }
参数类型必填默认值说明
adGroup字符串否按名称限定为一个广告组。省略时,将读取账户中的每条广告;这可以回答标题是否在多个广告组中重复
adId字符串否按数字 ID 限定为一条广告,以读取原本应该投放的文案
includeRemoved布尔值否false包含已移除的广告。默认关闭:已移除广告的文案属于历史记录,会挤占正在投放的广告

每条标题和描述都会返回其固定位置设置和 Google 自己给出的效果标签,以及展示路径、最终 URL,还有导致状态受限或未获批准的政策主题。审核结果说明出了问题;主题则说明是什么问题。 APPROVED_LIMITED 旁边显示 TRADEMARKS_IN_AD_TEXT,就能知道该怎么修;若只有 APPROVED_LIMITED,就得去控制台查看。

它还能回答单条广告视图无法回答的两个问题:

  • 为什么强度是 Poor。 与 Google 的要求相比,素材数量是多少(3 of 15 headlines, 2 of 4 descriptions),以及有多少素材被固定位置。固定位置通常是有意设置的,通常不会体现在强度标签中,也是强度低于文案实际水平的常见原因。广告内重复的文本也会列出,因为重复素材会占用名额,却无法增加变化。
  • 某个标题是否在多条广告中重复。 如果同一标题文本出现在多条广告中,就会列出相关广告及广告组。即使同一广告组中的两条广告共用标题,也不代表它们是互相测试的两个变体;控制台也不会一眼显示这一点。

除非设置 includeRemoved,否则不会包含已移除的广告;并且只有响应式搜索广告会在这些字段中包含文案:其他广告类型会列出其类型,但不显示文案,而不会被视为没有文案的广告。此处不会读取附加到广告、广告系列或账户的素材资源,例如附加链接、促销信息和价格,因此在此输出中显得内容单薄的广告,仍可能同时通过附加素材进行投放。

ads_assets

广告下附加了哪些内容:附加链接、宣传信息、结构化摘要、促销、价格、电话和图片素材,涵盖三个层级,并显示每项素材的实际文案,而不只是其类型和 ID。

{ "campaign": "search-uk-us-2026-09" }
参数类型必填默认值描述
campaignstring否按名称将广告系列和广告组素材限定为一个广告系列。仍会列出帐户级素材,因为它们适用于每个广告系列,包括此广告系列
typeone of SITELINK, CALLOUT, STRUCTURED_SNIPPET, PROMOTION, PRICE, CALL, IMAGE否限定为一种素材类型。省略时会列出所有类型,包括此工具无法以结构化方式读取的类型
includeRemovedboolean否false包含状态为已移除的链接。默认关闭:已移除的素材属于历史记录,会挤占仍可投放的素材

促销素材会显示为 up to 20% off on Pro plan with code LAUNCH20, 2026-01-01 to 2026-01-31,而不是 PROMOTION #4417。这很重要,因为 Google 以百万分之一表示促销百分比,其中 1,000,000 代表 100%,所以原始字段是一个没人能看出折扣幅度的数字。价格素材会返回其商品和货币,附加链接会返回其描述。

读取结果前,有三点值得了解:

  • 帐户级素材适用于每个广告系列,因此即使指定了一个广告系列,也会列出这些素材。这也是 ads_ad_copy 的另一面:广告在那里看起来可能空空如也,但实际投放时可能附带四个附加链接和一项促销,而这些素材都未关联到该广告系列。
  • 已附加不代表已展示。 Google 会针对每次竞价决定是否展示素材,以及展示哪些素材。这里说明的是可供投放的素材,而不是实际展示的素材。
  • 没有匹配结果的广告系列名称会被拒绝,而不是返回结果。 之前,拼写错误会返回零行且不报错,旁边还会有一条说明帐户级素材也会列出的提示,导致读者以为帐户里没有素材。现在会先解析名称,再读取任何内容;如果名称未知,就会明确说明。输错广告系列名称的调用者,恰恰就是接下来会说“该广告系列没有附加链接”并据此采取行动的人。
  • 无法读取的层级会在原位报告错误。 三个层级对应三个独立查询;如果其中一个失败,另外两个仍会返回结果,并由 levelErrors 指明失败的层级。如果空列表悄悄代表“查询出错”,看起来就会像“没有附加任何内容”,而这恰恰是此工具被问及时最不该给出的答案。

对于此工具无法以结构化方式读取的类型,会列出其素材类型和字段类型,不再进一步解读,而不会编造摘要:归类为 BUSINESS_NAME 的 TEXT 素材,其内容大多由后半部分说明。只有字段类型与素材类型不同时才会显示,因为两者通常是同一个词,重复显示只会造成冗余。此处不报告素材指标。

ads_query

针对结构化读取未涵盖的问题,执行任意 GAQL SELECT 查询。GAQL 除 SELECT 外没有其他语句,因此此查询无法更改任何内容;不以 SELECT 开头的查询会被拒绝。

{ "query": "SELECT campaign.name, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_7_DAYS" }
参数类型必填默认值描述
querystring是GAQL SELECT 语句。GAQL 没有其他语句,因此此查询无法更改任何内容
ads_search_terms

实际触发广告的查询,以及每条查询匹配的关键字。这是付费版的 Search Console 查询维度,但也有同样的注意事项:Google 会隐藏搜索人数过少的词,因此未列出的词代表未知,而非不存在。

{ "days": 90, "minImpressions": 1 }
参数类型必填默认值描述
daysnumber否30回溯多少天进行报告,截止到今天
minCostnumber否0排除此时间范围内费用低于该值的搜索词
minImpressionsnumber否0排除展示次数低于该值的搜索词
zeroConversionsOnlyboolean否false仅保留没有带来转化的词,即用于添加否定关键字的列表
ads_changes

账号发生了哪些变更、变更时间、涉及哪些字段、由谁执行,以及变更来自工具还是浏览器中的用户:前者的 client 为 GOOGLE_ADS_API,后者为 GOOGLE_ADS_WEB_CLIENT。这是 ads_update 写入的所有内容以及手动进行的控制台编辑的审计记录。Google 仅保留 30 天记录,因此超出此范围的请求会被拒绝,而不会静默截断。

{ "days": 14, "limit": 100 }
参数类型必填默认值描述
daysnumber否14读取多少天的变更历史,截止到现在。Google 保留 30 天记录,超过此范围的请求会被拒绝
limitnumber否100返回最近的变更数
ads_negatives

已在广告系列、广告组或共享列表级别设置的否定关键字。否定关键字会阻止流量,但不会留下任何记录,因此,当某个关键字停止投放且看不出原因时,应检查此列表;添加可能已存在的词之前,也应先检查此列表。

{ "level": "all" }
参数类型必填默认值描述
levelone of campaign, adGroup, sharedSet, all否"all"要读取哪些否定关键字。在广告系列级别屏蔽的词会在该系列的所有位置被屏蔽;共享列表则适用于关联到它的每个广告系列
ads_negatives_update

以逐项枚举的方式批量添加或移除否定关键词。此处有意不提供模式或匹配全部形式:只需一个拼写错误,“屏蔽所有匹配 X 的词”就可能酿成波及整个账户的错误,而明确列出清单则不会犯这种错误。

{ "action": "add", "level": "campaign", "target": "search-uk-us", "keywords": ["free", "crack"], "matchType": "EXACT", "dryRun": false }
参数类型必填默认值描述
actionadd、remove 之一是添加否定关键词或移除现有关键词。移除和添加同样重要:错误的否定关键词不会显示任何信息
levelcampaign、adGroup 之一否"campaign"否定关键词的作用范围。广告系列级别的否定关键词会在该广告系列的所有位置屏蔽该词
targetstring是广告系列或广告组名称。必须精确匹配一个对象,否则不会更改任何内容
keywordsstring 列表是逐项枚举的否定词。不提供模式或匹配全部形式:选择器只需一个拼写错误,就可能屏蔽整个广告系列
matchTypeBROAD、PHRASE、EXACT 之一否"EXACT"每个词的屏蔽方式。BROAD 会屏蔽包含其所有词语的查询,这种设置可能悄无声息地扼杀广告系列
dryRunboolean否true报告将要发生的更改,以及哪些拟添加的否定关键词会屏蔽有效关键词,但不做任何更改
confirmboolean否false即使触发了防护条件,也执行此批次操作。试运行会列出触发的条件,因此此选项用于确认已阅读相关信息

否定关键词看起来很安全,因为它们只会减少支出,而这种直觉恰恰让它们变得危险。错误的出价会体现为支出。错误的否定关键词则什么也不会显示:流量不再到来,该词也会从搜索词报告中消失,并且没有任何地方会说明原因。在备份插件广告系列中添加 backup 作为广泛匹配否定关键词,会让该广告系列的流量归零;Google 不会报告错误,因为这完全是有效的否定关键词。

因此,在添加任何内容之前,系统都会将每个拟添加的否定关键词与该广告系列自身的有效关键词进行比对;除非设置了 confirm,否则会拒绝整个批次。拒绝信息会说明这可能造成的损失:"backup" as a BROAD negative would block this campaign's own keyword "wordpress backup", which served 41 impressions。此检查会尽可能贴近 Google 的匹配逻辑,但最终以 Google 为准。检查有意采取宽松策略,因为误报只会多出一句提示,而漏报却会毁掉整个广告系列。

移除操作不会进行冲突检查。移除否定关键词只会让流量重新进入,这会体现为支出增加,而不是悄无声息地消失。

ads_update

更改一个关键词的出价、广告系列的每日预算、广告系列状态、广告状态或关键词状态。这是这里唯一会产生费用的工具,因此它经过设计,可避免意外触发。

暂停关键词有独立的操作类型,因为降低出价并不等同于暂停。 降低出价的关键词仍处于启用状态,仍符合投放条件,也仍在争夺同一份每日预算。如果采取行动的原因是预算受限,降低出价并不会释放任何预算。

{ "kind": "budget", "target": "search-uk-us-2026-09", "value": "5.00", "dryRun": false, "confirm": true }
参数类型必填默认值描述
kindone of bid, budget, campaignStatus, adStatus, keywordStatus是要更改的内容:关键词的最高 CPC 出价、广告系列的每日预算、广告系列状态、广告状态或关键词状态。使用 keywordStatus 停止投放某个关键词;降低出价并不等同于暂停,因为该关键词仍符合投放条件,并继续争夺同一份预算
targetstring是关键词文本、广告系列名称或数字广告 ID。必须恰好匹配一个对象,否则调用会被拒绝
valuestring是出价或预算的新金额(美元),或状态的新值 pause 或 enable
dryRunboolean否true报告将要进行的更改以及触发了哪些保护条件,但不实际更改任何内容。默认启用:此工具会产生费用,因此必须明确请求才能执行更改
confirmboolean否false执行会触发保护条件的更改。在试运行中会被忽略。试运行会列出触发保护条件的原因,因此此选项确认的是已查看过的内容,而非未知情况

四道防线,各自都源于真实故障,而非假设:

  • 默认进行试运行。 dryRun 默认为 true,因此省略该参数时只会报告更改,然后停止。必填参数比命令行标志更能确保这一点,因为标志可能被忘记,而默认行为不会。
  • 必须恰好匹配一个对象,否则拒绝。 目标未匹配到任何对象,说明存在拼写错误;目标匹配到两个对象,说明请求更改的对象并非你指定的对象。这两种情况都会在写入前停止。
  • 以文字说明原因的保护条件。 更改金额超过当前金额的三倍、单笔出价或每日预算超过 $25,或暂停当前正在投放的对象,都会触发保护条件。更改预算时还会说明月度折算金额,因为每天 $30 看起来不多,折算后约为每月 $912。试运行会列出原因,而 confirm 确认的是你已查看过的内容,而非未知情况。
  • 写入后会回读数值。 HTTP 200 表示请求已被接受,并不代表系统存储的值就是你要的值。结果会包含 readBack 和 matches;如果不匹配,则会返回错误。

如果更改不会产生实际效果,工具会明确说明,而不会发送毫无意义的修改请求。

从命令行使用此工具时,除了 --allow-write,还需要 --allow-spend。一个标志同时授权“重新提交站点地图”和“将每日预算提高到三倍”,并不能构成有效的防护。

ads_keyword_create

向广告组添加一个关键词。这里唯一会创建而非更改内容的工具,因此它采用不同的防护措施。

{ "keyword": "wordpress backup plugin", "adGroup": "brand-exact", "bid": 1.2, "dryRun": false }
参数类型必填默认值描述
keywordstring是要添加的关键词文本。创建时会按原样使用;此工具不会推测变体
adGroupstring是要添加到的广告组。必须精确匹配一个广告组,否则不会添加任何内容
bidnumber是以美元计的最高每次点击费用出价。创建时没有当前出价可供比较,因此唯一的额度检查是上限
matchTypeone of EXACT, PHRASE, BROAD否"EXACT"关键词的匹配方式。默认使用 EXACT,因为它只购买文本所述内容;PHRASE 和 BROAD 会购买超出此处所写文本的内容,因此都会触发防护
dryRunboolean否true报告将添加的内容以及触发的防护,但不实际添加
confirmboolean否false即使触发了防护,也要添加。试运行会列出所有原因,因此此选项用于确认已阅读这些原因

此程序包中的其他所有写入操作都会读取当前值,将其与请求值比较,并在两者相同时拒绝操作。**创建操作没有当前值。**没有可比较的内容,也没有可据以拒绝的条件,因此必须用其他检查取代比较,而不是跳过检查;取代它的是重复项检查:

  • 如果目标广告组中已存在该关键词,则会拒绝添加,包括已移除的关键词。已移除的条件仍保留文本,而 Google 会以错误拒绝重复项,并指出界面中看不到的资源;如果没有事先提醒,遇到这种情况会令人困惑。
  • **如果帐户其他位置存在相同关键词,则会触发防护,而非拒绝操作。**有意在两个广告组中使用相同文本是可能的,因此直接拒绝会让合理的结构无法实现;不作提示则会让两个副本在无提示的情况下争夺同一预算。
  • 默认使用 EXACT。PHRASE 和 BROAD 都会购买超出此处所写文本的内容,因此都会触发防护。BROAD 是会为用户本不打算购买的搜索花费预算的匹配类型。
  • 写入后会回读关键词,并将其匹配类型和状态与发送的内容进行比较。创建操作返回 200 表示已接受,而非已存在且正确。

有一点不对称之处值得明确说明:创建的关键词会立即开始投放,而且与出价更改不同,它没有之前的状态可供恢复。要撤销操作,必须暂停或移除已创建的内容。

ads_update_batch

一次调用可更改多个关键词出价,或多个广告系列的每日预算。每次调用只能处理一种类型:出价总额和预算总额相加,会把每次点击的上限与每日金额相加,没有一句诚实的话能描述这个总和。

{ "kind": "bid", "changes": [{ "target": "wordpress backup", "value": 0.85 }, { "target": "backup plugin", "value": 0.6 }], "dryRun": false, "confirm": true }
参数类型必填默认值描述
kindone of bid, budget是每次调用只能处理一种类型。只有在一种类型内,总额保护才有意义:出价和预算的单位都是美元,状态则不是,混合计算会让总额无法解读
changesJSON list是一个包含多组键值对的命名列表,每组都有自己的值。没有选择器形式:枚举不会像模式那样造成错误
dryRunboolean否true解析并计算每个条目的金额,报告总额,但不进行任何更改
confirmboolean否false即使触发了保护条件,也执行批量操作。试运行会列出所有原因,因此这表示你已看过相关内容

这是一个包含多组键值对的命名列表,而不是应用于多个对象的规则。它没有“把所有内容都提高 20%”这样的操作,也没有选择器,因为此工具要防止的错误恰恰是选择器容易导致的错误:匹配范围超出调用者想象的模式,在任何人看到生成的列表之前就已应用。每个条目都会指明一个目标,以及它最终应达到的值;试运行会打印出这个列表供你核对。

与循环调用 ads_update 相比,它有四个不同之处:

  • 所有条目都完成解析后,才会写入任何内容。 如果第四个条目没有匹配项,前面三个条目就不会已经生效。循环调用单条更新可能中途失败,让账户处于无人决定过的状态,也不会有任何一行记录说明发生了什么。
  • 保护针对总额,而不只是每个条目。 五次上调即使各自都在单项上限内,加在一起仍是一笔很大的支出变更;逐项操作正是这种情况容易被忽视的原因。
  • 会指出与其余条目不一致的那一项。 十九个出价各自变动几美分,另一个变动 40 美元,所有条目仍可能都低于上限,但其中依然可能有误操作。某条目的变动若远大于本批次的中间值,就会被点名标出,因为拼写错误可能隐藏在可接受的总额之中,而这正是批量操作与逐项发送相同写入的区别。
  • 两个条目不能指向同一个对象。 同一目标出现两次会被拒绝;两个名称不同但共用同一预算的广告系列也会被拒绝,因为总额会重复计算该预算,而第二次写入会悄然覆盖第一次。

无论列表有多长,单项上限都保持不变,因为单项检查关注的是该条目是否有拼写错误,而批次越大,拼写错误也不会因此变得更可接受。批次总额上限则会随批次增长,但增长缓慢:二十个条目并不意味着风险是一个条目的二十倍,而是一次性做出的一个决定。若保护条件会对每个符合实际情况的批次都触发,那就不叫保护,而是打勾走流程;一旦 confirm 成为例行操作,它就会在无人阅读的情况下被传入。

无论是否触发保护条件,总额都会始终用文字说明,因为人们会读这句话,而保护机制只会在不符合条件时拦住你。预算的总额在两种情况下都以月度金额表示:这些每日预算合计为每天 $13.00,约合每月 $395,高于之前的每天 $10.00,约合每月 $304。

每次写入后,都会逐条读回所有值。结果会先指出哪些条目未能存储最初发送的值,再指出哪些条目已生效以及账户当前保存的值,因为部分写入时,关键问题永远不是有多少条,而是具体哪些条目成功了。请求被接受一次,只代表请求被接受,并不代表 N 个值都已存储;部分写入恰恰是批量操作最容易隐藏的情况。批次会作为单个请求发送,不会出现部分失败,因此写入被拒绝时不会留下任何内容;错误信息也会明确说明这一点,不会让你猜测。

与 ads_update 一样,从命令行调用时,除了 --allow-write,还需要 --allow-spend。

从命令行运行工具

上面的每个工具也都可以在没有 MCP 客户端的情况下运行。如果结果需要写入文件,以便后续运行时进行差异比较,就应使用这种方式:

seo-mcp query search_analytics --site-url sc-domain:example.com --start-date 2026-08-05 --out /tmp/sa.json
seo-mcp query --help                  # list the tools
seo-mcp query wporg_plugin --help     # list one tool's parameters

每次运行都会在标准错误输出中标明自身版本(seo-console-mcp 0.15.1 running wporg_plugin),因此标准输出始终可解析,--out 文件也始终是纯 JSON。结果不会以其他方式说明是由哪个二进制文件生成的,这可不是无关紧要的细节:npx 会复用缓存中的旧版本,且完全不会报错;安装失败时,之前的版本仍会保留并继续运行。当前正在运行的版本、版本范围解析出的版本,以及 npm 标记为最新的版本,这三个值通常一致,但彼此并不必然相同。

标志使用工具的参数名称并转换为 kebab-case(例如,siteUrl 对应 --site-url);camelCase 写法也同样可用。列表值以逗号分隔。结果会写入 --out 指定的位置;若未指定,则输出到标准输出。运行失败时会以非零状态码退出,并将错误消息写入标准错误输出。它运行的实现与 MCP 接口公开的实现相同,因此两者不会出现偏差。

会更改数据的工具(submit_sitemap、delete_sitemap、request_recrawl、indexnow_submit)在列表中标记为 (write),除非传入 --allow-write,否则拒绝从命令行运行。

只需一行 cron 配置即可记录运行历史;服务有意不负责管理调度器:你的机器已经有一个重启后仍会运行的调度器。

# every Monday at 06:00, one snapshot named after the moment it was taken
0 6 * * 1 seo-mcp query snapshot --properties sc-domain:example.com --out-path auto

开发

npm run dev
npm run build
npm test
npm run lint
npm run format
npm run format:check
npx tsc --noEmit

测试使用注入的 Google 客户端模拟对象,不会调用 Google 的线上服务。请勿提交服务账号密钥。除了 *.key.json,此存储库还会忽略 credentials*.json、.env*、PEM 文件和 P12 文件。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。