mcpField
U
upkeep-mcp

upkeep-mcp

ローカル
github.comクラウド・インフラ07 週間前に更新

upkeep-mcp について

upkeep-mcpは、複数のクライアントサイトを管理する人向けの、定期的なWebサイト保守チェック用MCPサーバーです。ドメイン、SSL、稼働状況、SEO、アクセシビリティを調べ、緊急度順のポートフォリオレポートを作成します。

主な機能

  1. 01ドメイン登録とDNSの確認
  2. 02SSL証明書と失効状況の確認
  3. 03稼働状況、リダイレクト、セキュリティヘッダーの確認
  4. 04SEO監査とサイトクロール
  5. 05緊急度順のポートフォリオレポート
  6. 06アクセシビリティ監査

活用シーン

  1. 01複数のクライアントサイトの保守課題を優先順位付け
  2. 02証明書の有効期限とドメイン設定の確認
  3. 03リンク切れや重複するページメタデータの検出

MCP 対応

保守チェックをMCPツールとして公開し、`portfolio://sites`リソースと`quarterly_report`プロンプトも提供します。ツールの結果には、絞り込み、並べ替え、レポート作成に使える構造化データが含まれます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"tiagocalado86-upkeep": {
"command": "npx",
"args": [
"-y",
"upkeep-mcp"
]
}
}
}
起動コマンドnpx -y upkeep-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmupkeep-mcp0.6.1

ツール

8

掲載時のツール一覧 · 2 週間前に更新

このツールにパラメーターはありません。

詳細

upkeep-mcp

継続的なウェブサイト保守で定期的に行う確認を担う MCP サーバーです。 ドメイン、SSL 証明書、稼働状況、テクニカル SEO、アクセシビリティを、 公開情報だけで確認できます。

単一のドメインではなく、保守契約で複数のクライアントサイトを管理する 人向けに構築されています。目標は、次の質問にすばやく答えることです。 今週、対応が必要なのは何ですか?

ステータス

初期開発段階で、各フェーズを公開しながら開発しています。ブラウザーを 必要としない機能はすべて実装済みで、現在利用できます。

ツール目的ステータス
domain_check登録期限、レジストラー、ネームサーバーの一致、DNS レコード、DNSSEC利用可能
ssl_check証明書の有効期限、発行者、チェーンの有効性、SAN の網羅範囲、TLS バージョン利用可能
uptime_checkHTTP ステータス、応答時間、リダイレクトチェーン、HTTPS へのアップグレード、セキュリティヘッダー利用可能
healthサーバー名、バージョン、Node.js のバージョン、稼働時間利用可能
seo_auditタイトル、メタ情報、見出し、canonical、robots.txt、サイトマップ、リンク切れ利用可能
site_crawlサイト全体の重複タイトル、リンク切れ、意図しない noindex利用可能
portfolio_report上記すべてをポートフォリオ全体で確認し、緊急度順に並べ替え利用可能
accessibility_audit実際のブラウザーで axe-core を使って WCAG 違反を確認利用可能

また、portfolio://sites リソース(ツール呼び出しを使わずにクライアントが 読み取れるサイト一覧)と、quarterly_report プロンプト(ポートフォリオの 実行結果を、クライアントが実際に読むレポートにまとめる)も提供します。

npm で公開されているため、1 つのコマンドでインストールできます。 インストールを参照してください。URL をクライアントに 案内するだけにして、何も実行したくない場合に備えて、公開インスタンスも 稼働しています。ホスト型インスタンスを参照してください。

使用例

> Is example.com about to expire?

example.com expires 2027-08-13 (346 days).
Registrar: RESERVED-Internet Assigned Numbers Authority.
Nameservers: elliott.ns.cloudflare.com, hera.ns.cloudflare.com.
Resolves: apex yes, www yes. DNSSEC: delegation signed.
> Check the certificate on expired.badssl.com

expired.badssl.com:443 certificate expires 2015-04-12 (-4159 days).
Issued by COMODO RSA Domain Validation Secure Server CA.
Chain does not verify (CERT_HAS_EXPIRED). Negotiated TLSv1.2.
Host matched via *.badssl.com.
Revocation not established: http://ocsp.comodoca.com could not answer: the
responder is not authorised to answer for this certificate.

