Contentgate

io.github.adsandcode由 GitHub 账号 adsandcode 发布v0.2.0更新于 Oct 29, 2026

Pre-deploy checks for content sites: keywords, translations, links, claims, page SEO/GEO audit.

已验证STDIO仅桌面开发者工具数据与分析

概览

AI 生成的概览

本地 MCP 服务器,对内容页面做上线前检查:关键词、翻译、内链、宣称、SEO/GEO 审计与页面比对。

可以做什么
  • 检查关键词覆盖情况,以及译文与原文在结构上是否仍一致
  • 核查页面正文是否链接到自家商业页面,并标记把结果说成事实的绩效宣称
  • 审计渲染后的页面:无 JavaScript 时的可见文本、JSON-LD、外链 rel、图片 alt 与宽度、favicon
  • 对页面内容做哈希,并据此判断 sitemap lastmod 日期是否诚实
  • 比较两个页面逐字相同的句子比例
适用场景
适合在撰写或发布内容页面时使用,希望在页面正式上线前而非上线后发现问题,例如关键词覆盖、翻译结构漂移、缺少内链、有风险的宣称或 SEO/GEO 标记问题。
运行要求
以本地 stdio 进程运行,通常通过 npx 启动 npm 包 mcp-server-contentgate,因此需要 Node.js。未声明任何认证、环境变量或请求头。各工具为纯函数:不访问文件系统或网络。
安装前请注意
工具只接收内容并返回判定结果,不会写入、发送或删除数据。默认参数需要调整:传入 exclude_classes,避免全站通用区块让关键词与内链检查形同虚设;当源语言与目标语言使用同一文字时,将 forbid_source_script 设为 false。默认的套话清单反映某位编辑的繁体中文偏好,应自行替换。

安装

在 SourceWeft 中

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

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

其他 MCP 客户端

参照 仓库 中的启动说明。

README

mcp-server-contentgate

MCP server for pre-deploy content checks. Catch the problem while the page is being written, not after it is live.

Documentation and background: adsandcode.com/en/open-source/contentgate

json
{  "mcpServers": {    "contentgate": { "command": "npx", "args": ["-y", "mcp-server-contentgate"] }  }}

Tools

ToolWhat it answers
check_keywordsDo the terms this page is meant to rank for actually appear in it?
check_translationIs this translation still structurally the same document as its source?
check_internal_linksDoes this page link to anything on its own site that makes money, outside the boilerplate? Absolute links count only for hosts in site_hosts.
check_claimsDoes this copy state outcomes as facts in a way regulated advertising rejects? A disclaimer counts only when its negation governs the claim itself.
sitemap_lastmodHas this page genuinely changed, or is the build about to lie about it?
content_hashStable hash of a page with volatile blocks removed.
audit_pageIs this page readable without JavaScript, marked up with JSON-LD that parses, honest about its outbound links, and complete in its images and favicon?
compare_pagesHow many sentences do these two pages share word for word?

Every tool is pure: content in, verdict out. No filesystem access, no network access, nothing written.

The guards are also importable as plain functions, and importing starts nothing: import { checkClaims, auditPage } from "mcp-server-contentgate".

Page audit

audit_page runs six checks on one rendered page and returns a verdict for each; pass checks to run fewer.

  • visible_text: characters readable with JavaScript off, leaving out <template> and elements with the hidden attribute. Google renders JavaScript; many AI crawlers read only the HTML the server sent, so an article injected by a script is invisible to them. 1200 is a house default, not a search-engine number.
  • structured_data: every JSON-LD block parses, the @type values you require are present (default Article, BreadcrumbList, Organization), and there is a dateModified. A required type is satisfied by its schema.org subtypes (BlogPosting and NewsArticle are Articles; Corporation, NewsMediaOrganization or a LocalBusiness is an Organization). A ProfilePage is not required to be an Article.
  • outbound_links: external links without rel nofollow, sponsored or ugc. Google does not require any rel on ordinary editorial links (only sponsored on paid or affiliate links and ugc on user-generated ones), so do not add nofollow to a citation to make this pass: list the sites you cite in cite_ok. Hosts are resolved the way a browser resolves them, so backslashes and extra slashes do not disguise where a link goes; registries anyone can register under (co.uk, github.io, pages.dev) are refused in cite_ok.
  • images: <img> without alt or width. alt="" is accepted.
  • favicon: home page only; an icon <link> in the head, in a format Google Search lists (BMP, GIF, ICO, PNG, JPEG, PPM, TIFF), read from the URL path or, for a data: URI, its MIME type.
  • stock_phrases: an editorial style list, not a detector of machine-written text. The default list is one editor's Traditional Chinese taste and is meant to be replaced: connectives such as 因此, and 然而, flag ordinary sentences. Pass your own, and always for any other language.

