MCPの出典情報を欠落させない|provenance用outputSchema設計
MCPツールの回答へ出典URL、発行者、取得日時、該当箇所、ハッシュを構造化して残すoutputSchema設計です。2026-07-28仕様のstructuredContentとJSON Schema 2020-12に沿う実装例を示します。
- mcp
- source-attribution
- structured-content
- json-schema
- legal-tech
- agent-ops
- 情報確認
- 参考リンク
- 5件
- 更新性
- 長く使える
- 読了目安
- 約9分
仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。
結論
MCPで出典を落とさない最も堅い方法は、回答文へURLを書かせるプロンプトではなく、ツールの outputSchema に provenance.sources を定義し、必須項目として検証することです。2026年7月28日版MCPは structuredContent と outputSchema を正式に扱いますが、共通のcitation項目までは規定していません。出典の粒度はサーバー側のアプリケーション契約として設計します。
サーバーは検証済みの一つのオブジェクトから structuredContent と互換用の TextContent を生成します。URLだけでなく発行者、取得日時、資料種別、該当箇所を残せば、後工程が「どの資料のどこに基づく値か」を機械的に追えます。
この記事の対象読者
この記事は、検索、法令、社内文書、RAG、データベースを読むMCPサーバーの開発者と、ツール出力を監査するプラットフォーム担当者向けです。MCPの入門記事を読んだ後、単なるテキスト回答から検証可能な構造化結果へ進みたい場合を想定しています。
法令調査での具体的な資料接続は法案から現行法までの調査フロー、公開パッケージで出典URLを扱う流れはe-Gov法令MCPのnpm公開手順も参照してください。
2026-07-28仕様で保証される範囲
MCP 2026-07-28のTools仕様では、ツール定義に任意の outputSchema を宣言できます。ツール結果の structuredContent はオブジェクトだけでなく、配列、文字列、数値、真偽値、nullを含む任意のJSON値です。
outputSchema がある場合、仕様上の責任は明確です。
- サーバーは、
structuredContentをoutputSchemaに適合させなければならない - クライアントは、受け取った構造化結果を検証することが推奨される
- 後方互換性のため、構造化JSONを
TextContentにも直列化して返すことが推奨される $schemaを省略したJSON Schemaは2020-12が既定になる
一方、MCPは「出典URLは citationUrl と呼ぶ」「取得日時を必須にする」といったprovenanceの業務モデルまでは決めません。そこを標準仕様の機能だと説明すると過剰主張になります。本稿の provenance は、MCPが運べるJSONの上に置く設計例です。
まずデータと根拠を分ける
トップレベルを data と provenance に分けます。data はツールが提供したい業務データ、provenance はその生成根拠です。
| フィールド | 必須 | 目的 | 注意点 |
|---|---|---|---|
data | 必須 | ツール本来の結果 | ツールごとのスキーマへ置き換える |
provenance.generatedAt | 必須 | 結果を組み立てた時刻 | 出典の公開日時とは別 |
provenance.sources[].id | 必須 | data 側から参照する出典ID | 配列内で重複させない |
provenance.sources[].uri | 必須 | 一次資料の所在 | リダイレクト後URLもログに残すとよい |
provenance.sources[].title | 必須 | 人が識別できる資料名 | モデルが推測せず取得元から読む |
provenance.sources[].publisher | 必須 | 発行主体 | ドメイン名と同一とは限らない |
provenance.sources[].retrievedAt | 必須 | 実際に取得した時刻 | キャッシュ作成時刻と区別する |
provenance.sources[].sourceType | 必須 | 法令、API、文書などの分類 | 自組織の列挙値を管理する |
provenance.sources[].locator | 任意 | 条、ページ、段落、JSON Pointer | 大きな資料では事実上必須 |
provenance.sources[].publishedAt | 任意 | 資料の公開日時 | 取得できない場合に捏造しない |
provenance.sources[].effectiveAt | 任意 | 法令・規程などの適用基準日 | 公布日や取得日と混同しない |
provenance.sources[].contentHash | 任意 | 取得バイト列の同一性確認 | 発行者の真正性は証明しない |
provenance.transformations | 任意 | 抽出・集計・正規化の履歴 | 自由文だけでなく種別を持たせる |
provenance.warnings | 任意 | 欠落・試行提供・推定を明示 | 正常データに紛れ込ませない |
取得時刻と公開時刻、適用時点を一つの date へまとめないことが重要です。とくに法令、料金、製品仕様は三つの時刻がずれます。
provenance用outputSchemaの例
次のスキーマは、data.items を返す検索ツールを想定した最小実用例です。実案件では data の部分を自分のツール出力へ置き換えます。
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "additionalProperties": false, "required": ["data", "provenance"], "properties": { "data": { "type": "object", "additionalProperties": false, "required": ["items"], "properties": { "items": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["id", "value", "sourceRefs"], "properties": { "id": { "type": "string", "minLength": 1 }, "value": { "type": "string" }, "sourceRefs": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } } } } } } }, "provenance": { "type": "object", "additionalProperties": false, "required": ["generatedAt", "sources"], "properties": { "generatedAt": { "type": "string", "format": "date-time" }, "sources": { "type": "array", "minItems": 1, "items": { "type": "object", "additionalProperties": false, "required": [ "id", "uri", "title", "publisher", "retrievedAt", "sourceType" ], "properties": { "id": { "type": "string", "minLength": 1 }, "uri": { "type": "string", "format": "uri" }, "title": { "type": "string", "minLength": 1 }, "publisher": { "type": "string", "minLength": 1 }, "retrievedAt": { "type": "string", "format": "date-time" }, "sourceType": { "type": "string", "enum": [ "official-api", "official-page", "law", "dataset", "document" ] }, "publishedAt": { "type": "string", "format": "date-time" }, "effectiveAt": { "type": "string", "format": "date" }, "locator": { "type": "string", "minLength": 1 }, "license": { "type": "string", "minLength": 1 }, "contentHash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" } } } }, "transformations": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["type", "description"], "properties": { "type": { "type": "string", "enum": ["extract", "filter", "normalize", "aggregate"] }, "description": { "type": "string", "minLength": 1 }, "toolVersion": { "type": "string", "minLength": 1 } } } }, "warnings": { "type": "array", "items": { "type": "string", "minLength": 1 } } } } }}sourceRefs は sources[].id を参照します。JSON Schemaだけで「参照先IDが配列中に存在する」ことまで表すのは扱いづらいため、これはアプリケーション検証で補います。同じ id の重複も、スキーマ検証後に確認してください。
JSON Schema Draft 2020-12の format は、利用するバリデーターや設定によって注釈としてだけ扱われる場合があります。date-time や uri を本当に拒否条件にするなら、バリデーターのformat検証を有効にしてテストします。
ツール定義へ組み込む
outputSchema は tools/list に含まれる個々のツール定義へ置きます。概念上は次の形です。
const searchTool = { name: "search_with_sources", description: "一次資料と出典情報をセットで返す", inputSchema: { type: "object", additionalProperties: false, required: ["query"], properties: { query: { type: "string", minLength: 1 } } }, outputSchema: provenanceOutputSchema};outputSchema が宣言されると、サーバーには適合する構造化結果を返す責任が生じます。「失敗時だけprovenanceを省略する」といった実装はスキーマ違反です。取得失敗を業務結果として返すなら、warnings や明示的なステータスをスキーマへ設けます。リクエスト自体が不正ならJSON-RPCエラー、ツール実行が失敗したならMCP Tools仕様のエラー表現、と層を分けます。
structuredContentとTextContentを一つから作る
結果を二系統で別々に組み立てると、URLや時刻がずれます。一つの structured を検証し、その同じ値をJSON直列化します。
const structured = { data: { items: [ { id: "result-1", value: "確認した値", sourceRefs: ["source-1"] } ] }, provenance: { generatedAt: "2026-08-13T01:00:00Z", sources: [ { id: "source-1", uri: "https://example.go.jp/official/item/1", title: "公式資料名", publisher: "発行機関名", retrievedAt: "2026-08-13T00:59:30Z", sourceType: "official-page", locator: "第2節" } ], transformations: [ { type: "extract", description: "第2節から対象値を抽出", toolVersion: "1.3.0" } ], warnings: [] }};
validateAgainstOutputSchema(structured);
const callToolResult = { resultType: "complete", content: [ { type: "text", text: JSON.stringify(structured) } ], structuredContent: structured};ここで validateAgainstOutputSchema は利用中のJSON Schemaバリデーターへ置き換えます。MCP 2026-07-28の成功結果には resultType: "complete" が入り、structuredContent は宣言した outputSchema に適合させます。stdioの生JSON-RPCで結果を確かめる方法はMCPサーバーのJSON-RPC最小テストで扱います。
contentHashが証明するもの、しないもの
contentHash は、保存した本文バイト列へSHA-256を計算し、後日同じバイト列かを確認する用途に向きます。次の値は「この取得物のハッシュ方式とダイジェスト」を表します。
sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08ただし、これは次を証明しません。
- そのURLを本物の発行者が管理していたこと
- 取得時点で通信経路や端末が侵害されていなかったこと
- 資料に書かれた事実が正しいこと
- HTMLの意味内容が同じこと(広告や時刻でバイト列は変わり得る)
真正性が必要なら、公式ドメインの確認、TLS、デジタル署名、公開されたチェックサム、取得ログ、アーカイブ方針を組み合わせます。ハッシュはprovenanceの一要素であって、出典評価そのものではありません。
W3C PROV-Oとの関係
W3C PROV-Oは、provenanceをEntity、Activity、Agentなどの関係として相互運用可能に表す語彙です。本稿の小さなJSONスキーマはPROV-O準拠を名乗るものではありません。
ただし、「取得した資料」「抽出・変換した活動」「発行または処理した主体」を分けて考える設計思想は参考になります。組織間で由来情報を交換する要件が出たら、独自JSONからPROV-O等へのマッピングを別途設計します。最初から複雑なオントロジーを全MCPツールへ強制する必要はありません。
実装・レビューのチェックリスト
-
dataとprovenanceをトップレベルで分離した -
sourcesは1件以上を必須にした -
id、uri、title、publisher、retrievedAt、sourceTypeを必須にした - 大きな資料には
locatorを付けた - 公開日時、取得日時、適用時点を別フィールドにした
- 不明な日時や発行者をモデルに推定させていない
-
sourceRefsの参照整合性をアプリ側で検証した - JSON Schemaのformat検証設定を確認した
- 返却直前に
outputSchemaでサーバー側検証した - クライアント側でも
structuredContentを検証した -
TextContentを同じオブジェクトから生成した - ハッシュを真正性の証明と説明していない
- 取得失敗や試行提供を
warningsに残した
よくある質問
MCPには標準のcitationやprovenanceフィールドがありますか?
2026-07-28仕様はstructuredContentとoutputSchemaを定義していますが、全ツール共通のcitationやprovenanceオブジェクトを必須にはしていません。必要なフィールドは各サーバーのoutputSchemaでアプリケーション契約として定義します。
structuredContentだけ返せば十分ですか?
最新仕様を実装したクライアント同士なら構造化データを扱えますが、公式仕様は後方互換性のため、同じJSONをTextContentにも直列化して返すことを推奨しています。二つを別々に組み立てず、一つのオブジェクトから生成してください。
contentHashがあれば出典の真正性を証明できますか?
いいえ。ハッシュは取得したバイト列が後から変わっていないかを照合する材料ですが、その内容を正しい発行者が公開したことまでは証明しません。HTTPS、公式ドメイン、署名、取得ログなどを別に検証する必要があります。
まとめ
MCPで出典を保持する鍵は、モデルへ「出典を書いて」と頼むことではなく、ツールの成功条件に出典を組み込むことです。outputSchema で provenance.sources を必須化し、返却前後に検証し、同じオブジェクトを structuredContent と TextContent へ載せます。
URL、発行者、取得日時、資料種別、該当箇所を揃えれば、後工程は値から一次資料へ戻れます。公開日時・適用時点・変換履歴・ハッシュは必要に応じて追加し、それぞれが証明できる範囲を過大評価しないことが、監査可能なMCPサーバーの土台になります。
一次情報・参考リンク
- MCP 2026-07-28 Tools https://modelcontextprotocol.io/specification/2026-07-28/server/tools 公開
- MCP 2026-07-28 Base Protocol https://modelcontextprotocol.io/specification/2026-07-28/basic 公開
- MCP 2026-07-28 Schema Reference https://modelcontextprotocol.io/specification/2026-07-28/schema 公開
- JSON Schema Draft 2020-12 https://json-schema.org/draft/2020-12
- W3C PROV-O https://www.w3.org/TR/prov-o/
関連して読む
- · 参考リンク 6件
houan-mcpとe-Gov法令MCPの調査フロー|法案から現行法まで
国会提出法案をhouan-mcpで特定し、成立・公布を確認してからe-Gov法令検索へつなぐ実務フローです。法案名と法律名を混同せず、現行条文・過去時点・一次URLを証拠として残す方法を解説します。
- · 参考リンク 7件
e-Gov法令MCPとは?Claude Codeで日本法令を参照する設計と作り方
e-Gov法令APIをClaude CodeやCursorから使うMCPサーバーの仕組み、stdio設定、出典付き条文取得、安全境界、既存実装との差別化を解説します。
- · 参考リンク 5件
e-Gov法令XMLをMCP向けJSONへ変換する:条・項・号と出典を壊さない設計
e-Gov法令APIのXMLを、AIが引用しやすいMCPレスポンスへ変換する設計を解説。条・項・号の順序、施行時点、改正履歴、原文参照を失わない型と実装手順を示します。