Needs attention:
- [critical] The certificate expired 4159 days ago.
- [critical] The certificate chain does not verify: CERT_HAS_EXPIRED.
> Check the certificate on revoked.grc.com

revoked.grc.com:443 certificate expires 2026-10-18 (42 days).
Issued by Certera RSA DV SSL CA 2.
Chain verifies. Negotiated TLSv1.2.
Host matched via revoked.grc.com.
Revoked on 2025-09-18.

Needs attention:
- [critical] The certificate was revoked on 2025-09-18; browsers that check
  revocation will refuse the site.

2 つ目の例が示している点に注目してください。チェーンは検証に成功します。 Node 自体は失効確認を行わないため、この証明書はハンドシェイクを完了し、 信頼できるものとして報告されます。発行者に問い合わせて初めて問題が見つかります。

各ツールはテキストとともに構造化データも返すため、結果を並べ替えたり、 フィルタリングしたり、レポートに取り込んだりできます。各ツールの入力と 出力の詳細はexamples/に、ポートフォリオ全体のセッション (毎週の優先順位付け、詳細確認、前回の実行結果との比較で断言できることと できないこと)はexamples/conversation.mdにあります。

ツール

domain_check

入力:domain — ドメイン名のみ、完全な URL、または国際化ドメイン名です。サブドメインは登録可能ドメインに短縮されます。登録はこのドメインに対して行われるためです。

有効期限と残り日数、レジストラとその IANA ID、レジストリステータス、A/AAAA/NS/MX/TXT/CAA レコード、apex と www が名前解決されるかどうか、委任が DNSSEC で署名されているかどうか、またそのドメインからメールを送信できる主体について SPF と DMARC のレコードに何が記載されているかを返します。

メール認証情報は、ドメイン自身の DNS から読み取ります。SPF レコードは apex、DMARC レコードは _dmarc にあります。レコードが存在しない場合は情報として報告されます。これは今週発生した障害ではなく、継続的な改善事項だからです。レコードが存在するが誤っている場合は警告です。現時点で機能していないためです。SPF レコードが 2 つあると受信側は SPF 全体をスキップし、+all はインターネット上のすべての主体に、そのドメインからのメール送信を許可します。

DKIM は意図的に報告しません。DKIM キーは <selector>._domainkey にありますが、セレクターを検出することはできません。できるのは推測だけで、推測のたびに DNS クエリが 1 回必要です。これはサブドメインの列挙にあたり、このプロジェクトでは行いません。そのため、DKIM がないドメインと、セレクターが推測されなかったドメインは区別できないままにし、後者を前者として報告することはありません。

**次に、各ドメイン自身のネームサーバーに対して、TCP ポート 53 経由で再帰問い合わせを無効にした状態で、ゾーンについて直接問い合わせます。**これは再帰リゾルバーでは答えられない唯一の質問です。再帰リゾルバーは、いずれか 1 台のサーバーから受け取った内容を返すだけで、どのサーバーが回答したかは示しません。これにより、移行後も委任に残されたサーバーを検出できます。そのサーバーが REFUSED を返したり、ホスト名が名前解決されなくなったりすると、そこに到達したリゾルバーのクエリは遅延または失敗します。また、異なるバージョンのゾーンを保持しているネームサーバーも検出できます。これは「自分の環境では動くが、同僚の環境では動かない」という障害の原因になります。

障害と、まだ確認できていない状態は別々に評価します。リゾルバーはまず UDP で問い合わせますが、このサーバーが使えるのは TCP だけです。そのため、TCP を拒否するネームサーバーが壊れているとは限りません。sapo.pt の 4 台はすべて TCP を拒否しますが、ドメインは問題なく名前解決されます。シリアル番号の違いも info です。github.com は相互にゾーン転送を行わない 2 つのプロバイダーを利用しているため、8 台のネームサーバーのうち 4 台は 1656468023、残り 4 台は 1 を報告しますが、問題はありません。名前解決されないホスト名や、ゾーンに対する権威のない回答は、すべての人にとって障害となるため、警告です。全体をスキップするには checkNameservers: false を渡します。portfolio_report はこれを使用します。ポートフォリオではサイトごとにこの処理を行うことになり、ポート 53 を開けないデプロイ環境では、すべてのサイトが一度に「未確認」と評価されてしまうためです。 docs/adr/0020 には、DNS を手動で扱う理由と、意図的に確認対象から外している事項が記録されています。

