mcpField
S
SERP Title Width

SERP Title Width

本地服务
adsandcode.com商业与营销01 周前更新

关于 SERP Title Width

SERP Title Width 是面向 SEO 审核和网站构建流程的标题宽度检查工具,提供 MCP 服务和命令行工具。它按渲染像素宽度评估中日韩标题,并检查长度及标题集合中的重复尾缀等规则。

主要功能

  1. 01按像素宽度测量标题
  2. 02检查标题长度与风险等级
  3. 03扫描 HTML 文件或目录
  4. 04检测重复模板尾缀
  5. 05提供 MCP 服务和命令行工具

适用场景

  1. 01审核网站的中日韩页面标题
  2. 02在构建或 CI 中检查标题
  3. 03批量检测标题中的重复尾缀

MCP 相关

MCP 服务向客户端提供 `measure_titles` 和 `check_title_files` 工具,可测量标题文本或只读扫描本地文件与目录。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"adsandcode-serp-title-width": {
"command": "npx",
"args": [
"-y",
"mcp-server-serp-title-width"
]
}
}
}
启动命令npx -y mcp-server-serp-title-width

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

安装包
npmmcp-server-serp-title-width0.1.0

工具

2

收录的工具列表 · 更新于 6 天前

参数类型必填说明
titlesarray是与 <title> 中完全一致的标题字符串,已解码("&",而非 "&amp;")。

详细介绍

mcp-server-serp-title-width

检查中文、日文和韩文网页标题在 Google 搜索结果中是否能完整显示,依据的是渲染后的像素宽度,而不是字符数。 作为 MCP 服务(供 AI Agent 使用)和命令行工具(用于构建和 CI)提供。

文档和背景:adsandcode.com/en/open-source/serp-title-width

问题

网站审计工具和 SEO 插件通常通过统计字符数来判断标题长度,限制大约为 60 个字符。这条经验法则源自拉丁文本。在 Google 用于搜索结果标题的字体中,一个 CJK 表意文字、假名或韩文音节宽 22px,大约是一个普通拉丁字母的两倍。60 个这样的字符宽达 1320px,约为桌面搜索结果栏宽度 652px 的两倍。按字符数检查会让 CJK 标题通过,但 Google 会将其截断一半。

Google 只说明标题链接会根据需要截断;其文档没有给出字符数或像素宽度限制:

“标题链接会根据需要在 Google 搜索结果中截断” (Google Search Central,《影响搜索结果中的标题链接》)

因此,必须测量宽度。

模型

测量日期为 2026-09-18,使用 google.com 的 zh-TW(繁体中文,台湾)界面,运行于 Windows 上的 Chrome。测量方法是在页面中读取搜索结果标题的计算样式,并使用同一页面中的 canvas 测量字形宽度。

