mcpField
G
graph-atlas-mcp

graph-atlas-mcp

ローカル
github.com/darrenjrobinson開発ツール11 日前に更新

graph-atlas-mcp について

graph-atlas-mcp は、Entra などの ID 領域を含む Microsoft Graph の公開・未公開のスキーマ変更を履歴とともに追跡します。開発者や管理者は変更を検索し、権限やロールとの関係を確認して、MCP Apps のビジュアライザーで探索できます。

主な機能

  1. 01キーワードや意味によるスキーマ変更検索
  2. 02日付やオブジェクトによる変更の絞り込み
  3. 03オブジェクトの変更履歴確認
  4. 04Graph オブジェクトと権限・ロールの関連付け
  5. 05ビジュアルなスキーマグラフの探索

活用シーン

  1. 01Graph API エンドポイントの最近の変更確認
  2. 02API オブジェクトに関連する権限の確認
  3. 03Entra ロールがアクセスできる範囲の探索

MCP 対応

Microsoft Graph のスキーマ変更、スナップショット、権限、ロールを照会する MCP ツールを提供します。MCP Apps ビジュアライザーで、対応する MCP クライアント内からスキーマグラフを表示・探索できます。

設定

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

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

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

パッケージ
npmgraph-atlas-mcp0.4.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Microsoft Graph Atlas MCP

Microsoft Graph API 全体にわたるスキーマ変更を追跡する MCP サーバーです。Microsoft が文書化している変更と、文書化していない変更の両方を追跡します。Entra ID、Entra ID Governance、Identity & Access Management、Entra Agent ID、Information Protection の全領域を対象としており、公開時点で過去1年分の履歴が登録されています。MCP Apps を介して MCP クライアント内に表示される、インタラクティブなスキーマビジュアライザーも付属しています。

npm npm downloads License: MIT

README の画像

理由

Microsoft Graph は v1.0 と beta の両方で継続的に進化しています。公式の変更履歴は編集されており、不完全です。文書化されていないスキーマ変更(新しいプロパティ、削除されたリレーションシップ、新しい列挙型の値など)は、発表される前に本番環境へ反映されます。この MCP は、実際の $metadata CSDL を毎日比較し、公開コミュニティトラッカーと公式の変更履歴から過去1年分のデータを補完することで、このギャップを埋めます。

データソース

ソース内容粒度
seed-entra-mschanges.entra.ms の過去の CSDL 差分を一度だけインポートプロパティ単位
backfill-graph-changelogMicrosoft の公式「What's New」履歴を一度だけスクレイピングし、IAM のオブジェクトファミリー8種類に分類機能単位
self$metadata を毎日取得して差分を比較。初回の収集以降、継続して実施プロパティ単位