ssl_check

入力:domain、省略可能なport(デフォルトは443)。

有効期限と残り日数、発行者、証明書チェーンが検証されるか、検証されない場合はその理由、証明書がカバーするホスト名と該当するSANエントリー、ネゴシエートされたTLSバージョンと暗号スイート、証明書が失効しているかどうかを返します。期限切れ、自己署名、信頼されていない証明書も拒否せずに検査して報告します。見つける価値があるのは、そうした証明書です。

失効はOCSPで確認します。リクエストが一切不要なため、サーバーがハンドシェイクに添付するレスポンスを優先します。添付されていない場合は、証明書に記載されたレスポンダーに直接問い合わせます。回答は、署名が発行機関に対して検証され、さらにCertIDが実際に提示された証明書に対応することが確認されて初めて信頼されます。そうでなければ、サーバーが失効した証明書と、別の証明書に対する有効なレスポンスを組み合わせるだけで、簡単に正常な結果を装えてしまいます。

健全な証明書の多くは、まったく確認できません。2025年以降、最大手の発行者であるLet's EncryptとGoogle Trust ServicesはOCSPレスポンダーを公開せず、CRLによって失効情報を配布しています。これはunavailableReasonとして報告され、検出事項は生成されません。これは認証局の判断であり、サイト所有者が対処できることではないためです。問い合わせを受けたレスポンダーが応答しなかった場合は別で、unknownが1件記録されます。

uptime_check

入力:url — 完全なURL、またはHTTPSで試行するドメイン名。

ステータスコード、応答時間、リダイレクトチェーンの全ホップ、プレーンHTTPがHTTPSにアップグレードされるか、HSTSポリシー、および報告対象となるセキュリティヘッダーを返します。

seo_audit

入力:url — 監査するページ。加えて省略可能なcheckLinks(デフォルトはtrue)とmaxLinks(デフォルトは25)。

タイトルとメタディスクリプションおよびその長さ、見出し構造、canonical、lang、viewport、Open Graph、hreflangの代替ページ、alt属性のない画像、robots.txtとサイトマップの状態、そして壊れている内部リンクを返します。

gzip圧縮されたサイトマップは、読み込む前に展開されます。gzip圧縮されているかどうかは、ファイル名やContent-Typeではなく先頭の2バイトで判定します。.xml.gzという名前でもgzip圧縮されていないファイルは多く、gzip圧縮されていてもtext/xmlとラベル付けされているファイルも多いためです。

次に、サイトマップをプロトコルのルールに照らして検証します。200を返して解析できるファイルが、正常に機能するファイルとは限らないためです。sitemaps.orgの名前空間がないルート要素は全体が破棄され、別のホスト上にあるエントリーは除外され、エスケープされていない&が1つあるだけでドキュメントは整形式XMLではなくなり、その後のエントリーはすべて失われます。各ルール違反は、違反するエントリー数と例を1つ添えて、一度だけ報告されます。5万件のURLに繰り返し発生する間違いも、修正すべき1つの問題として表示されます。W3C Datetime形式ではない<lastmod>や、7つの値以外の<changefreq>のように、ヒントが失われるだけのルール違反はinfo、エントリーまたはファイルが失われる違反はwarningとして評価されます。

robots.txtはほかのものをリクエストする前に読み込まれ、その指示に従います。対象ページ自体にも、すべての内部リンクにも適用されます。このクローラーに読み取りが許可されていないページは、その旨を報告し、取得しません。また、読み取れないrobots.txtは、RFC 9309の要件に従い、すべてを禁止するものとして扱われます。

> Audit the homepage of example.com

https://example.com/ answered 200. Title: "Example Domain".
1 h1, 0 images without alt, 0 internal links (0 checked, 0 broken).
Sitemap: the sitemap URL answered 404.

Needs attention:
- [warning] The page has no meta description, so search engines will write their own summary of it.
- [info] The page declares no canonical URL, which is how duplicate addresses for the same page get separated.
- [info] The page has no og:title or no og:image, so it will share poorly on social networks and in messaging apps.
- [info] There is no sitemap at https://example.com/sitemap.xml: the sitemap URL answered 404.
- [info] The site publishes no robots.txt. Nothing is blocked, but the sitemap cannot be declared there either.
site_crawl