项目值
搜索结果标题字体Arial 22px,行高 28px
桌面搜索结果栏652px,在 1366px 和 1920px 视口宽度下相同
桌面端截断由 Google 服务器完成(截断文本并附加 ...),而非由 CSS 完成
移动端两行,每行 343px
全角字符22.0px(1em)。全角指东亚宽度为 W 或 F 的字符(UAX #11):表意文字、假名、韩文、全角标点、大多数表情符号
可打印 ASCII(U+0020-U+007E)Arial 字体自身的字宽,包含全部 95 个字符:例如 W 为 20.76px,O 为 17.11px,A 为 14.67px,数字为 12.24px,i 为 4.89px,空格为 6.11px
其他半角字符12.2px(估算值,未经测量)
零宽字符0px:U+200B-U+200D、U+2060、U+FEFF、变体选择符、表情符号肤色修饰符
表情符号序列每个字素簇计为一个字符:家庭表情符号、旗帜或带组合变音符号的字母都算一个字符

阈值:

等级宽度结果原因
safe不超过 572px(26 个全角字符)通过保守范围。为窄屏,以及你的 <title> 与 Google 显示的标题之间的差异留出余量
long超过 572px警告超出保守范围,但未进入临界区
edge超过 630px失败接近测得的桌面端单行显示上限
cut超过 648px失败宽于桌面搜索结果栏:桌面搜索结果会截断该标题

一个数字的宽度约为一个全角字符的 0.56 倍,因此“2026”占用的空间相当于 2.2 个表意文字。大写字母比数字宽得多:全大写的产品名称可能会让标题超出限制,而按字符数统计或将所有拉丁字母视为等宽的模型却会认为标题符合要求。

ASCII 字宽取自字体文件(Windows 上的 Arial Version 7.01),以字体单位计,通过 scripts/measure-arial.py 测量,并用三种方法交叉核验:以 2048px 运行的 Pillow、通过 fontTools 读取的字体字宽表,以及将 Chrome canvas 设为 22px arial 后调用的 measureText()。全部 95 个字符的结果误差均在 0.0001px 以内。

重新测量

如果 Google 更改标题字体大小,上面的所有数值都会不再准确。请在你关心的界面语言下打开 google.com 搜索结果页,并在浏览器控制台中运行:

(() => { const h = document.querySelector('a h3'), s = getComputedStyle(h);
  const c = document.createElement('canvas').getContext('2d');
  c.font = s.fontSize + ' ' + s.fontFamily;
  return { font: s.fontSize + ' ' + s.fontFamily,
           col: h.closest('div[data-hveid],div').getBoundingClientRect().width,
           cjk: c.measureText('貓').width, digit: c.measureText('0').width }; })()

如果 cjk 不再是 22,请更新 src/width.ts 中的 EM 和阈值。 如果字体发生变化,请使用 python scripts/measure-arial.py path/to/font.ttf 重新生成 ASCII 表格。不要直接用 Pillow 在 22px 下测量:字体微调会将每个字宽舍入到整数像素(W 会变成 21),而浏览器使用的是未经微调的字宽。

安装

需要 Node.js 18 或更高版本。无需 API 密钥,也无需网络访问。

MCP 服务
{
  "mcpServers": {
    "serp-title-width": { "command": "npx", "args": ["-y", "mcp-server-serp-title-width"] }
  }
}
CLI
npx -y -p mcp-server-serp-title-width serp-title-width ./public

或者使用 npm install -g mcp-server-serp-title-width 全局安装一次,然后运行 serp-title-width。

CLI 用法

serp-title-width <file|dir> ...           check <title> in .html/.htm files (directories are recursive)
serp-title-width --titles "t1" "t2" ...   check title strings
serp-title-width ... --json               machine-readable output
serp-title-width --selftest               run the ruler's positive and negative controls (use alone)

示例:

$ serp-title-width --titles "家常料理食譜站|滷肉飯做法・便當菜色・120道快速晚餐" \
    "旗艦手機開箱|SAMSUNG GALAXY S26 ULTRA VS GOOGLE PIXEL" "京都三天兩夜行程"
Checked 3 title(s). Safe <= 572px / edge > 630px / cut > 648px (Arial 22px, measured 2026-09-18).
------------------------------------------------------------------------------
[FAIL] (input 2)
   旗艦手機開箱|SAMSUNG GALAXY S26 ULTRA VS GOOGLE PIXEL
   688.3px / 31.3 full-width characters / cut
   [FAIL] Cut: 688px (31.3 full-width characters), 40px over the 648px line. Desktop results will truncate it.
   [warn] Keyword zone (text before the first ?:、,) is 688px, wider than the 343px first line on mobile, so the line breaks inside it.

[warn] (input 1)
   家常料理食譜站|滷肉飯做法・便當菜色・120道快速晚餐
   564.7px / 25.7 full-width characters / safe
   [warn] Keyword zone (text before the first ?:、,) is 565px, wider than the 343px first line on mobile, so the line breaks inside it.

[ok] (input 3)
   京都三天兩夜行程
   176.0px / 8.0 full-width characters / safe

------------------------------------------------------------------------------
Passed 2 / must fix 1

第二个标题有 47 个字符,低于常见的 60 字符限制,宽度为 688px。扫描文件时,只会列出有问题的标题,并附上它们相对于所给文件夹的路径。一次检查整个网站,以便检测出跨页面重复出现的模板尾部文本。

从磁盘读取内容的规则:

  • 目录会递归搜索 .html 和 .htm 文件。 跳过 node_modules 和所有以 . 开头的内容(例如 .git),且不会跟随指向文件夹的符号链接。
  • 显式指定的文件不论扩展名为何都会读取,因此 serp-title-width page.php.txt 可以正常运行。
  • 扫描到 20,000 个 HTML 文件后会以退出代码 2 停止,这通常表示该路径不是网站的构建输出目录。
  • 只检查文档 head 中的 <title>。注释、<svg>、<math>、<script>、<style>、<template> 和 <noscript> 中的标题,以及 head 结束后的标题,都会被忽略。
退出代码
Code含义
0所有标题均通过(允许有警告)
1至少有一个标题需要修复
2标尺未通过自身检查,或输入有误:未知选项、路径不存在、路径或子文件夹不可读、HTML 文件超过 20,000 个、未找到 <title>、--selftest 与其他参数同时使用

每次给出判定前都会运行自检。如果标尺无法证明它仍能标记已知的不合格标题并通过已知的合格标题,就不会给出判定。

MCP 工具

工具输入功能
measure_titlestitles: string[]测量每个标题,并一起检查整个标题集合
check_title_filespaths: string[]从本地文件或目录中读取 head 里的 <title>(递归,规则与 CLI 相同),然后运行相同的检查。只读

每个结果都包含 px、full_width_units(px / 22)、tier、fails 和 warns (每条发现的格式为 {rule, message}),以及针对整个标题集合的 boilerplate_tails,还有值为 pass 或 fix 的 verdict。服务启动时会运行自检,如果失败则拒绝启动。

规则

规则级别条件原因
length_cutfail宽度超过 648px超出桌面端栏的宽度
length_edgefail宽度超过 630px接近测得的桌面端单行上限
length_longwarn宽度超过 572px超出保守的安全行宽
separators在 572px 以内时 warn,超过 572px 时 fail、 和 , 合计超过 2 个在支撑此模型的样本中,Google 截断一条较长的 zh-TW 标题时,截断位置落在其中一个标点上。样本量较小:请将其视为启发式规则。未超出安全行宽的标题很少会被缩短,因此此时只发出警告
question_marksfail全角 ? 超过 1 个编辑规则:一个标题,只问一个问题。此规则并非来自 Google 文档
boilerplate_tailfail最后一个 、 或 , 之后的短语(4 个或更多字符)在标题集合中以相同结尾出现在超过 2 个标题中Google 的标题链接文档指出,模板化标题是个问题。不统计冒号之后的文本:同一文档建议将站点名称放在每个标题的开头或结尾,并用连字符、冒号或竖线分隔,因此每个页面都采用 …:Site Name 是推荐模式
keyword_zonewarn第一个 ? : 、 , 之前的文本宽度超过 343px在移动设备上,首行会在主要关键词中间换行
emptyfail标题为空或只有空白字符
stuffingfail相同的 2–4 个 CJK 表意文字连续出现 3 次或更多Google 的标题链接文档建议避免关键词堆砌。连续字符段会以贪婪方式拆分,因此此规则可检测 A|A|A 这类字面重复,而非不同变体

局限性

  • 仅针对一种设置进行测量。 google.com、zh-TW 界面、Windows 上的 Chrome,2026-09-18。其他界面语言、浏览器或操作系统可能使用不同的字体和宽度。
  • 未单独测量日语和韩语。 假定假名和韩文字母与全角字符相同(East Asian Width W),这符合它们的常规排版方式,但尚无人针对该模型测量 google.co.jp 或 google.co.kr。请将这些语言的结果视为估算值。
  • 未对字偶距进行建模。 宽度是逐个字符相加的。Chrome 还会调整部分字母对之间的间距,使文本略窄:上方的全大写示例在此处为 688.3px,在 Chrome 的画布中使用默认字偶距时为 686.7px。因此结果倾向于高估宽度。
  • ASCII 之外的半角字符宽度为估算值,按 12.2px 计算。它们在 Arial 中的实际宽度各不相同:é 和 – 为 12.24px,“ 为 7.33px,‘ 为 4.89px,Æ 和 ™ 为 22px。
  • 模糊宽度字符(East Asian Width A,例如 ① ※ …)按半角计算。根据后备字体的不同,它们的实际显示宽度可能更大。
  • Google 可能会显示其他内容。 除了 <title>,Google 还会从多个来源生成标题链接,包括标题、og:title、锚文本和 WebSite 结构化数据(其中包含站点名称);它可能会替换被认为是模板化或不准确的标题,也可能省略已重复显示的站点名称。因此,未出现在 <title> 中的文本也可能显示在结果中。标题通过规则并不能保证最终显示的内容。
  • 未测量 Emoji。 如果 Emoji 字素簇的第一个码位是全角字符,或带有 Emoji 呈现选择符 U+FE0F,则每个字素簇按一个全角字符计算。其他 Emoji(例如 Windows 上显示为两个字母的旗帜)则按其第一个码位计算。
  • HTML 读取方式简单。 head 中的 <title> 使用模式匹配查找,而非完整的 HTML 解析器。 &amp; &lt; &gt; &quot; &apos; &nbsp; 和数字字符引用会被解码;其他命名字符引用则按原样测量。

端口移植与一致性

这是同一模型的 Python 实现的 TypeScript 端口移植版,原实现未发布。此移植版有意做了四项改动:

原因改动
ascii-width全部 95 个可打印 ASCII 字符均使用 Arial 自身的宽度。首个参考实现仅有 14 个值,且 W 的值有误(18.33px,而非 20.76px);参考实现后来也采用了同一张表
zero-width零宽字符计为 0,每个字素簇计为 1
colon-tail: 后的短语不视为模板化尾缀
separator-tier分隔符多于 2 个时,仅在 572px 安全行宽内发出警告

已发布的代码可以切换回参考实现的行为,因此 scripts/parity.mjs --ref <title_check.py> 会检查两件事:该模式下的代码与参考实现完全一致;正常模式下的每处差异都由上述四个原因之一造成。与当前参考实现对比的结果:

  • 287 个混合标题(繁体中文、日语假名、韩文谚文、拉丁字母、数字、全角标点、表情符号、空白边界情况):在参考实现模式下,像素宽度、模板化尾缀以及未通过和警告规则的有序列表均完全一致。正常模式下有 27 项判定不同,且都有明确的原因:colon-tail 21 项、separator-tier 4 项、zero-width 3 项(单个标题可能有多个原因)。与首个参考实现对比时,ascii-width 也会改变 4 项判定,包括上面的全大写示例。
  • 从 U+0020 到 U+FFFF 的每个码位(不含代理项,共 63,456 个):在参考实现模式下,宽度仅在双方使用不同 Unicode 数据时有差异。与 Python 3.10(Unicode 13.0)对比时,有 1,613 个码位不同:其中 1,392 个未分配(CPython 3.12 之前的版本会将未分配码位报告为东亚宽度 F),143 个是在 Unicode 13.0 之后才分配的,还有 78 个在后续 Unicode 版本中从 N 变为 W(U+2630-U+2637、U+268A-U+268F、U+4DC0-U+4DFF)。与 Python 3.12(Unicode 15.0)对比时,有 85 个不同:即相同的 78 个码位,以及 7 个较新的分配码位。此软件包采用 get-east-asian-width 的较新数据。正常模式下另有 21 个差异,均为零宽字符。

许可证

MIT。

维护者

由 Ads & Code 构建并维护。

评论

支持 Markdown

第一次接触 MCP?

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

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