さらに2つのテーブルが、すべての変更に実際のアクセス許可/ロールのコンテキストを付与します。permissions(Merill の Graph Permissions Explorer からスクレイピングした1,036個のスコープ)と、roles(Microsoft Learn のアクセス許可リファレンス に掲載されている、135個の Entra 組み込みロールとその microsoft.directory/* アクション)です。これらは role_permission_map で相互参照されています。

クイックスタート(npx)

Node.js 22 以降が必要です(組み込みの node:sqlite を使用します)。MCP クライアントに設定を追加します。例として、 Claude Desktop の claude_desktop_config.json の場合:

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

セットアップはこれだけです。初回起動時にサーバーが、このリポジトリの GitHub Releases から公開済みの最新データベース(変更履歴、アクセス許可、ロール、埋め込みデータ)を ~/.graph-atlas-mcp/ に自動ダウンロードし、毎日のリリースに合わせて最新の状態に保ちます。

ソースから開発する

git clone https://github.com/darrenjrobinson/graph-atlas-mcp.git
cd graph-atlas-mcp
npm install
npm run build
データベースにデータを入力する(初回実行)
npm run seed                # one-off: import changes.entra.ms's ~1,600 historical records
npm run backfill            # re-runnable: scrape the official changelog for the 8 IAM families
npm run collect             # fetch v1.0 + beta $metadata, establish today's baseline snapshot
npm run collect-permissions # re-runnable, ~9 min: scrape ~1,036 Graph permission pages
npm run collect-roles       # re-runnable, ~1 min: scrape 135 Entra built-in roles + actions
npm run build-role-map      # re-runnable: cross-reference roles <-> permissions (see limitations)

プロジェクトのルートに graph-atlas.db が生成されます。npm run seed は Git で無視される一度限りのローカルスクリプト(scripts/seed-from-entra-ms.js)を使用します。このスクリプトはコミット済みのリポジトリには含まれていません。

DB は WAL ジャーナルモードを使用するため、これらの収集スクリプトは、ファイルをすでに開いている MCP クライアント(Claude Desktop など)と並行して実行しても、ロック競合は発生しません。

オプション:セマンティック検索

OPENAI_API_KEY が設定されている場合、search_changes はハイブリッド(キーワード+セマンティック)モードで自動的に実行されます。設定されていない場合は、キーワードのみの検索に切り替わります。

export OPENAI_API_KEY=sk-...
npm run embed      # generates embeddings for any change records that don't have one yet

collect の実行後に npm run embed を再実行すると、新しいレコードのみが埋め込まれます。全件を再度埋め込むのではなく、差分更新されます。

ソースのチェックアウトを MCP クライアントに接続する

開発時は、npm パッケージではなく、ビルドとローカル DB をクライアントに指定します。

{
  "mcpServers": {
    "graph-atlas": {
      "command": "node",
      "args": ["--experimental-sqlite", "/absolute/path/to/graph-atlas-mcp/dist/index.js"],
      "env": {
        "GRAPH_ATLAS_DB": "/absolute/path/to/graph-atlas-mcp/graph-atlas.db"
      }
    }
  }
}

GRAPH_ATLAS_DB は、明示的に指定した DB ファイルをサーバーに参照させます。設定されていない場合、サーバーはまず ~/.graph-atlas-mcp/graph-atlas.db(最新の GitHub Release から自動ダウンロード)を探し、次に現在の作業ディレクトリにある ./graph-atlas.db を探します。

ツール

ツール目的
search_changesすべてのソースを対象に、自然言語またはキーワードで検索します。OpenAI キーが設定されている場合はハイブリッド方式(キーワード検索+Reciprocal Rank Fusion によるセマンティック検索)、設定されていない場合はキーワード検索のみです。
get_recent_changes構造化クエリです。日付、エンドポイント、オブジェクトの種類/名前、変更の種類、ソースで絞り込みます。
get_object_history1 つのオブジェクト(例:group、accessPackage)の変更履歴全体を、古い順に表示します。すべてのソースを対象に、大文字と小文字を区別せずに照合します。
get_change_detail1 件の変更レコードの詳細全体と、同じ日付/オブジェクトに関する関連変更を表示します。
get_snapshot_summaryスナップショットごとのエンティティ、プロパティ、列挙型の数を表示します。「Graph API は現在どのくらいの規模ですか?」といった質問に使えます。
get_server_infoサーバー自体に関する情報(実行中のバージョン、変更履歴のエントリ、データの鮮度、2 つのリリースチャネル(日付タグ付きのデータベースの日次リリースと、semver による npm サーバーリリース))を表示します。
get_permission_contextGraph オブジェクトに関係する権限、それぞれの権限で可能になること、付与できるユーザー(ヒューリスティック。制限事項を参照)、および最近の変更を表示します。
schema_change_reportスキーマ/権限/ロールのグラフを構造化 JSON(UI なし)で出力します。ノードとエッジ、変更アクティビティの件数を含み、推論に利用できます。
visualize_schema_graphMCP クライアント内で、インタラクティブな Graph Atlas ビジュアライザーを開きます(MCP Apps経由)。検索、展開、ノードごとの詳細表示が可能な D3 の力学ベースのグラフです。以下を参照してください。
expand_schema_node開いているビジュアライザーのノードを 1 つ展開します(または、モデルに 1 ノードの近傍差分を提供します)。アプリのダブルクリック/展開操作を支えます。
search_schema_objectsエンティティの種類、権限、ロールを名前で検索し、曖昧な名前を正規のノード ID に解決します。アプリの検索ボックスを支えます。
get_node_timelineアプリ専用です。ビジュアライザーの詳細パネル用に、簡潔な変更タイムラインを表示します(モデルは代わりに get_object_history を使用します)。
クエリの例
  • 「Agent ID Graph API の最近の変更は何ですか?」
  • 「グループの API に入れ子化に関する変更はありましたか?」
  • 「accessPackageSuggestion リソースの履歴はどうなっていますか?」
  • 「過去 7 日間に beta エンドポイントで何が変更されましたか?」
  • 「機密ラベルまたは DLP ポリシーの変更を表示してください」

スキーマビジュアライザー

visualize_schema_graph は Graph Atlas ビジュアライザーを開きます。これは、MCP Apps (Claude Desktop、ChatGPT、VS Code などの準拠ホスト)を通じて、MCP クライアント内に直接表示される d3 の力学ベース SVG グラフです。アーキテクチャとルック&フィールは、EntraPulse Polyarchy から移植されています。

  • ダークテーマのクローム(ライトテーマはホストに準拠):ピル型のビュータブ、ガラス風パネル、ノード/エッジ/ツール呼び出しのライブ件数を表示する下部ステータスバー。
  • 追加型キャンバス+セッションキャッシュ — 探索するにつれてグラフが蓄積されます。任意のノードをダブルクリックするか、パネルの フォーカスに設定 ボタンを押すと、そのノードにコンテキストが切り替わります。ホップ距離が再設定され、キャンバスがノードを中央に表示するよう移動し、その近傍が展開されます。このセッションですでに取得済みの項目は、キャッシュから即座に再展開され、ツール呼び出しの再実行はゼロです。リセットするとキャンバスはクリアされますが、キャッシュは保持されます。
  • 検索 — ツールバーの検索ボックス(search_schema_objects を使用)で、エンティティの種類、アクセス許可、ロールを名前で検索し、選択した項目にフォーカスを切り替えます。
  • 詳細パネル — 種類ごとのフィールド(エンティティの場合はプロパティ/ナビゲーション/変更、アクセス許可の場合はアプリ/委任の同意と説明、ロールの場合は影響範囲/公開アクション/テンプレート ID)に加えて、パネル内に変更履歴のタイムラインを表示します(get_node_timeline を使用)。
  • 配置変更可能なレイアウト — ノードをドラッグするとドロップした場所に固定されるため、密集した近傍を読みやすくするためにクラスターを引き離せます。新たな展開は、展開元のノードから広がります。
  • カラー表現 — エンティティの種類はフォーカスからの距離に応じた色合い(青のグラデーション)で表示されます。アクセス許可とロールは関連性を示す色(緑の 関連/琥珀色の 付与)をまとい、距離に応じて色が薄くなります。赤はシグナルとして使われます。赤い実線のリングは特権ロールと管理者の同意が必要なアクセス許可を示し、琥珀色/赤色のアクティビティドットは最近変更されたエンティティを示します。凡例(左下)は表示フィルターも兼ねており、関連性やオブジェクトの種類のチェックを外すと、その項目が薄く表示されます。
  • モデル認識 — フォーカスや展開が変わるたびにアプリが updateModelContext を送信するため、アシスタントは追加のツール呼び出しなしで画面上の内容を把握できます。

質問の起点に合わせて、view(またはアプリ内のタブ)で選べる3つのピボット軸があります。Role、Permission、またはエンティティ/APIから開始できます。

  • entity — グラフのエンティティの種類。エッジはナビゲーションプロパティと継承を表します。 focus_object = group のようなエンティティ。Permission タブでエンティティを展開すると、それに関連するアクセス許可が表示されます。Role タブでは2ホップ先まで表示され、それらのアクセス許可に加え、それを付与するロールも表示されます(そのため、user を展開すると User Administrator、Helpdesk Administrator などが表示されます)。
  • permission — アクセス許可スコープ、それに関連するエンティティ、およびそれを付与するロール。 focus_object = User.Invite.All のようなアクセス許可。
  • role — Entra ロール、それが付与するアクセス許可、およびそれらが関連するエンティティ(2ホップ先まで)。focus_object = User Administrator のようなロール。ロールで実際に何ができるか、また最小権限の比較に関する質問に答えるためのビューです。

npm run build でビルドします(サーバーの tsc、app-ui の型チェックに続いて、esbuild が app-ui/atlas-app/ を自己完結型の単一ファイル dist/app-ui/atlas-app.html にバンドルします。MCP App のリソースは、外部ネットワークへの依存がない単一の塊である必要があります。リソース URI は ui://graph-atlas/atlas-app.html です)。サーバーは起動時にビルド済み HTML を一度読み込むため、再ビルド後は MCP クライアント(またはサーバー接続)を再起動してください。

MCP Jam でのテスト
# published package
npx @mcpjam/inspector@latest npx -y graph-atlas-mcp

# or a source checkout
GRAPH_ATLAS_DB=/absolute/path/to/graph-atlas.db \
  npx @mcpjam/inspector@latest node --experimental-sqlite /absolute/path/to/dist/index.js

ソースをチェックアウトしてテストする場合、すべてのパスを絶対パスにする必要があります。MCP Jam は独自の作業ディレクトリからサーバーを起動するためです。MCP Jam(v2.34)について知っておくべき注意点が2つあります。ウィジェットが表示されるのは MCP Jam ホストプロファイル のみです(「Claude」ホストエミュレーションプロファイルでは、ウィジェットの iframe が「loading」のままになります)。また、ウィジェットが空白になる原因を診断するには、ウィジェットの Sandbox タブと debug/widget-visibility トレースイベントを確認するのが最も手早い方法です。

注意:エンティティノード ID はどこでも小文字(accessreview)ですが、表示ラベルでは CSDL の大文字小文字を維持します(accessReview)。CSDL と権限ソースデータではエンティティ名の大文字小文字が一貫していないため、正規 ID を使うことで、すべてのビューで同じエンティティを1つのノードとして扱えます。

この実装中に検出して修正した実際のバグ:

  • CSDL の短縮 graph. 名前空間エイリアスが削除されず、エッジがすべて黙ってゼロになっていました。
  • permissions.resources のエンティティ名は Merill のページ間で大文字小文字が一貫しておらず、同じエンティティが見た目の似た2つのノードに分割され、その間に接続先のないエッジができるところでした。
  • MCP Apps の autoResize(デフォルトで有効)は、アプリ自身のドキュメントのコンテンツの高さを基に iframe のサイズを決めます。高さ全体を使うフレックスアプリには役立ちません。現在、アプリではこれを無効にし、スペースを明示的に確保します(対応している場合は全画面表示、それ以外の場合は高さのあるインラインフレーム)。
  • 元の force-graph(canvas)実装では、graphData() の直後、デバウンスされたレイアウトによってノードの位置が割り当てられる前に、同期的に zoomToFit を呼び出していました。その結果、ズーム変換が NaN になり、初回以降の再レンダリングで canvas が常に空白になっていました。d3/SVG への移植により、この種のバグを解消しました。シミュレーションは同期的に実行され、中央揃え処理では配置されていないノードを考慮します。
  • UI は変更期間ピッカーの値("30")を送信していましたが、サーバーは ISO 日付を辞書順で比較していたため、変更数がすべて黙ってゼロになっていました。現在は since で両方の形式を受け付け(日数はサーバー側で正規化)、UI も引き続き ISO 日付に変換します。
  • ブラウザーは非表示の iframe 内で requestAnimationFrame を停止するため、ホストがウィジェットを非表示にしている間にグラフを初期化すると、d3 のシミュレーションでレイアウトされず、すべてのノードが原点に重なって表示されていました。新しいノードには展開元の隣に明示的な初期位置を設定し、構造のレンダリングごとにレイアウトを同期的に1回実行します。また、canvas が再び表示されると IntersectionObserver がシミュレーションを再開します。
  • autoResize を無効にしても、一部のホスト(Claude Desktop のアプリ領域など)はアプリが報告した高さを基に iframe のサイズを決めます。現在、アプリは表示モードのネゴシエーション後に必ずサイズを報告し、ホストから containerDimensions が公開されている場合はそれを使います。また、ホストコンテキストが変わるたびにサイズを再報告します。

動作の仕組み

  1. 毎日の収集(.github/workflows/collect.yml、UTC 02:00)では、両方のエンドポイントから $metadata を取得します。どちらも一般公開されており、Entra アプリの登録は不要です。
  2. scripts/parse-csdl.js は CSDL XML を構造化 JSON(エンティティ型/複合型/列挙型、プロパティ、ナビゲーションプロパティ、エンティティセット、シングルトン、関数/アクション)に解析します。
  3. scripts/diff-snapshots.js は、今日の解析結果を snapshots/v1.0/ と snapshots/beta/ に保存されている最新のスナップショットと比較します(監査証跡としてリポジトリにコミットされています)。
  4. 検出された変更は source = 'self' として graph-atlas.db に挿入されます。変更が見つかった場合は、scripts/create-release.js が更新された GitHub Release を公開します。
  5. MCP クライアントは、ローカルキャッシュより新しい最新リリースがあれば、起動時に自動でダウンロードします。

既知の制限事項

  • キーワード検索では、実際の BM25 ではなく、LIKE ベースの照合を使用します。Node に組み込まれている node:sqlite には FTS5 拡張機能が含まれていません。ランキングには、単純な用語の網羅率と出現頻度に基づくヒューリスティックを使用します。
  • セマンティック検索には OPENAI_API_KEY が必要です。ベクトルの保存には sqlite-vec を使用します(同梱されており、外部のベクトルデータベースは不要です)。
  • $metadata の差分検出が対象とするのはスキーマレベルの変更のみです。CSDL 自体に現れない動作、権限、エンドポイントレベルの変更は対象外です。
  • 遡及入力された変更履歴レコードは、シードデータや自己収集データのようなプロパティレベルではなく、「X リソース型を追加」のような機能レベルの内容です。公式の変更履歴には CSDL フラグメントが含まれていません。
  • get_permission_context はレスポンスサイズを制限します。 user のような一般的なオブジェクトは 190 件以上の権限に一致し、Directory.ReadWrite.All のような広範な権限には 300 件以上のエンドポイントが列挙されます。テストでは、上限のないレスポンスが 417KB に達し、実際に MCP トランスポートの切断を引き起こしました。オブジェクト名によるクエリでは、権限がリソース数の少ない順に 25 件まで(limit パラメーターで最大 50 件)に制限され、さらに一致する項目があるかどうかは total_matching_count で確認できます。各権限の graph_endpoints は 10 件までに制限され、graph_endpoints_total_count/graph_endpoints_truncated で全体数と切り捨ての有無を確認できます。特定の権限の詳細を切り捨てなしで取得するには、permission_name で絞り込んでください。
  • grantable_by(ロールと権限の対応付け)は、信頼できる公式の対応付けではなく、ヒューリスティックな相関です。 Microsoft は、Entra RBAC アクション(microsoft.directory/*)と OAuth 権限スコープ(User.Read.All など)の公式な対応表を公開していません。この 2 つは、たまたま重複するリソース型を管理する別々の認可システムです。scripts/build-role-permission-map.js は、権限の主なリソース(権限名から導出。例:AdministrativeUnit.Read.All → administrativeUnit)を、同じリソースに対するロールのアクションと照合します。grantable_by の結果を信頼できるものとして扱う前に、必ず確認してください。照合は、単純な「読み取り対書き込み」という大まかな二分法ではなく、操作カテゴリ(read/create/update/delete/restore/enable/disable/invite/license/session/all)に基づきます。以前の二分法によるバージョンでは、誤検出が確認されていました。「Directory Writers」には users に対する create/update/enable/disable アクションはありますが、delete/restore アクションはありません。それにもかかわらず、両方が「write-tier」であるというだけで、User.DeleteRestore.All に対して grantable_by に表示されていました。Graph の細分化された権限名(DeleteRestore、EnableDisableAccount、Invite、ReadUpdate など)は、設計上、操作ごとに分かれています。そのため、permissionRequiredCategories() は各動詞セグメントを、それを満たす特定のアクションカテゴリに対応付けます。Microsoft の組み込みロールのリファレンスを使い、ゲストのライフサイクルに関する一連の操作(invite/create/update/enable-disable/delete-restore × Guest Inviter/Directory Writers/User Administrator、計 15 通り)すべてで照合を検証済みです。認識されない動詞や利用頻度の低い動詞(ReadWrite、Write、Manage、FullControl、および Teams/Chat 固有の比較的まれな約 75 種類のバリエーション)では、「何らかの変更アクションがあれば満たす」という判定にフォールバックします。広範な権限は、部分的な書き込み機能でも実際に満たされるため、これらの特定の動詞では、引き続きやや大まかな指標となります。
  • RBAC アクションが一切公開されていない Entra ロールもあります(現在は Purview Workload Content ロール 3 種類)。これらの権限は、Entra の外部で Microsoft Purview のロールグループとファーストパーティの同期アプリを通じて管理されるため、ロールと権限の対応付けはできません。ビジュアライザーと検索では、「0 件の権限を付与」と誤解を招く表示をするのではなく、「公開されたアクションなし — Entra の外部で管理」と表示します。
  • ロールの Graph API ルート(GET /roleManagement/directory/roleDefinitions)を利用するには、このプロジェクトでは構成されていない RoleManagement.Read.Directory と Application.Read.All を持つアプリ登録が必要です。そのため、collect-roles.js では PRD に記載された代替手段(Microsoft Learn の公開権限リファレンスのスクレイピング)を使用します。
  • permissions.combined_with(複数のスコープを組み合わせて必要とするエンドポイントがある場合。例:Application.Read.All and Policy.Read.All)は設定されていません。Merill のページ構造からは、十分な信頼性でスクレイピングできないためです。

謝辞

このプロジェクトは、Entra コミュニティの他のメンバーによるデータおよび設計の成果を基盤としています。ここでは、プロジェクトの共同作成者ではなく、データソースおよび着想元としてクレジットを記載しています。

  • Eric — changes.entra.ms の作成者。過去の変更データの元となる CSDL 差分トラッカーです
  • Merill Fernando — Graph Permissions Explorer の作成者。アクセス許可の拡充(§6)のデータソースです
  • EntraPulse Polyarchy — Darren Robinson 自身による以前の MCP。その d3 force-graph/MCP Apps アーキテクチャ(デザインシステム、セッションキャッシュ、コンテキスト切り替えのインタラクションモデル)が、Graph Atlas ビジュアライザーの基盤となっています

ライセンス

MIT

コメント

MCP は初めてですか?

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

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