入力:開始地点となるページの url と、任意の maxPages(デフォルトは25、最大100)および maxDepth(デフォルトは3)です。

そのページからサイトを幅優先でたどり、1ページだけでは把握できない情報を報告します。同じタイトルを持ち、同じ検索結果で競合するページ、同じメタディスクリプションを持つページ、リンク元のページも含めた内部リンク切れ、再構築後もインデックス登録を拒否しているページ、そしてサイトのうちどれだけに到達できたかを確認できます。

開始地点のオリジン内にとどまります。https://example.com と https://www.example.com は別のオリジンです。両者を行き来するクロールでは、一方のサイトのページがもう一方の重複ページとして報告されてしまいます。サイト外へリダイレクトするリンクはカウントしますが、そのままにします。robots.txt を読み取ったのはこのオリジンについてであり、ほかのサイトには適用されないためです。

クロールには、ページ数、深さ、2分間の期限という3つの上限があります。どの上限でクロールが終了したかと、見つかったものの未訪問のURL数を報告します。サイトの4分の1しか確認できなかったことを明記しないレポートは、レポートがないよりも悪いからです。robots.txt は最初に読み取られ、各URLへのリクエスト前に必ず遵守されます。読み取れない場合は、RFC 9309に従いクロールを拒否します。

この機能は意図的に portfolio_report には含めていません。ポートフォリオ全体で1サイトあたり25ページをクロールするのは、コストの規模が異なります。また、docs/adr/0010 で予測されていた理由を、docs/adr/0021 に記録しています。seo_audit の depth パラメーターではなく、独立したツールとした理由です。

> Crawl example.com and tell me what needs fixing

Crawled 25 pages of https://example.com, 3 levels deep.
2 broken internal links, 1 title used more than once.
Stopped at the page budget; 11 URLs were not visited.

Needs attention:
- [warning] 2 internal links are broken: https://example.com/old-pricing (it answered 404) linked from https://example.com/, https://example.com/team/ana (it answered 404) linked from https://example.com/team.
- [warning] 1 title is used by more than one page, so those pages compete with each other in search results; the widest is "Services" on 4 pages.
- [info] 6 of 25 pages have no meta description, so search engines will write their own summary of them.
- [info] The crawl stopped at the page budget with 11 URLs found and not visited, so everything here describes the part of the site that was looked at.
portfolio_report

入力:インラインの sites または file(デフォルトは sites.json)と、任意の checks および tags です。

上限付きの並行処理でポートフォリオ全体にすべてのチェックを実行し、対応が必要な順に並べたレポートを返します。稼働していないサイト、最も期限が迫っている項目、前回の実行から悪化した項目の順です。チェックできないサイトは検出結果として扱われ、レポート全体の失敗にはなりません。

> What needs attention across my sites this week?

3 sites checked: 0 critical, 2 warning, 0 unknown, 1 fine.

Needs action:
- [warning] Example Ltd: Plain HTTP does not redirect to HTTPS.
- [warning] Example Ltd: No Strict-Transport-Security header is sent.
- [warning] Example Net: Plain HTTP does not redirect to HTTPS.
- [warning] Example Net: No Strict-Transport-Security header is sent.

No change is reported: this server has not run a report on this portfolio before,
and the portfolio names no history file, so nothing survived the last restart.
History for this portfolio is kept in memory only. To compare across restarts,
add a "history" path to the portfolio file.

Nothing to do: Example Foundation.

再起動をまたいだ比較。 デフォルトでは、前回の実行結果はこのサーバープロセス内にのみ保存され、それ以外には残りません。そのため、毎日再起動するクライアントでは、比較できる期間は常に1日以内となり、四半期ごとのレポートは作成できません。ポートフォリオファイルに次の1行を追加します。

{ "version": 1, "history": "upkeep-history.json", "sites": [...] }

すると、実行結果はポートフォリオファイルと同じ場所に書き込まれます。次のレポートでは、再起動が何度あっても、最大90日前までの実行結果と比較できます。このファイルにはクライアント名と、どのクライアントで問題が発生したかが記録されるため、自分のアカウントだけが読み取れる状態で作成され、実行のたびに置き換えられます。この行がなければ、何も書き込まれません。理由についてはdocs/adr/0018に記録されています。

