MCP Compliance について
MCP Complianceは、MCP仕様への準拠を検証するCLI、MCPサーバー、プログラム用APIです。開発者やCIでの利用を想定し、HTTPとstdioを対象に、仕様バージョンを選択して採点レポートを作成します。
主な機能
- 012つのMCP仕様バージョンを検証
- 02仕様バージョンの自動判定と指定
- 03宣言された機能に応じてテスト
- 04A〜Fの評価とスコアを出力
- 05CI厳格モード、JSON、SARIFに対応
- 06CLI、MCPサーバー、APIを提供
活用シーン
- 01リリース前のMCPサーバー検証
- 02必須テスト失敗時にCIを停止
- 03トランスポート、ツール、リソースの動作確認
MCP 対応
MCPサーバーとして、AIアシスタントに準拠テスト機能を公開します。CLIとAPIからもMCPサーバーを検査できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | はい | テスト対象の MCP サーバー URL(HTTP または HTTPS が必須) |
| auth | string | いいえ | Authorization ヘッダーの値(例:"Bearer tok123") |
| only | array | いいえ | これらのカテゴリまたはテスト ID に一致するテストのみを実行します |
| skip | array | いいえ | これらのカテゴリまたはテスト ID に一致するテストをスキップします |
| headers | object | いいえ | すべてのリクエストに追加するヘッダー(例:{"X-Api-Key": "abc"}) |
| retries | integer | いいえ | 失敗したテストの再試行回数(デフォルト:0、最大:10) |
| timeout | integer | いいえ | リクエストのタイムアウト(ミリ秒)(デフォルト:15000、最大:300000) |
| specVersion | enum | いいえ | テスト対象の MCP 仕様リビジョン。"auto"(デフォルト)ではサーバーを調査し、対応する最新リビジョンに基づいて評価します。"2025-11-25" または "2026-07-28" を指定すると、そのスイートを強制的に使用します。auto | 2025-11-25 | 2026-07-28 |
詳細
@yawlabs/mcp-compliance
ワンクリックでローカルの Yaw MCP 設定に追加され、すべての Yaw Terminal セッションで利用できるようになります。または、以下の手順で手動インストールできます。
任意の MCP サーバーが仕様に準拠しているかテストできます。 2 つのテストスイートで、MCP 2025-11-25 向けに 88 件、MCP 2026-07-28 向けに 103 件のテストを実施し、トランスポート、ライフサイクル、ツール、リソース、プロンプト、エラー処理、スキーマ検証、セキュリティを網羅します。このツールはサーバーをプローブし、対応する最新の仕様リビジョンを評価します。また、--spec-version でリビジョンを指定することもできます。HTTP エンドポイント(https://my-server.com/mcp)と stdio サーバー(npx @modelcontextprotocol/server-filesystem /tmp)のどちらにも対応しています。CLI、MCP サーバー、プログラム用 API を提供します。
Yaw Labs が開発・保守しています。
このツールを使う理由
MCP サーバーは急速に増えていますが、コンプライアンステストを実施せずに公開されるものがほとんどです。トランスポート処理の不具合、エラーコードの欠落、不正なスキーマ、機能に関する暗黙の違反はよく見られます。テストスクリプトを自作するのは手間がかかり、網羅性にも欠けます。
このツールは、こうした問題を解決します。
- 2 つの仕様リビジョンに 1 つのツール — MCP 2025-11-25(
initializeとセッションを使う時代)向けに 88 件、MCP 2026-07-28(ステートレス、リクエストごとの_meta、server/discover、キャッシュヒント、MRTR)向けに 103 件のテストを実施します。どちらも同じ 8 つのカテゴリ、つまりトランスポート、ライフサイクル、ツール、リソース、プロンプト、エラー処理、スキーマ検証、セキュリティを網羅します。HTTP 固有のテスト(CORS、TLS、ヘッダー検証、レート制限)は stdio では実行されません。2025-11-25 のスイートでは HTTP で 85 件、stdio で 55 件、2026-07-28 のスイートではそれぞれ 99 件と 75 件のテストを実行します。 - リビジョンを自動検出 —
server/discoverのプローブを 1 回実行するだけで、サーバーがどの時代の仕様に対応しているかをツールが判定します。両方の時代に対応するサーバーは、警告を表示して 2026-07-28 に基づいて評価します。--spec-versionでどちらかのリビジョンを指定できます。詳しくは仕様バージョンをご覧ください。 - 機能に応じたテスト — テストはサーバーが宣言した機能に合わせて調整されます。サーバーがツールに対応していると宣言した場合、ツールのテストは必須になります。サーバーが対応を宣言していない機能で誤って失敗することはありません。
- スコアを評価 — 必須テスト 70%、任意テスト 30%の加重スコアに基づき、A〜F の評価を付けます。準拠状況を 1 つの数値で伝えられます。
- CI に対応 —
--strictモードでは、必須テストが失敗すると終了コード 1 を返します。あらゆるパイプラインに組み込めます。 - 仕様を参照 — 各テストから、検証対象の MCP 仕様の該当セクションにリンクしています。何を、なぜテストしているのかが明確です。
- 3 つのインターフェース — 人向けの CLI、AI アシスタント向けの MCP サーバー、統合向けのプログラム用 API を提供します。
- 公開された方法論 — テスト方法論とルールカタログは CC BY 4.0 で公開されているため、誰でも互換ツールを構築したり、ルールをフォークしたりできます。
クイックスタート
リモート HTTP サーバー:
npx @yawlabs/mcp-compliance@latest test https://my-server.com/mcp
ローカル stdio サーバー(npm にある MCP サーバーの大多数):
# Pass the command directly, Inspector-style
npx @yawlabs/mcp-compliance@latest test npx @modelcontextprotocol/server-filesystem /tmp
# Or a local build
npx @yawlabs/mcp-compliance@latest test node ./dist/server.js
# With env vars
npx @yawlabs/mcp-compliance@latest test -E GITHUB_TOKEN=$GITHUB_TOKEN -- npx @modelcontextprotocol/server-github
グローバルにインストール:
npm install -g @yawlabs/mcp-compliance
mcp-compliance test https://my-server.com/mcp
これで完了です。文字による評価(A〜F)、テストごとの成功/失敗、準拠スコアを含む、色分けされたターミナルレポートが表示されます。
CLI の使い方
HTTP ターゲット
# Terminal output with colors and grade
mcp-compliance test https://my-server.com/mcp
# JSON / SARIF for scripting + GitHub Code Scanning
mcp-compliance test https://my-server.com/mcp --format json
mcp-compliance test https://my-server.com/mcp --format sarif > compliance.sarif
# Strict mode for CI — exits 1 on required-test failure
mcp-compliance test https://my-server.com/mcp --strict
# Auth (shorthand or full header)
mcp-compliance test https://my-server.com/mcp --auth "Bearer tok123"
mcp-compliance test https://my-server.com/mcp -H "X-Api-Key: abc"
# Focus the run
mcp-compliance test https://my-server.com/mcp --only transport,lifecycle
mcp-compliance test https://my-server.com/mcp --skip prompts,resources
mcp-compliance test https://my-server.com/mcp --verbose
stdio ターゲット
コマンドと引数を位置引数として渡します(MCP Inspector 方式)。ターゲットがこちらのオプションと衝突するフラグを必要とする場合は、区切りに -- を使用してください。
# npm-distributed stdio servers
mcp-compliance test npx -y @modelcontextprotocol/server-filesystem /tmp
mcp-compliance test uvx mcp-server-git
# Local build
mcp-compliance test node ./dist/server.js
# With env vars (repeatable -E, or --env-file)
mcp-compliance test -E API_KEY=secret -E REGION=us-east-1 -- npx my-server
mcp-compliance test --env-file .env -- node ./server.js
# Set working directory
mcp-compliance test --cwd ./services/mcp -- node ./dist/server.js
# Target uses a flag that collides with ours — use `--` to separate
mcp-compliance test --verbose -- node ./server.js --verbose
Windows では、npx やその他の .cmd シムは、シェル経由で起動することで自動的に処理されます。
仕様バージョン
このツールには、サポートする MCP 仕様のリビジョンごとにテストカタログが用意されています。2025-11-25(88 件のテスト:initialize ハンドシェイク、セッション、ping)と 2026-07-28(103 件のテスト:ステートレス、リクエストごとの _meta、server/discover、キャッシュヒント、MRTR)です。実行時に採点するリビジョンは、--spec-version で指定した 1 つだけです。
# auto (default): probe the server, grade the newest revision it speaks
mcp-compliance test https://my-server.com/mcp
# pin a revision — no probe, the named catalog runs regardless of what the server answers
mcp-compliance test https://my-server.com/mcp --spec-version 2026-07-28
mcp-compliance test https://my-server.com/mcp --spec-version 2025-11-25
# --list never connects: under auto (the default) it prints every catalog in its own
# section; --spec-version <date> previews just that one
mcp-compliance test --list --spec-version 2026-07-28 --transport stdio
デュアル時代のクライアントに関する仕様独自のルールに従って、auto がどのように判定するかを説明します。このツールは、仕様に準拠した 2026-07-28 の server/discover を 1 回送信します(HTTP では、これは事前接続確認も兼ねるため、検出に追加のラウンドトリップは不要です。stdio では最初のやり取りになります)。DiscoverResult、または最新のコード(-32020、-32021、-32022)を持つ JSON-RPC エラーが返された場合は、2026-07-28 が選択されます。それ以外の場合(-32601、-32000、400 の「未初期化」、404、HTML ページ、またはタイムアウトまでに応答がない場合)は、2025-11-25 が選択されます。最新のエラー本文を伴わない 401/403 も 2025-11-25 に分類されます。この場合、注記には時代を特定できなかったと記され、レポートの最初の警告(すべての出力形式で共通)には、以下の採点結果には意味がないことが示されます。Authorization ヘッダーが設定されていない場合、401、または WWW-Authenticate: Bearer チャレンジを伴う 403 は、認証が必要であると判断されます(注記は authentication required -- pass --auth、警告は --auth を指定して再実行するよう促します)。ヘッダーが設定されている場合、401、または error パラメーターを含む Bearer チャレンジを伴う 403 は、認証情報が拒否されたと判断されます(注記は credential rejected -- check --auth、警告にはそのエラーから取得した理由が示されます。たとえば invalid_token はトークンが無効または期限切れであることを、insufficient_scope はスコープまたは権限が不足していることを意味します)。それ以外の 403(トンネルのホスト名を通した SDK の Host 検証、Origin 検証、ゲートウェイ)は、ヘッダーの有無にかかわらず中立的な表現になります。注記には forbidden -- Host/Origin validation, a gateway, or missing credentials(ヘッダーがある場合は ... or token permissions)と記されます。警告には、JSON-RPC エラーメッセージがあればその本文の内容が引用され、Host/Origin 検証とゲートウェイの可能性が最初に示されます。また、ヘッダーがない場合は、サーバーが認証情報を必要とする場合に限り --auth が提案されます。フォールバックは、意図的に単一のエラーコードに基づく判定にはしていません。未知のメソッドを無視するレガシーサーバーも、タイムアウト後には正しく分類されます。レポートのヘッダーには理由が記載されます(auto-detected from server/discover: supportedVersions [2026-07-28]、... JSON-RPC error -32601, legacy、... no response, legacy)。JSON の warnings にも同じ注記が含まれます(Spec version auto-detected as <v> (server/discover -> <reason>). Pin with --spec-version to override.)。到達不能なサーバーは 2025-11-25 として採点され、サーバーを必要とするすべてのテストが失敗します(何も受信できなかった場合は、2026-07-28 の事後スキャンも、空の記録を対象に合格するのではなく失敗します)。
プローブには2つのタイムアウトがあります。stdioでは--startup-timeoutで制限されます。ターミナルモードでは約2秒後に、待機中であることと--spec-version 2025-11-25へのフォールバックを示す薄いステータス行がstderrに表示されるため、不明なメソッドに対して応答しないレガシーサーバーがハングしたように見えることはありません。プローブ中に子プロセスが終了した場合(initializeより前の不明なメソッドに対してディスパッチャーが例外をスローするレガシーサーバーの場合)、レポートには終了コードとstderr末尾を含む警告が表示され、新しいインスタンスを起動して2025-11-25として評価します。新しいインスタンスもinitializeに応答する前の起動時に終了した場合、警告ではプローブの有無にかかわらずサーバーが起動時に終了すると伝え、バージョンを固定するよう勧めるのではなく、コマンド、その引数、環境を確認するよう案内します。benchmarkも同じ方法で、プローブによって終了した子プロセスを再起動し、独自の--startup-timeoutでプローブを制限して、同じステータス行を表示し、警告を出力に含めます。HTTPではプローブはプリフライトであり、--preflight-timeoutで制限されます。プリフライトがタイムアウトした場合は、実行を2025-11-25にフォールバックする前に、--startup-timeoutの範囲内で1回再プローブします。これにより、起動が遅いサーバーも到達不能としてではなく、実際の時代に合わせて評価されます。
両方の時代に対応するサーバー(公式SDK 2.0で構築されたサーバーのデフォルト)は2026-07-28として評価され、レポートには、もう一方の時代とその時代に固定する方法を示す警告が含まれます。この判定は、supportedVersionsに2025-11-25が含まれている場合、または情報提供用のlifecycle-dual-eraプローブにInitializeResultが返された場合に行われます(SDK 2.0のサーバーは最新バージョンのみを通知しますが、それでもinitializeには応答します。stdioでは、両方の時代に対応するサーバーはプロセスごとに時代を固定するため、このプローブは新しいプロセスに送られます)。レガシー側も評価するには、--spec-version 2025-11-25を指定して再実行します。initializeには応答する一方で、仕様に準拠したserver/discoverを拒否するサーバーは、両方の時代に対応するのではなく、レガシー版のみです。lifecycle-dual-eraにはlegacy-only: ...と表示され、警告では--spec-version 2025-11-25(またはauto)を指定して再実行するよう案内されます。レポートのspecVersionは常に解決済みのリビジョンであり、autoではありません。
固定した実行では、サーバーの応答にかかわらず指定されたカタログが実行されますが、知っておくべき補足事項が2つあります。HTTPでは、プリフライトは引き続き最新のserver/discoverであるため、固定した実行でサーバーが明らかにもう一方の時代の応答を返した場合は警告が表示されます(Server answered the 2026-07-28 server/discover probe with a DiscoverResult ...; this run is pinned to 2025-11-25. Re-run with --spec-version 2026-07-28 (or auto) to grade it)。警告には時代を示すシグナル(DiscoverResult、JSON-RPC本文、またはHTTP 4xx)が必要です。5xxやHTMLページからは時代を判断できないため、警告は表示されません。また、supportedVersionsに2025-11-25が含まれる両対応サーバーを2025-11-25に固定した場合は、別の固定バージョンに誘導するのではなく、Server is dual-era (...); this run grades its 2025-11-25 side.と表示されます。さらに、2026-07-28に固定されたレガシー版のみのサーバーは、lifecycle-discoverと、6つの_meta/標準ヘッダー拒否テストの両方で評価不能になります。仕様に準拠したserver/discoverを拒否するサーバーが、形式に誤りのあるバリエーションも拒否したからといって、何かが証明されるわけではないため、これらの必須テストは成功扱いではなく失敗となります。
CIでautoを使う場合に知っておくべきことが2つあります。
- 設定を変更しなくても評価結果は変わることがあります。 サーバーを2026-07-28に対応するSDKにアップグレードした日から、
autoがテストスイートを切り替えます。テストIDも必須項目も新しいベースラインも異なります。自分で指定したときだけテストスイートを切り替えたい場合は、--spec-version(または設定ファイルの"specVersion")を固定してください。 diffは異なるリビジョンのレポートを比較せず(IDを比較できるのは同じカタログ内のみです)、固定すべき--spec-versionを案内します。SARIFのアップロードはリビジョンごとに追跡されます(automationDetails.idはmcp-compliance/<specVersion>/)。そのため、切り替えると古いアラートが黙って閉じられるのではなく、新しいアラートのセットが作成されます。--only/--skipの値は解決されたカタログに対して照合されます。カタログ内で一致するものがない値(たとえば、2026-07-28 の実行でのlifecycle-init)は、空の実行を黙って実行する代わりに警告として報告されます。また、実行するテストがない場合はAll tests passedではなくNo tests ran -- check --only/--skipと表示されます。2026-07-28 のテストスイートでは、絞り込みを行った実行でもサーバーが測定されます。絞り込みで除外された機能テストがキャッシュしていたであろうtools/list/resources/list/prompts/listの結果は、それを必要とするテストによって必要に応じて一度だけ取得されるため、--only security、--only schema、--only lifecycleでは、テストがスキップされて合格するのではなく、実際のチェックが行われます。このようなリスト呼び出しが失敗し、その-listテストが絞り込みで除外されている場合、リストを必要とするチェックは、記録された理由(tools/list failed (JSON-RPC error -32603 (boom)); no tools list to validate)とともに失敗します。これにより、リストが壊れているのに A と評価されることはありません。ターゲットのトランスポートでは無効になるテスト(stdio サーバーでのtransport-postなど)にしか一致しない--onlyの値も警告され、--listでは一覧表示される各カタログの下に同じ警告が表示されます。
オプション
| オプション | 適用対象 | 説明 |
|---|---|---|
--spec-version <v> | both | 評価する MCP 仕様の改訂版:auto(サーバーを調査し、新しい方を優先)、2025-11-25、または 2026-07-28(デフォルト:auto、または設定内の specVersion)。仕様バージョンを参照してください |
--format <format> | both | 出力形式:terminal、json、sarif、github、markdown、または html(デフォルト:terminal) |
--config <path> | both | 設定ファイルからデフォルト値を読み込みます(デフォルト:cwd 内の mcp-compliance.config.json) |
--output <file> | both | 実行後、指定したパスにローカル SVG バッジを書き込みます |
--list | both | 現在のフィルターで実行されるテスト ID を表示して終了します(接続は行いません。デフォルトの --spec-version auto では、各カタログを個別のセクションに表示し、--spec-version <date> では指定したものをプレビューします) |
--transport <kind> | both | http または stdio で絞り込みます(ターゲットが指定されていない場合に --list と併用したときのみ使用) |
--strict | both | 必須テストに失敗した場合、終了コード 1 で終了します(CI 用) |
--min-grade <grade> | both | 成績がこのしきい値(A~F)を下回った場合、終了コード 1 で終了します |
-H, --header <h> | HTTP | すべてのリクエストにヘッダーを追加します。形式は "Key: Value" です(複数回指定可能) |
--auth <token> | HTTP | -H "Authorization: <token>" の省略形です |
-E, --env <var> | stdio | stdio コマンド用の環境変数を設定します。形式は "KEY=VALUE" です(複数回指定可能) |
--env-file <path> | stdio | ファイルから環境変数を読み込みます(1 行につき KEY=VALUE を 1 つ指定) |
--cwd <dir> | stdio | stdio コマンドの作業ディレクトリ |
--watch | stdio | Ctrl+C が押されるまで、カレントディレクトリ内のファイルが変更されるたびにテストスイートを再実行します(デバウンス 500 ms。node_modules、.git、dist、coverage、ビルドキャッシュ、ログ/スワップ/一時ファイルは無視します)。stdio ターゲットのみ対象です。また、--format が terminal、markdown、html の場合のみ使用できます。--strict と --min-grade は適用されません |
--timeout <ms> | both | 初回のやり取り後に適用される、リクエストごとのタイムアウト(ミリ秒、デフォルト:15000) |
--startup-timeout <ms> | both | サーバーからの最初の応答に使える時間:auto 時の stdio 時代判定プローブ、いずれかのトランスポートでの 2025-11-25 initialize ハンドシェイク、および HTTP でプリフライトがタイムアウトした場合に送信される 2 回目の時代判定プローブ(デフォルト:max(--timeout, 60000)。stdio サーバーの起動前に行われるコールド npx キャッシュの取得も対象です) |
--preflight-timeout <ms> | HTTP | プリフライト server/discover リクエストの期限です。auto では時代判定プローブも兼ねます。ここでタイムアウトした場合、実行時に 2025-11-25 がデフォルトとして使用される前に、--startup-timeout の範囲内で 1 回再試行します(デフォルト:min(--timeout, 10000)) |
--retries <n> | both | 失敗したテストの再試行回数(デフォルト:0) |
--only <items> | both | 指定したカテゴリまたはテスト ID に一致するテストのみ実行します(カンマ区切り) |
--skip <items> | both | 指定したカテゴリまたはテスト ID に一致するテストをスキップします(カンマ区切り) |
--concurrency <n> | both | 同時に実行する並列安全テストの最大数(デフォルト:1。値を増やすと所要時間を短縮できますが、タイミングに敏感なサーバーの動作に影響する可能性があります) |
--verbose | both | 各テスト結果を実行時に PASS、FAIL、SKIP として表示します(stdio の stderr も転送します) |
--no-color | both | 色付き出力を無効にします(NO_COLOR 環境変数でも同じ設定になります) |
CI との連携
GitHub Action(任意の .github/workflows/*.yml に追加します):
- uses: YawLabs/mcp-compliance@v0
with:
target: 'node ./dist/server.js' # or a URL like https://my-server.com/mcp
format: github # ::error per required failure, ::warning per optional failure and per report warning, ::notice summary with the spec version
strict: 'true' # exit non-zero if any required test fails
min-grade: 'A' # also exit if grade slips
spec-version: auto # or pin 2025-11-25 / 2026-07-28; the resolved value is the `spec-version` output
CLI の手動実行:
# GitHub Actions: ::error per required failure, ::warning per optional failure and per
# report warning, and a ::notice summary naming the grade and the spec version graded
mcp-compliance test https://my-server.com/mcp --format github --strict
# Slack/Linear/PR comment: drop the body straight into a comment
mcp-compliance test https://my-server.com/mcp --format markdown > report.md
# HTML report (self-contained, share anywhere — issue comments, S3, GitHub Pages)
mcp-compliance test https://my-server.com/mcp --format html > report.html
# Block release if grade slips below B
mcp-compliance test https://my-server.com/mcp --min-grade B
# Preview which tests will run before connecting (handy for --only/--skip authoring)
mcp-compliance test --list --transport stdio --skip security --spec-version 2026-07-28
# Diff two runs — exit 1 if anything that was passing (or skipped) is now failing;
# checks that start or stop skipping are listed as "Newly skipped" / "No longer skipped" and never fail the diff.
# A baseline from an earlier version works too: its skips are read from their wording, and both
# reports are scored from their results as this version scores them (skips left out).
# Both reports must grade the same spec revision; pin --spec-version on both runs
# so a server upgrade cannot flip the suite under the baseline.
mcp-compliance test https://my-server.com/mcp --format json --spec-version 2026-07-28 > current.json
mcp-compliance diff baseline.json current.json
# Watch mode for stdio dev loop — re-runs on file changes in cwd
mcp-compliance test --watch -- node ./dist/server.js
# Latency benchmark (--spec-version and --startup-timeout work as for test)
mcp-compliance benchmark -- node ./dist/server.js -r 200 -c 4
Docker:
docker run --rm ghcr.io/yawlabs/mcp-compliance test https://my-server.com/mcp
設定ファイルのひな形を作成する
mcp-compliance init
対話形式のプロンプトで、トランスポート(http/stdio)、コマンド/URL、環境変数、タイムアウト、厳格モードを順に設定すると、コミット可能な mcp-compliance.config.json が作成されます。
設定ファイル
mcp-compliance.config.json をリポジトリに追加して、CI と開発ループで引数なしで mcp-compliance test を実行できるようにします。サポートされている場所(次の順に検索されます):mcp-compliance.config.json、.mcp-compliancerc.json、.mcp-compliancerc、および package.json の "mcp-compliance" フィールドです。明示的なファイルを読み込むには、--config <path> を渡します。
HTTP:
{
"target": {
"type": "http",
"url": "https://my-server.com/mcp",
"headers": { "Authorization": "Bearer tok123" }
},
"timeout": 20000,
"specVersion": "2026-07-28",
"strict": true
}
stdio:
{
"target": {
"type": "stdio",
"command": "node",
"args": ["./dist/server.js"],
"env": { "LOG_LEVEL": "error" }
},
"skip": ["security"],
"strict": true
}
優先順位:CLI フラグ > 設定ファイル > デフォルト。すべてのフィールドはコマンドラインで上書きできます。specVersion は auto、2025-11-25、または 2026-07-28 を指定でき、0.19 で追加されました。このフィールドを設定した構成は、古いツールバージョン(0.18.x を含む)では不明なキーとして拒否されるため、この設定を使用する箇所では @yawlabs/mcp-compliance@^0.19 に固定してください。
ローカル SVG バッジ
実際のグレードを反映するローカル SVG を作成し、リポジトリにコミットします。
mcp-compliance test https://my-server.com/mcp --output badge.svg
mcp-compliance test node ./dist/server.js --output badge.svg
次に、README に埋め込みます。

88 個のテスト項目(2025-11-25)
2025-11-25 カタログでは、initialize とセッションの時代を対象に評価します。これは、最新の server/discover に応答しないすべてのサーバーに対して、--spec-version auto が選択するカタログです。
トランスポート(16 テスト)
HTTP のみ(13):
- transport-post — サーバーが HTTP POST リクエストを受け付けます(必須)
- transport-content-type — application/json または text/event-stream で応答します(必須)
- transport-notification-202 — 通知に対して正確に 202 Accepted を返します
- transport-content-type-reject — JSON 以外のリクエスト Content-Type を拒否します
- transport-session-id — 初期化後に MCP-Session-Id を必須にします
- transport-session-invalid — 不明なセッション ID に対して 404 を返します
- transport-get — GET が SSE ストリームまたは 405 を返します
- transport-delete — DELETE を受け付けるか、405 を返します
- transport-batch-reject — JSON-RPC バッチリクエストを拒否します(必須)
- transport-content-type-init — Initialize 応答に有効なコンテンツタイプが設定されています
- transport-get-stream — セッション付き GET が SSE または 405 を返します
- transport-concurrent — 同時リクエストを処理します
- transport-sse-event-field — SSE 応答に必須の event: message フィールドが含まれます
stdio のみ(3):
- stdio-framing — 改行区切りの JSON フレーミング(必須)
- stdio-unicode — UTF-8 の Unicode ラウンドトリップで、ASCII 以外のペイロードが保持されます
- stdio-unknown-method-recovers — 不明なメソッドに対して -32601 を返し、処理を継続します
ライフサイクル(21 テスト)
- **lifecycle-init** — 初期化ハンドシェイクが成功します(必須) - **lifecycle-proto-version** — 有効な YYYY-MM-DD 形式のプロトコルバージョンを返します(必須) - **lifecycle-server-info** — 名前を含む serverInfo を返します - **lifecycle-capabilities** — capabilities オブジェクトを返します(必須) - **lifecycle-jsonrpc** — 有効な JSON-RPC 2.0 レスポンスです(必須) - **lifecycle-ping** — ping メソッドに応答します(必須) - **lifecycle-instructions** — instructions フィールドが存在する場合、有効な文字列です - **lifecycle-id-match** — レスポンス ID がリクエスト ID と一致します(必須) - **lifecycle-string-id** — 文字列のリクエスト ID をサポートします(JSON-RPC 2.0) - **lifecycle-version-negotiate** — 不明なプロトコルバージョンを適切に処理します - **lifecycle-reinit-reject** — 2 回目の initialize リクエストを拒否します - **lifecycle-logging** — logging/setLevel を受け付けます(logging capability が宣言されている場合は必須) - **lifecycle-completions** — completion/complete を受け付けます(completions capability が宣言されている場合は必須) - **lifecycle-cancellation** — キャンセル通知を処理します - **lifecycle-progress** — 進行状況通知を適切に処理します - **lifecycle-list-changed** — 宣言された capability に対する listChanged 通知を受け付けます - **lifecycle-progress-token** — SSE 経由のリクエストで進行状況トークンをサポートします - **lifecycle-sampling-capability** — サーバー側でのクライアント sampling capability の使用を確認する参考チェックです - **lifecycle-roots-capability** — サーバー側でのクライアント roots capability の使用を確認する参考チェックです - **lifecycle-elicitation-capability** — 2025-11-25 クライアント elicitation capability の参考チェックです - **lifecycle-meta-tolerance** — サーバーは受信リクエスト内の不明な `_meta` フィールドを無視しますツール(4 件のテスト)
- tools-list — tools/list が有効な配列を返します(tools capability が宣言されている場合は必須)
- tools-call — tools/call が正しい形式で応答します
- tools-pagination — tools/list がカーソルベースのページネーションをサポートします
- tools-content-types — ツールのコンテンツ項目が有効な型です
リソース(5 件のテスト)
- resources-list — resources/list が有効な配列を返します(resources capability が宣言されている場合は必須)
- resources-read — resources/read がコンテンツ項目を返します
- resources-templates — resources/templates/list が動作するか、method-not-found を返します
- resources-pagination — resources/list がカーソルベースのページネーションをサポートします
- resources-subscribe — リソースの購読/購読解除(subscribe capability が宣言されている場合は必須)
プロンプト(3 件のテスト)
- prompts-list — prompts/list が有効な配列を返します(prompts capability が宣言されている場合は必須)
- prompts-get — prompts/get が有効なメッセージを返します
- prompts-pagination — prompts/list がカーソルベースのページネーションをサポートします
エラー処理(10 件のテスト)
- error-unknown-method — 不明なメソッドに対して JSON-RPC エラーを返します(必須)
- error-method-code — 正しい -32601 エラーコードを使用します
- error-invalid-jsonrpc — 不正な形式の JSON-RPC を処理します(必須)
- error-invalid-json — 無効な JSON ボディを処理します
- error-missing-params — name を指定せずに tools/call を呼び出した場合、エラーを返します
- error-parse-code — 無効な JSON に対して -32700 を返します
- error-invalid-request-code — 無効なリクエストに対して -32600 を返します
- tools-call-unknown — 存在しないツール名に対してエラーを返します
- error-capability-gated — 宣言されていない capability に対応するメソッドを拒否します
- error-invalid-cursor — 無効なページネーションカーソルを適切に処理します
スキーマ検証(6 件のテスト)
- **tools-schema** — すべてのツールに有効な name と inputSchema がある(tools capability を宣言する場合は必須) - **tools-annotations** — ツールのアノテーションが存在する場合、有効である - **tools-title-field** — ツールに title フィールドが含まれている(2025-11-25) - **tools-output-schema** — outputSchema を持つツールが有効である(2025-11-25) - **prompts-schema** — プロンプトに有効な name フィールドがある(prompts capability を宣言する場合は必須) - **resources-schema** — リソースに有効な uri と name がある(resources capability を宣言する場合は必須)セキュリティ(23 テスト)
- security-auth-required — 認証されていないリクエストを拒否する
- security-www-authenticate — 401 レスポンスに WWW-Authenticate ヘッダーが含まれている
- security-auth-malformed — 形式が不正な認証情報を拒否する
- security-tls-required — HTTPS/TLS を強制する
- security-session-entropy — セッション ID のエントロピーが高い
- security-session-not-auth — セッション ID で認証を回避できない
- security-oauth-metadata — Protected Resource Metadata エンドポイントが存在する(RFC 9728)
- security-token-in-uri — クエリ文字列内の認証トークンを拒否する
- security-cors-headers — CORS ヘッダーが制限されている
- security-origin-validation — DNS リバインディング対策として Origin ヘッダーを検証する
- security-command-injection — ツールのパラメーターへのコマンドインジェクションに耐える
- security-sql-injection — ツールのパラメーターへの SQL インジェクションに耐える
- security-path-traversal — ツールのパラメーターへのパストラバーサルに耐える
- security-ssrf-internal — 内部ネットワークへの SSRF に耐える
- security-oversized-input — サイズ超過の入力を適切に処理する
- security-extra-params — 余分なツールパラメーターを拒否するか無視する
- security-tool-schema-defined — すべてのツールで inputSchema が定義されている
- security-tool-rug-pull — ツール定義が呼び出しのたびに変わらない
- security-tool-description-poisoning — ツールの説明にインジェクションパターンが含まれていない
- security-tool-cross-reference — ツールがほかのツールを名前で参照しない
- security-error-no-stacktrace — エラーレスポンスからスタックトレースが漏えいしない
- security-error-no-internal-ip — エラーレスポンスから内部 IP が漏えいしない
- security-rate-limiting — レート制限が適用されている
103 件のテストで確認する内容(2026-07-28)
2026-07-28 カタログでは、ステートレスでリクエストごとに _meta を使う時代を評価します。initialize ではなく server/discover を使用し、セッションはなく、キャッシュ可能なすべての結果にキャッシュヒントを付け、すべての結果に resultType を付け、サーバー起点のリクエストの代わりに MRTR input_required 結果を使い、リソースが見つからない場合は -32602 を返します。2025-11-25 のリストと共有される ID は同じ機能を対象としますが、基準と必須フラグはカタログ間で異なる場合があります(stdio-framing と error-invalid-jsonrpc はこのカタログでは任意、error-method-code は必須です)。そのため、ID を比較できるのは同一カタログ内に限られます。判定が変わったチェックには新しい ID が付与され、diff は異なるリビジョン間のレポート比較を拒否します。事後テストでは、実行中にサーバーが送信したすべてのメッセージの記録をスキャンします(何も受信していない場合に、空振りで合格するのではなく失敗します)。_meta および標準ヘッダーの拒否テストでは、拒否の帰属先を特定できます。適合する server/discover が提供された場合に限り拒否が評価されるため、レガシー版しかないサーバーをこのカタログに固定すると、「評価不能」として失敗します。セットアップ時の server/discover は 429 の後に一度再送され、これを読み取るすべてのルールは、最終的に採用された応答を判定します。拒否を評価するチェック(transport-batch-reject、transport-content-type-reject、lifecycle-jsonrpc、lifecycle-subscriptions-listen、および 6 つのエラーチェック(error-unknown-method、error-invalid-jsonrpc、error-invalid-json、error-missing-params、error-capability-gated、error-invalid-cursor)に加え、error-parse-code と error-invalid-request-code が受け入れる本文なしの 4xx)では、応答の帰属先も確認します。ゲートウェイの -32001 本文を伴う 401、認証拒否と判断できる 403(--auth を指定しない場合は、あらゆる Bearer チャレンジ、--auth を指定する場合は error パラメーターを含むもの)、再送後も 429 のままの応答、または適合する別のサーバーがプローブと並行して送信したリクエスト(server/discover、error-invalid-cursor の場合はカーソルを含まないリストメソッド)すら通過できないその他の 403 は、いずれも「評価不能」として失敗します。一方、チェック固有のコードを含まない 5xx は、サーバーがリクエストの処理に失敗したものとして失敗します。lifecycle-jsonrpc のプローブ自体が適合する server/discover であるため、比較用の別サーバーは送信されません。このプローブに対する 403、およびサーバー独自の拒否コードを含まない 5xx は、いずれも「評価不能」です。transport-batch-reject と transport-content-type-reject も、セットアップ時の server/discover 自体が拒否された場合、あらゆる拒否を「評価不能」として失敗させます。tools-call-unknown はまだこのようには判定しません。tools/call に対するゲートウェイの -32001 でも合格します。4 つのインジェクションテストでは、文字列引数を持つ最も安全な注釈ティアから、単一の(ツール、引数)対象を調べます。順序は readOnlyHint: true、destructiveHint: false、注釈なしのツール(仕様では destructiveHint の既定値は true です)、destructiveHint: true です。対象から外したツールと実際にプローブしたツールは警告に記載されます。その他の必須引数はスキーマに従うプレースホルダーで埋め、拒否されたペイロード、実行の証拠なしに返されたペイロード、ツールに到達しなかったペイロードの数を報告します(すべてが未到達の場合は警告を付けて判定不能となり、スキップとして記録されます)。stdio では、チェック自身のリクエストによってサーバーが停止した場合(インジェクションペイロード、1 MB の引数、不明なツール引数、stdio-unicode の CJK/絵文字プローブ、lifecycle-progress-token の呼び出しのいずれか)、その都度、以降のチェックのためにサーバーを再起動します。これは --retries を含むすべての場合に適用されます。セキュリティチェックと stdio-unicode は、サーバー停止として失敗します。その後、security-tool-rug-pull は新しいプロセスからの 2 つのリストを比較します。stdio-unicode と lifecycle-progress-token は、応答後すぐに終了する子プロセスも失敗として扱います(応答の後に通常の server/discover が続きます)。また、stdio-unicode は応答後に応答しなくなる場合も失敗します。security-rate-limiting は、読み取り専用かつ引数なしのツールがある場合、そのツールに対して tools/call を 50 回バースト送信します。バーストが問題なく処理された場合は、いずれの場合も警告付きで合格します。
トランスポート(20 テスト)
HTTP のみ(15): - **transport-post** — HTTP POST を受け付けます(必須) - **transport-content-type** — JSON または SSE で応答します(必須) - **transport-content-type-reject** — JSON 以外のリクエスト Content-Type を拒否します - **transport-batch-reject** — JSON-RPC バッチリクエストを拒否します(必須) - **transport-notification-202** — 通知に対して 202 Accepted を返します - **transport-concurrent** — 同時リクエストを処理します - **transport-get-removed** — GET に対して 405 を返します - **transport-delete-removed** — DELETE に対して 405 を返します - **transport-session-ignored** — Mcp-Session-Id を無視します - **transport-header-version-required** — MCP-Protocol-Version ヘッダーがない場合は拒否します(必須) - **transport-header-version-mismatch** — ヘッダーと _meta のバージョンが一致しない場合は拒否します(必須) - **transport-header-method-required** — Mcp-Method ヘッダーがない場合は拒否します(必須) - **transport-header-method-mismatch** — Mcp-Method と本文が一致しない場合は拒否します(必須) - **transport-header-name-mismatch** — Mcp-Name と本文が一致しない場合は拒否します - **transport-header-case-insensitive** — ヘッダー名では大文字と小文字を区別しません両方のトランスポート(1、事後検証):
- transport-no-server-requests — どのストリームでもサーバー起点のリクエストがありません(必須)
stdio のみ(4):
- stdio-framing — 改行区切りの JSON フレーミング
- stdio-unicode — UTF-8 Unicode のラウンドトリップ
- stdio-unknown-method-recovers — 不明なメソッドの後に復旧します
- stdio-cancellation — 不明なリクエストのキャンセルを無視します
ライフサイクル(22 テスト)
- lifecycle-discover — server/discover が DiscoverResult を返します(必須)
- lifecycle-discover-versions — supportedVersions が適切な形式です(必須)
- lifecycle-discover-caching — server/discover にキャッシュのヒントが含まれます(必須)
- lifecycle-jsonrpc — 応答が有効な JSON-RPC 2.0 です(必須)
- lifecycle-id-match — 応答の id がリクエストの id と一致します(必須)
- lifecycle-string-id — 文字列のリクエスト ID をサポートします
- lifecycle-capabilities — capabilities オブジェクトを返します(必須)
- lifecycle-server-info — _meta に serverInfo が含まれます
- lifecycle-instructions — Instructions フィールドが有効です
- lifecycle-meta-required — _meta のないリクエストを拒否します(必須)
- lifecycle-meta-protocol-version-required — protocolVersion のない _meta を拒否します(必須)
- lifecycle-meta-client-capabilities-required — clientCapabilities のない _meta を拒否します(必須)
- lifecycle-meta-client-info-optional — clientInfo のない _meta でも処理します(必須)
- lifecycle-version-unsupported — サポートされていないプロトコルバージョンを拒否します(必須)
- lifecycle-removed-methods — 削除されたレガシーメソッドを拒否します
- lifecycle-dual-era — レガシーの initialize プローブ(参考情報)
- lifecycle-capability-handlers-match — capability の宣言がハンドラーと一致します
- lifecycle-subscriptions-listen — subscriptions/listen は最初に確認応答を返します
- lifecycle-log-level-gating — logLevel がない場合はログ通知を送信しません(必須)
- lifecycle-meta-tolerance — 不明な _meta キーを許容します
- lifecycle-completions — completion/complete を受け付けます(completions capability が宣言されている場合は必須)
- lifecycle-progress-token — 進捗通知でトークンをエコーします
ツール(6 テスト)
- tools-list — tools/list が有効な応答を返します(tools capability が宣言されている場合は必須)
- tools-list-caching — tools/list にキャッシュのヒントが含まれます(tools capability が宣言されている場合は必須)
- tools-list-deterministic-order — tools/list の順序が決定的です
- tools-call — tools/call が正しく応答します(tools capability が宣言されている場合は必須)
- tools-content-types — ツールのコンテンツ項目の型が有効です(tools capability が宣言されている場合は必須)
- tools-pagination — tools/list がページネーションをサポートします
リソース(8 テスト)
- **resources-list** — resources/list が有効なレスポンスを返します(resources 機能を宣言している場合は必須) - **resources-list-caching** — resources/list にキャッシュヒントが含まれます(resources 機能を宣言している場合は必須) - **resources-read** — resources/read がコンテンツを返します(resources 機能を宣言している場合は必須) - **resources-read-caching** — resources/read にキャッシュヒントが含まれます(resources 機能を宣言している場合は必須) - **resources-not-found** — 存在しないリソースに対して -32602 を返します(resources 機能を宣言している場合は必須) - **resources-templates** — resources/templates/list が有効なレスポンスを返します - **resources-templates-caching** — resources/templates/list にキャッシュヒントが含まれます - **resources-pagination** — resources/list がページネーションに対応していますプロンプト(4 件のテスト)
- prompts-list — prompts/list が有効なレスポンスを返します(prompts 機能を宣言している場合は必須)
- prompts-list-caching — prompts/list にキャッシュヒントが含まれます(prompts 機能を宣言している場合は必須)
- prompts-get — prompts/get が有効なメッセージを返します(prompts 機能を宣言している場合は必須)
- prompts-pagination — prompts/list がページネーションに対応しています
エラー処理(12 件のテスト)
- error-unknown-method — 不明なメソッドに対して JSON-RPC エラーを返します(必須)
- error-method-code — 不明なメソッドで -32601 を使用します(必須)
- error-invalid-jsonrpc — 不正な形式の JSON-RPC を処理します
- error-invalid-json — 無効な JSON 本文を処理します
- error-parse-code — 無効な JSON に対して -32700 を返します
- error-invalid-request-code — 無効なリクエストに対して -32600 を返します
- error-missing-params — name を指定しない tools/call がエラーを返します
- tools-call-unknown — 不明なツール名に対してエラーを返します
- error-capability-gated — 宣言されていない機能に対するメソッドを拒否します
- error-invalid-cursor — 無効なページネーションカーソルを処理します
- error-id-echo — エラーレスポンスでリクエスト ID をエコーバックします
- error-retired-codes — 廃止されたエラーコードを使用しません
スキーマ検証(10 件のテスト)
- tools-schema — すべてのツールに name と inputSchema があります
- tools-annotations — ツールの注釈が有効です
- tools-title-field — ツールに title フィールドが含まれています
- tools-output-schema — outputSchema を持つツールが有効です
- prompts-schema — プロンプトに name フィールドがあります
- resources-schema — リソースに uri と name があります
- schema-result-type — すべての結果に resultType が含まれています(必須)
- schema-no-input-required-on-lists — input_required は MRTR メソッドでのみ使用されます(必須)
- schema-input-required-shape — InputRequiredResult の形式が正しいです
- schema-wire-valid — メッセージが 2026-07-28 スキーマに対して検証されます
セキュリティ(21 件のテスト)
- **security-auth-required** — 認証されていないリクエストを拒否します - **security-www-authenticate** — 401 レスポンスに WWW-Authenticate が含まれます - **security-auth-malformed** — 形式が不正な認証情報を拒否します - **security-tls-required** — HTTPS/TLS を強制します - **security-oauth-metadata** — Protected Resource Metadata エンドポイントが存在します - **security-token-in-uri** — クエリー文字列内の認証トークンを拒否します - **security-cors-headers** — CORS ヘッダーが制限されています - **security-origin-validation** — Origin ヘッダーを検証します - **security-command-injection** — ツールのパラメーターにおけるコマンドインジェクションに対処します - **security-sql-injection** — ツールのパラメーターにおける SQL インジェクションに対処します - **security-path-traversal** — ツールのパラメーターにおけるパストラバーサルに対処します - **security-ssrf-internal** — 内部ネットワークへの SSRF に対処します - **security-oversized-input** — サイズが大きすぎる入力を適切に処理します - **security-extra-params** — 余分なツールのパラメーターを拒否または無視します - **security-tool-schema-defined** — すべてのツールで inputSchema が定義されています - **security-tool-rug-pull** — ツール定義は呼び出しごとに変わりません - **security-tool-description-poisoning** — ツールの説明にインジェクションパターンが含まれていません - **security-tool-cross-reference** — ツールが名前で他のツールを参照しません - **security-error-no-stacktrace** — エラーレスポンスからスタックトレースが漏えいしません - **security-error-no-internal-ip** — エラーレスポンスから内部 IP が漏えいしません - **security-rate-limiting** — レート制限が適用されます評価
| 評価 | スコア |
|---|---|
| A | 90-100 |
| B | 75-89 |
| C | 60-74 |
| D | 40-59 |
| F | 0-39 |
必須テストはスコアの 70%、任意テストは 30%を占め、何らかの測定を行ったテストを対象に集計されます。何も測定しなかったテスト(スキップ)は、合格でも不合格でもなく、スコアから完全に除外されます。必須テストまたは任意テストがすべてスキップされた場合は、もう一方のテスト群がスコア全体を占めます。すべてのテストがスキップされた実行のスコアは、テストが一つも実行されなかった場合と同様に 0(F)です。ターミナル、Markdown、HTML、GitHub の各レポート、SARIF の invocation properties(note)、および MCP の mcp_compliance_test ツールには、「No test measured anything」と表示されます。JSON レポートでは件数に反映され(summary.skipped が summary.total と等しくなります)、スキップは合格数(summary.passed、カテゴリ別の件数)には引き続き含まれます。すべてのレポート形式でスキップを集計または一覧表示します(ターミナルでは SKIPPED CHECKS の下に表示されます)。ターミナルのカテゴリーバーと HTML のカテゴリカードでは測定された内容がスコアに反映され、--verbose ではスキップが SKIP として出力されます。また、diff ではスキップを開始または終了したチェックが一覧表示されます。0.19.0 以前に書き出されたレポートではスキップが合格として採点されていたため、同じ結果でもスコアは高くなります。スコアの変動幅は実行内容によって異なります。参照サーバーでは丸め後のスコアに変化はありませんでしたが、テスト群の不合格数とスキップ数の積が大きいほどスコアの低下幅も大きくなります。必須チェックがすべて合格するサーバーでも、評価が 1 段階下がることがあり、ほとんどのチェックで何も測定されなかった実行では、評価が数段階下がる場合があります。diff は、このバージョンの方式で両方のレポートの結果を採点するため、0.19.0 以前に書かれたベースラインも同じ条件で比較され、そのファイルに記録されたスコアを示す注記が表示されます。詳しくは、方法論ドキュメントのスコアリングアルゴリズムの全文をご覧ください。
CI との統合
# GitHub Actions example
- name: MCP Compliance Check
run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --strict
# With JSON output for parsing
- name: MCP Compliance Check
run: |
npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --format json > compliance.json
cat compliance.json | jq '.grade'
# With retries for flaky network conditions
- name: MCP Compliance Check
run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --strict --retries 2 --timeout 30000
# SARIF output for GitHub Code Scanning
- name: MCP Compliance Check
run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --format sarif > compliance.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: compliance.sarif
MCP サーバー(Claude Code、Cursor など向け)
このパッケージは、Claude Code、Cursor、または任意の MCP クライアントから使用できる 2 つのツールを備えた MCP サーバーも公開します。
セットアップ
Claude Code(ワンライナー):
claude mcp add mcp-compliance -- npx -y @yawlabs/mcp-compliance@latest mcp
または、プロジェクトのルートに .mcp.json を作成します:
macOS / Linux / WSL:
{
"mcpServers": {
"mcp-compliance": {
"command": "npx",
"args": ["-y", "@yawlabs/mcp-compliance@latest", "mcp"]
}
}
}
Windows:
{
"mcpServers": {
"mcp-compliance": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@yawlabs/mcp-compliance@latest", "mcp"]
}
}
}
ヒント: このファイルにはシークレットが含まれていないため、コミットしても安全です。
MCP クライアントを再起動し、プロンプトが表示されたらサーバーを承認してください。
ツール
- mcp_compliance_test — HTTP MCP エンドポイント(URL)に対して、コンプライアンススイート全体を実行します。認証、カスタムヘッダー、タイムアウト、再試行、カテゴリ/テストのフィルタリング、
specVersion(auto|2025-11-25|2026-07-28、デフォルトはauto)に対応しています。評価、スコア、解決されたspecVersion、詳細な結果(各テストに PASS、FAIL、SKIP のいずれかが付与されます。Tests 行にはスキップ数も含まれます)を返します。stdio ターゲットは CLI 専用です。 - mcp_compliance_explain — 特定のテスト ID が何を確認するのか、なぜ重要なのかを、仕様の該当セクションへのリンクとともに説明します。ID はカタログごとに異なります。1 つのカタログを参照するには
specVersionを指定し、両方を検索するには省略します(両方に共通する ID はスイートごとに一度説明され、必須フラグ/カテゴリも異なるかどうかが注記されます。一方のスイートにしか存在しない ID は、その旨が示されます)。
すべてのツールには MCP ツールアノテーション(readOnlyHint、destructiveHint、idempotentHint、openWorldHint)が付いているため、安全な操作では MCP クライアントが確認ダイアログを省略できます。
プログラムからの使用
import { runComplianceSuite } from '@yawlabs/mcp-compliance';
const report = await runComplianceSuite('https://my-server.com/mcp');
console.log(`Grade: ${report.grade} (${report.score}%)`);
// With options
const report2 = await runComplianceSuite('https://my-server.com/mcp', {
headers: { 'Authorization': 'Bearer tok123' },
timeout: 30000,
retries: 1,
only: ['transport', 'lifecycle'],
specVersion: '2026-07-28', // 'auto' (default) | '2025-11-25' | '2026-07-28'
});
console.log(report2.specVersion); // always the resolved revision, never 'auto'
// Per-revision catalogs and helpers
import { getTestDefinitions, specBaseFor, SUPPORTED_SPEC_VERSIONS } from '@yawlabs/mcp-compliance';
getTestDefinitions('2026-07-28'); // 103 TestDefinitions; TEST_DEFINITIONS stays the 2025-11-25 list
specBaseFor(report2.specVersion); // base URL for that revision's spec links
// Live progress for streaming UIs (e.g. server-sent-events to a browser)
await runComplianceSuite('https://my-server.com/mcp', {
onTestComplete: (result) => {
// result has the full TestResult: id, name, category, required,
// passed, skipped (true when the check measured nothing), details,
// durationMs, specRef. Push it to your client. (onProgress carries no
// skip flag: a skip arrives there as passed.)
sendToClient(result);
},
// Pre-test status lines: the stdio era probe still waiting after ~2 s,
// or an HTTP preflight timeout being re-probed within startupTimeout.
// The CLI prints these dimmed on stderr in terminal mode only.
onStatus: (message) => sendToClient({ status: message }),
});
レポートのスキーマ
テストスイートの JSON 出力は、安定したバージョン管理対象の契約です。すべてのレポートにはトップレベルに schemaVersion フィールドが含まれます。完全な JSON Schema は schemas/report.v1.json にあり、npm パッケージに同梱されています。
{
"schemaVersion": "1", // bumped on breaking changes to the report shape
"specVersion": "2026-07-28", // MCP spec revision the run graded — the RESOLVED value ("2025-11-25" or "2026-07-28"), never "auto"
"toolVersion": "0.19.0", // mcp-compliance version that produced the report
"url": "...",
"timestamp": "...",
"grade": "A",
"score": 92.5,
"summary": { "total": 99, "passed": 97, "failed": 2, "required": 24, "requiredPassed": 24, "skipped": 4 },
"tests": [ // ids are only meaningful together with specVersion
{ "id": "security-auth-malformed", "passed": true, "skipped": true,
"details": "Skipped: needs a valid credential to compare against (pass --auth)", ... },
...
],
// ...
}
実行されたものの測定対象がなかったテスト(--auth がない、ツールが宣言されていない、そのトランスポートには適用されないチェック、または先行するチェックで特定できなかった拒否)は、passed: true と skipped: true として記録されます。summary.skipped と各 categories[*].skipped にはその数が記録されます。スキップは passed に含まれますが、score からは除外されます(0.19.0 以前が出力したレポートでは、スキップも合格としてスコアに含まれていました)。そのため、合格数を根拠として扱う前に、passed とともに skipped を確認してください。SARIF 出力では、results には失敗のみが含まれ、スキップは実行の invocation プロパティ(testsSkipped、skippedTests)に記載されるため、Code Scanning でスキップがアラートとして表示されることはありません。
利用側のガイダンス:
schemaVersionに基づいてバージョンを固定してください。未知のバージョンのレポートは、構造を推測せずに拒否してください。testsを解釈する前にreport.specVersionを確認してください。0.19 以降は 1 つのツールバージョンでどちらのリビジョンのレポートも生成できるため、toolVersionだけをキーにするダッシュボードでは、同じバージョンからの2025-11-25と2026-07-28のレポートが表示されます。テスト ID、必須テストのセット、serverInfo.protocolVersionは、ここに示されるリビジョンに属します。未知のspecVersionは未知のschemaVersionと同様に扱い、推測せずに拒否してください。- このスキーマは、任意の Draft 2020-12 バリデーター(例:
ajv)で検証できます。厳格なスキーマ(additionalProperties: false)のため、レポートの検証には、そのレポートを書き出したツールバージョンに同梱されているreport.v1.jsonを使用してください。0.19 では v1 に省略可能なskippedフィールド(テスト、summary、categories内)が追加されているため、古いスキーマのコピーではこれらが拒否されます。 - 名前の変更、削除、型の変更がある場合は
schemaVersionを上げます。それ以外では、メジャーバージョン内でレポートの構造は安定しています。 - 同じサーバーに対する 2 回の実行では、解決される
specVersionが同じであれば、同等の評価、スコア、各テストの合否が得られます(タイミング/タイムスタンプを除く)。autoの場合、これはサーバーに依存するため、デプロイ間の決定性が重要な場合は--spec-versionを固定してください。
方法論とドキュメント
テスト方法論は、評価の検証可能性を確保するため、公開されています。
- テスト方法論 — 仕様改訂ごとのテスト実行モデル、スコアリングアルゴリズム、合否基準を含む88 + 103件のすべてのテストルール(CC BY 4.0)
- 機械可読なルールカタログ — 各ルールに適用される仕様改訂のタグが付いており、プログラムから利用できます(
src/tests/catalog-parity.test.tsによりコードと常に同期されています) mcp-complianceを作った理由 — 問題点、既存の代替手段、このツールの独自の取り組み- よくある失敗の修正方法 — 両方の改訂版を対象に、コードスニペット付きで、最も頻繁に発生するテスト失敗を修正する手順を紹介します
- 仕様バージョンポリシー — 1つのツールバージョンと複数の仕様カタログ:
autoによる判定方法、バージョンの固定方法、サーバーのアップグレード時に変わる内容 - パフォーマンスの詳細解説 — スイートを逐次実行する理由と、並列実行に伴うコスト
- 仕様に関するPR案 — これまで遭遇した曖昧なケースについて提案するMCP仕様の明確化案
この方法論は、権威ある適合性標準ではありません。これは1つのツールが採用した選択を公開し、調査、採用、フォークできるようにしたものです。公式のMCP仕様(2025-11-25、2026-07-28)ではサーバーが行うべきことを定義し、このドキュメントでは @yawlabs/mcp-compliance がそれを検証する方法を説明します。
要件
- Node.js 20+
ランタイム
mcp-compliance コマンドは小さなランチャーです。利用可能な oam ランタイムがインストールされていればそれを優先し、そうでなければnpmがすでに起動したNode上で追加コストなくCLIを実行します。CLIの動作はどちらのランタイムでも同じです。
| 変数 | 効果 |
|---|---|
MCP_COMPLIANCE_RUNTIME=auto | デフォルトです。見つかった中で最も新しいoam 0.18.0以降を使用し、見つからない場合はNodeにフォールバックします。使用できないoamが見つかった場合、または OAM_BIN が正しくない場合は、stderrにその旨を表示します(mcp-compliance: ...; using Node instead.)。 |
MCP_COMPLIANCE_RUNTIME=oam | oamのみを使用します。oam 0.18.0以降が見つからない場合は終了コード1で終了し、修正方法を表示します。古いoamには oam self-update、OAM_BIN にはその修正方法、oamがまったくない場合はインストールリンクが表示されます。 |
MCP_COMPLIANCE_RUNTIME=node | oamがインストールされていても、Nodeのみを使用します。 |
OAM_BIN=/path/to/oam | 検索の前に、このoamを試します。見つからない場合、0.18.0より古い場合、または実行できない場合は、ランチャーがその旨を表示して検索を続けます。 |
OAM_INSTALL_DIR=/dir | ~/.oam/bin、%LOCALAPPDATA%\oam\bin、PATH の前に、oamのインストーラーがバイナリを配置するこのディレクトリも確認します。 |
oamの最低バージョンは、最新リリースの0.18.0です。CLIの確認はこのリリースでのみ行われるため、これは必須要件です。0.9.0より前のoamでは、child_process が標準入出力と引数を処理する方法により、サーバーではなくランタイムが適合性評価の対象になってしまいます。古いoamを更新するには、oam self-update を実行してください。
oam run <path-to-package>/dist/index.js -- test <target> を実行すると、ランチャーを経由せずにoam上で直接CLIが実行されます。その場合は上記の内容は適用されず、最低バージョンのチェック、フォールバック、ランタイムの切り替えはありません。
貢献
git clone https://github.com/YawLabs/mcp-compliance.git
cd mcp-compliance
npm install
npm run build
npm test
開発コマンド:
| コマンド | 説明 |
|---|---|
npm run build | tsupでコンパイルします |
npm run dev | ウォッチモード |
npm test | テストを実行します(vitest) |
npm run lint | Biomeでチェックします |
npm run lint:fix | Biomeで自動修正します |
npm run typecheck | TypeScriptの型チェック |
npm run test:ci | ビルド + テスト(CI対応) |
リンク
License
MIT — see LICENSE.
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。