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 分