各サイトでは maxLinks を設定できます。これは seo チェックでリクエストする内部リンクの数で、0 を指定するとリクエストしません。この設定によって実行コストが決まります。20サイトで測定した場合、ポートフォリオの実行時間は seo なしで約8秒、ありで約40秒です。リンクチェックでは、ホストごとに0.5秒の間隔を空けて、リンクごとに1回リクエストするためです。

ポートフォリオファイルの形式はsites.example.jsonに記載されています。これを sites.json にコピーしてください。sites.json は .gitignore の対象なので、実際のクライアントリストがコミットされることはありません。file はクライアントがサーバーを起動したディレクトリを基準に解決されるため、そのディレクトリが自分のものではない場合はフルパスを指定してください。

accessibility_audit

入力:url。任意でstandardも指定できます(デフォルトはwcag2aa。ほかにwcag2a、 wcag21aa、wcag22aa、best-practiceがあります)。

ヘッドレスブラウザーでページを開き、axe-coreを実行します。違反したルール、各ルールに違反した要素数、先頭の数件のCSSセレクター、およびaxeが独自に判定できなかったルール数を返します。

ブラウザーが必要なツールはこれだけで、利用は任意です。このプロジェクトをインストールしても、何もダウンロードされません。必要な場合は、npx playwright install chromiumを一度実行してください。ブラウザーがない場合、ツールはその旨と該当コマンドを示し、ほかのすべてのチェックは続行されます。

自動ルールで見つかるアクセシビリティの問題は、およそ3分の1です。違反がないページは、機械でチェックできる部分に合格したということであり、使いやすいことと同じではありません。そのため、判定できなかったルールの数も併せて報告されます。

インストール

Node.js 22以降が必要です。それ以外は不要です。インストール時にブラウザーはダウンロードされず、accessibility_auditを除くすべてのチェックはブラウザーなしで動作します。

Claude Code
claude mcp add upkeep -- npx -y upkeep-mcp
Claude Desktop

サーバーをclaude_desktop_config.jsonに追加します:

{
  "mcpServers": {
    "upkeep": {
      "command": "npx",
      "args": ["-y", "upkeep-mcp"]
    }
  }
}

クライアントを再起動し、healthツールを実行するよう依頼してください。サーバーのバージョン、Node.jsのバージョン、プロセスの稼働時間が返されます。

デスクトップクライアントは、通常は/など、任意のディレクトリでサーバーを起動します。影響するのは1つだけです。portfolio_reportとportfolio://sitesリソースは、そのディレクトリでsites.jsonを探します。sitesをインラインで渡すか、portfolio_reportにフルパスを指定してください(file: "/Users/you/sites.json")。

ソースから実行

開発用、またはブランチを実行する場合:

git clone https://github.com/tiagocalado86/upkeep-mcp.git
cd upkeep-mcp
npm install
npm run build
claude mcp add upkeep -- node /absolute/path/to/upkeep-mcp/dist/index.js
ホスト型インスタンス

サーバーを実行できない方や、実行したくない方のために、公開サーバーがあります:

https://upkeep-mcp-1080119881249.europe-west1.run.app/mcp

リモートサーバーのURLを指定できるMCPクライアントから接続してください。Claudeでは、カスタムコネクターとして設定します。ホストをブラウザーで開くと、概要を説明するシンプルなページが表示されます。

**これはデモです。**認証も、稼働保証も、サポートもありません。また、予告なく停止する場合があります。サポート対象の実行方法はnpx -y upkeep-mcpです。これらのチェックが業務で重要なら、こちらをお使いください。

accessibility_auditを含め、すべてのツールを利用できます。イメージにブラウザーが含まれており、そのブラウザーからのすべてのリクエストには、サーバーのほかの部分と同じルールが適用されます。自分でサーバーを実行できない人が、実行できる人よりも機能の劣るツールを使うことになってはなりません。

実際に異なる点が1つあります。これは妥協ではなく、公開環境で実行することの性質によるものです。接続先は公開アドレスのみで、ポートも3つに限られます。443、平文HTTPがアップグレードされるかを確認する場合の80、およびドメイン自身が公開しているネームサーバー向けの53です。そのため、localhostを含め、ローカルネットワーク上のものはチェックできません。その場合はstdioサーバーを使用してください。