compare_pages splits both pages into sentences (on 。!? and on . ! ? before whitespace), ignores sentences under ten characters, and measures the shared share in characters in both directions.

Sources for each rule are in the repository README.

The one design rule

A guard that has never been shown to fail is decoration.

The server runs its negative tests at startup and refuses to start if they fail. A checker that cannot prove it still catches a known-bad input should not be answering questions about your content.

The same test file is run by the Python implementation in the same repository, and both are required to produce identical verdicts on every case.

Three behaviours worth knowing before you call it

Keyword matching never normalises whitespace. web hosting and webhosting are different strings with different search volumes. If you pass one, the other does not satisfy it.

Pass exclude_classes. A call-to-action block that appears on every page will otherwise satisfy check_keywords and check_internal_links everywhere, and both tools become decoration.

Set forbid_source_script: false when the target language shares the source script, such as Simplified Chinese from a Traditional Chinese source. Otherwise every document in that locale is reported as untranslated.

Python CLI

The same checks run as a deploy gate, reading your site from disk, in the contentgate package in the same repository.

Licence

MIT.

Maintainer

Built and maintained by Ads & Code.

来源:mcp/README.md,提交 7a892be

工具

8

check_keywords

Verify that target keywords actually appear in a rendered page. Every term tied at the highest search volume must appear at least `primary_min_hits` times; every other term at least once. Matching is literal and case-insensitive: whitespace is never normalised, because 'web hosting' and 'webhosting' are different terms with different search volumes.

输入参数html必填scopekeywords必填exclude_classesprimary_min_hits

check_translation

Compare a translation against its source document for structural drift: heading sequence, HTML tag sequence, table row count, internal link paths, price tokens, locale prefix on internal links, leftover source-script characters, introduced em dashes and emoji. This checks structure, not meaning: it cannot tell you a translation is good, only that it is no longer the same document.

输入参数locale必填source必填translation必填check_locale_prefixforbid_source_scriptrequire_front_matter

check_claims

Scan copy for affirmative performance claims of the kind that get finance, health and other regulated advertising rejected: guaranteed profit, stated win rates, promised returns. A disclaimer is not flagged when its negation governs the claim itself, shortly before it in the same clause (不保證獲利, 'we do not guarantee profit', 'no guaranteed returns'), or when the phrase is named as forbidden ('guaranteed profit claims are banned'). A negation elsewhere in the sentence does not count: 保證獲利,絕不會虧損 is still a claim.

输入参数text必填

sitemap_lastmod

Decide a sitemap lastmod date honestly. Hash the meaningful content of a page, compare it against the stored hash, and move the date only when the content genuinely changed. Stamping today's date on every URL every build teaches crawlers that the field carries no information.

输入参数body必填today必填previous_hashstrip_classesstrip_patternsprevious_lastmod

content_hash

Hash the meaningful content of a page, with volatile blocks and scripts removed. Use it to tell a real edit from a rebuild.

输入参数body必填strip_classesstrip_patterns

audit_page

Page-level SEO/GEO audit of one rendered HTML page, before it ships. Checks: visible_text (characters readable with JavaScript off, excluding <template> and elements with the hidden attribute; Google renders JavaScript, but many AI crawlers read only the HTML the server sent, so an article injected by a script is invisible to them); structured_data (every JSON-LD block parses, required @type values are present, dateModified exists; a required type is satisfied by its schema.org subtypes, e.g. BlogPosting or NewsArticle for Article; a ProfilePage is not required to be an Article); outbound_links (external links without rel nofollow, sponsored or ugc, with hosts resolved the way a browser resolves them, so backslash and extra-slash tricks are caught. Google does not require any rel on ordinary editorial links, only sponsored on paid or affiliate links and ugc on user-generated ones: do not add nofollow to citations to make this pass; list the sites you cite in cite_ok instead); images (<img> without alt or width); favicon (home page only: an icon <link> in <head>, in a format Google Search lists); stock_phrases (an editorial style list of filler phrases, meant to be replaced with your own; not a detector of machine-written text). Returns a verdict per check. Pure: nothing is fetched or written.

输入参数url必填html必填checkscite_okmin_charsrequire_typesstock_phrasesrequire_date_modified

compare_pages

Measure how many sentences two pages share word for word, using the text a crawler sees with JavaScript off (navigation and footers excluded). Sentences split on 。!? and on . ! ? followed by whitespace; sentences under ten characters are ignored. The share is measured in characters, in both directions, and the larger figure decides, because a short page copied into a long one is a small share of the long page and all of the short one.

输入参数html_a必填html_b必填max_share

版本历史

1
  1. v0.2.0最新Oct 22, 2026

评分

已满足适用检查项的 90%

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

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

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

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分