HTTPで自分のサーバーを実行する

トランスポートは、ホスト型インスタンスと同じものです:

npm run build
npm run start:http -- --port 8080

HTTPエントリーポイントは、ソケットを付けたstdioのものではありません。見知らぬ人はプロセスを起動した本人ではないため、上記のアドレスとポートのルールが適用され、呼び出し元ごとのレート制限を通じてトラフィックが許可されます。docs/deploying.mdではGoogle Cloud Runでの実行方法を説明し、docs/adr/0012ではガードと、それで防げないことを説明しています。

セキュリティとプライバシー

このサーバーは、認証情報を求めたり、受け取ったり、保存したりすることはありません。ブラウザーや DNS リゾルバーを使える人なら誰でも読める情報のみを読み取ります。

  • API キー、トークン、パスワードは、どのサービスに対しても一切使用しません。
  • 侵入的な動作は行いません。ポートスキャン、サブドメインの総当たり、脆弱性の調査は行いません。公開されている設定を調べるものであり、攻撃用のツールではありません。
  • ページをクロールする際は robots.txt を遵守し、ホストごとのレート制限を設け、連絡先 URL を含む識別可能な User-Agent を使用します。
  • 機密性の高い状態を永続的に保存しません。キャッシュは TTL 付きのメモリ内保存のみで、データベースはありません。このサーバーが書き込む唯一のファイルは、ポートフォリオファイルに history パスが指定されている場合に限り作成される、ポートフォリオ実行時のスナップショットです。
  • 問い合わせる第三者は、回答を保持するサービスのみです。レジストリ独自の RDAP サーバー、IANA の RDAP ブートストラップファイル、および node:dns では確認できない唯一の事項(DNSSEC 委任に署名があるかどうか)を確認するための cloudflare-dns.com です。どのサービスがどの情報を得るかは SECURITY.md に記載されています。

制限事項

できないことを隠すツールは、機能が少ないツールよりも問題があるため、率直に記載します。

  • 証明書失効リストはダウンロードしません。 失効確認は OCSP でのみ行います。CRL は、認証局がこれまでに失効させたすべてのシリアル番号をまとめたファイルです。ある証明書についての一つの疑問に答えるためだけに、数メガバイトのファイルを取得することになります。そのため、発行元がレスポンダーを公開していない証明書は、このツールが読み込みを拒んだファイルをもとに判定するのではなく、理由を添えて未確認と報告します。2025 年以降、これはウェブの大きな割合を占める Let's Encrypt と Google Trust Services にも当てはまります。詳しくは docs/adr/0017を参照してください。
  • OCSP 応答はある時点の状態を示すもので、継続的な通知ではありません。 レスポンダーはおよそ 1 週間先までの応答を事前に署名するため、good は「thisUpdate 時点では失効していない」という意味です。1 時間前に失効した証明書でも、認証局が次の応答を公開するまでは good と表示される場合があります。応答の古さを推測するのではなく確認できるよう、producedAt、thisUpdate、nextUpdate をすべて報告します。
  • 有効期限を公開していないレジストリもあります。 .de、.nl、.no、.au、.fi は、どのプロトコルでも有効期限を公開していません。結果ではレジストリ名を示してその旨を伝え、「不明」のままにしません。登録情報の取得には RDAP のみを使用し、WHOIS へのフォールバックはありません。その理由については docs/adr/0004で説明しています。
  • DNSSEC の検証は行いません。 委任に署名があるかどうかと、その情報をどこから取得したかを報告します。チェーンを検証したと主張することはありません。
  • 親ゾーンの委任情報とゾーン自体の情報は比較しません。 「レジストラに登録されているネームサーバーと、ゾーン内のネームサーバーが一致しない」というのも、よくある委任の問題です。これを調べるには、親ゾーンのサーバーにリファラルを問い合わせる必要があり、2 回目のホップと別の機能が必要になります。ここで確認するのは、ゾーン自体のネームサーバー同士が一致しているかどうかです。
  • 応答時間には接続の確立時間が含まれます。 DNS、TCP、TLS を含め、最初の応答ヘッダーを受信するまでの実時間を測定するため、サーバーの処理時間を示すものではありません。
  • seo_auditはサイト全体ではなく、1 ページを監査します。 ページ内のリンクをリクエストしてリンク切れを探しますが、クロールは行いません。2 階層目には進みません。サイトを監査するには、対象となるページごとに実行してください。
  • サイトマップは、XSD ではなくプロトコルの規則に照らして確認します。 ドキュメントが存在すること、<urlset> または <sitemapindex> を宣言していること、<loc> エントリの数、gzip 圧縮されて届いたかどうかを確認します。sitemap.xml.gz は読み込む前に展開しますが、展開後のサイズは 16 MiB を上限とし、展開爆弾は展開せずに拒否します。次に、コンシューマーがエントリを保持するかどうかを決める規則を確認します。具体的には、名前空間、<loc> の存在、絶対 URL であること、エスケープされていること、2048 文字以内であること、サイトマップと同じホストであること、<lastmod> が W3C Datetime であること、<changefreq> と <priority> が規定の範囲内であること、そして 50,000 エントリの上限です。ここでは XML パーサーもスキーマバリデーターも使用しないため、意図的に確認しない規則が 4 つあります。50 MB のサイズ制限、別のインデックスを列挙するインデックス、重複エントリ、そして <lastmod> が正しいかどうかです。これらについては docs/adr/0019に記載し、その理由も説明しています。規則は読み込んだ内容に対して確認するため、読み込み上限を超えたサイトマップは、切り捨て前のエントリをもとに判定し、レポートで切り捨てられたことを伝えます。nodejs.org にある別ホストへの余分なエントリは上限を超えた部分にあるため、報告されません。
  • 何千階層も深くネストされたページは、監査せずに拒否します。 HTML の解析コストはネストの深さのおよそ二乗になるため、異常に深いドキュメントを処理するとサーバーが数分間応答できなくなるおそれがあります。seo_auditは先に深さを測定し、拒否したことを報告します。
  • アクセシビリティは、機械で確認できる範囲でのみチェックします。 自動ルールで検出できるのは、実際の問題のおよそ 3 分の 1 です。ツールは axe が判定できなかったものを合格として数えずに報告しますが、ここで緑色の結果が出ても、アクセシビリティに関する保証にはなりません。
  • ここでは、ページの検索順位は一切判定しません。 seo_auditが報告するのは HTML の内容です。検索順位は、公開エンドポイントでは取得できない要素にも左右されます。
  • 「前回からの変更」は、別途指定しない限りサーバープロセスの稼働中だけ保持されます。 デフォルトでは前回の実行結果はメモリ上に保持され、どこにも書き込まれません。そのため、再起動したサーバー(デスクトップ MCP クライアントでは日常的に発生します)には比較対象がなく、何も変わっていないかのように見せず、その旨を伝えます。ポートフォリオファイルにhistoryのパスを追加すると、最大 90 日間、再起動後も比較できるようになります。指定がなければ何も書き込まれません。同じ方法で測定した実行結果同士だけを比較するため、稼働時間だけを素早く確認した実行の後で、実際にはない回帰を捏造することはありません。 docs/adr/0011と docs/adr/0018で、この選択について説明しています。
  • 保持するのは直前の実行結果のみで、履歴を連続して保存することはありません。 実行のたびに前回の結果を置き換えます。四半期ごとの傾向を追うには別の機能と、それに伴う保存方法の検討が必要ですが、これまで要望はありません。
  • 証明書とドメインは、異なる基準日数で判定します。 登録の警告は期限まで 30 日以内、証明書の警告は 14 日以内です。ACME クライアントは期限まで 30 日の時点で更新するため、それより早く警告すると、正常なサイトのほとんどで警告が出てしまいます。

ドキュメント

  • CONTRIBUTING.md — 開発環境のセットアップと、ツールの追加方法
  • docs/architecture.md — リクエストの処理の流れと、ネットワークを使わずにテストする方法
  • docs/prior-art.md — すでに一部を実現している MCP サーバー、それぞれの優れた点、この MCP サーバーが埋めるギャップ
  • docs/deploying.md — HTTP インスタンスの実行方法と、その特徴
  • docs/adr/ — 構造上の決定事項を記録した短い文書。ブラウザーをオプションとする理由も含みます
  • SECURITY.md — 脅威モデルと報告ポリシー
  • CHANGELOG.md

ライセンス

MIT — LICENSEをご覧ください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。