Skip to main content
Glama

Microsoft Graph Atlas MCP

An MCP server that tracks schema changes across the Microsoft Graph API — both the changes Microsoft documents and the ones it doesn't. Covers the full Entra ID, Entra ID Governance, Identity & Access Management, Entra Agent ID, and Information Protection surface, seeded with a year of history at launch. Ships with an interactive schema visualiser rendered inside the MCP client via MCP Apps.

npm npm downloads License: MIT

Why

Microsoft Graph evolves continuously across v1.0 and beta. The official changelog is curated and incomplete — undocumented schema changes (new properties, removed relationships, new enum values) land in production before they're announced. This MCP closes that gap by diffing the actual $metadata CSDL daily, and backfills a year of history from both a public community tracker and the official changelog.

Related MCP server: ms-365-admin-mcp-server

Data sources

Source

What it is

Granularity

seed-entra-ms

One-time import of changes.entra.ms's historical CSDL diffs

Property-level

backfill-graph-changelog

One-time scrape of Microsoft's official "What's New" history, classified into 8 IAM object families

Feature-level

self

Daily $metadata fetch + diff, ongoing from first collection

Property-level

Two further tables enrich every change with real-world permission/role context: permissions (1,036 scopes scraped from Merill's Graph Permissions Explorer) and roles (135 Entra built-in roles and their microsoft.directory/* actions, from the Microsoft Learn permissions reference), cross-referenced into role_permission_map.

Quick start (npx)

Requires Node.js 22+ (uses the built-in node:sqlite). Add to your MCP client — e.g. Claude Desktop's claude_desktop_config.json:

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

That's the whole setup: on first launch the server auto-downloads the latest published database (change history, permissions, roles, embeddings) from this repo's GitHub Releases into ~/.graph-atlas-mcp/, and keeps it current against the daily release cadence.

Developing from source

git clone https://github.com/darrenjrobinson/graph-atlas-mcp.git
cd graph-atlas-mcp
npm install
npm run build

Populate the database (first run)

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)

This produces graph-atlas.db in the project root. npm run seed uses a gitignored, one-off local script (scripts/seed-from-entra-ms.js) — it isn't part of the committed repo.

The DB uses WAL journal mode so these collection scripts can run concurrently with an MCP client that already has the file open (e.g. Claude Desktop) without lock contention.

search_changes runs in hybrid (keyword + semantic) mode automatically if OPENAI_API_KEY is set, and degrades to keyword-only otherwise:

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

Re-running npm run embed after a collect only embeds new records — it's incremental, not a full re-embed.

Connect a source checkout to an MCP client

When developing, point the client at your build and local DB instead of the npm package:

{
  "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 points the server at an explicit DB file. Without it, the server looks for ~/.graph-atlas-mcp/graph-atlas.db (auto-downloaded from the latest GitHub Release), then falls back to ./graph-atlas.db in the current working directory.

Tools

Tool

Purpose

search_changes

Natural-language or keyword search across all sources. Hybrid (keyword + semantic via Reciprocal Rank Fusion) when an OpenAI key is configured, keyword-only otherwise.

get_recent_changes

Structured query — filter by date, endpoint, object type/name, change kind, source.

get_object_history

Full change history for one object (e.g. group, accessPackage), oldest to newest. Matches case-insensitively across sources.

get_change_detail

Full detail for a single change record, plus related changes from the same day/object.

get_snapshot_summary

Entity/property/enum counts per snapshot — "how big is Graph API right now?"

get_server_info

About the server itself — running version, changelog entry, data freshness, and the two release channels (daily calendar-tagged database releases vs semver npm server releases).

get_permission_context

Which permissions touch a Graph object, what each unlocks, who can grant them (heuristic — see limitations), and its recent changes.

schema_change_report

Structured JSON (no UI) of the schema/permission/role graph — nodes + edges + change-activity counts, for reasoning over.

visualize_schema_graph

Opens the interactive Graph Atlas visualiser inside the MCP client (via MCP Apps) — a D3 force-directed graph with search, expand, and per-node detail. See below.

expand_schema_node

Expands one node of the open visualiser (or feeds the model a one-node neighborhood delta) — powers the app's double-click/Expand interactions.

search_schema_objects

Name search across entity types, permissions, and roles — resolves fuzzy names to canonical node ids; powers the app's search box.

get_node_timeline

App-only: compact change timeline for the visualiser's detail panel (the model uses get_object_history instead).

Example queries

  • "What are the recent changes to Agent ID Graph APIs?"

  • "Have there been changes to groups APIs for nesting?"

  • "What's the history of the accessPackageSuggestion resource?"

  • "What changed in the last 7 days on the beta endpoint?"

  • "Show me sensitivity label or DLP policy changes"

Schema visualiser

visualize_schema_graph opens the Graph Atlas visualiser — a d3 force-directed SVG graph rendered directly inside the MCP client via MCP Apps (Claude Desktop, ChatGPT, VS Code, and other compliant hosts). Its architecture and look & feel are ported from EntraPulse Polyarchy:

  • Dark-themed chrome (light theme follows the host): pill view tabs, glass panels, a bottom status bar with live node/edge/tool-call counts.

  • Additive canvas + session cache — the graph accumulates as you explore. Double-click any node (or the panel's Set as focus button) to flip context to it: hop distances re-anchor, the canvas glides to center it, and its neighborhood expands. Anything already fetched this session re-expands instantly from cache with zero repeat tool calls. Reset clears the canvas but keeps the cache.

  • Search — the toolbar search box (backed by search_schema_objects) matches entity types, permissions, and roles by name and flips focus to your pick.

  • Detail panel — per-kind fields (properties/navigations/changes for entities, split app/delegated consent + description for permissions, blast radius/published actions/template id for roles), plus an in-panel change-history timeline (backed by get_node_timeline).

  • Rearrangeable layout — drag a node and it stays pinned where you drop it, so you can pull clusters apart to read dense neighborhoods; new expansions bloom out of the node they came from.

  • Color language — entity types shade by distance from the focus (blue ramp); permissions and roles wear their relationship colour (green touches / amber grants), faded with distance. Red is reserved as a signal: a solid red ring marks privileged roles and admin-consent permissions, and an amber/red activity dot marks recently-changed entities. A legend (bottom-left) doubles as a visibility filter — unchecking a relationship or object type dims it.

  • Model awareness — the app pushes updateModelContext after every focus/expansion, so the assistant knows what's on screen without extra tool calls.

Three pivot dimensions, chosen via view (or the in-app tabs) so you can start wherever the question starts — a Role, a Permission, or an entity/API:

  • entity — Graph entity types; edges are navigation properties and inheritance. focus_object = an entity like group. Expanding an entity on the Permission tab reveals the permissions that touch it; on the Role tab it goes two hops — those permissions plus the roles that grant them (so expanding user surfaces User Administrator, Helpdesk Administrator, and friends).

  • permission — a permission scope, the entities it touches, and the roles that grant it. focus_object = a permission like User.Invite.All.

  • role — an Entra role, the permissions it grants, and the entities those touch (two hops). focus_object = a role like User Administrator. This is the one that answers "what can this role actually do" / least-privilege comparison questions.

Build it with npm run build (server tsc, an app-ui typecheck, then esbuild bundles app-ui/atlas-app/ into a single self-contained dist/app-ui/atlas-app.html — MCP App resources must be one blob with no external network dependencies; the resource URI is ui://graph-atlas/atlas-app.html). The server reads the built HTML once at startup, so restart your MCP client (or the server connection) after rebuilding.

Testing with 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

For source checkouts all paths must be absolute — MCP Jam spawns the server from its own working directory. Two MCP Jam (v2.34) quirks to know about: widgets only render under the MCP Jam host profile (the "Claude" host-emulation profile leaves the widget iframe stuck at "loading"), and the widget's Sandbox tab / debug/widget-visibility trace events are the fastest way to diagnose a blank widget.

Note: entity node ids are lowercase everywhere (accessreview), with display labels keeping CSDL casing (accessReview) — entity names aren't consistently cased across the CSDL and the permission source data, and a canonical id is what lets one entity stay one node across all views.

Real bugs caught and fixed while building this:

  • CSDL's short graph. namespace alias wasn't stripped (silently produced zero edges).

  • permissions.resources entity names aren't consistently cased across Merill's pages (would have silently split one entity into two duplicate-looking nodes with a dangling edge between them).

  • MCP Apps' autoResize (on by default) sizes the iframe off the app's own document content height — useless for a full-height flex app. The app now disables it and claims space explicitly (fullscreen where supported, a tall inline frame otherwise).

  • The original force-graph (canvas) implementation called zoomToFit synchronously after graphData() — before the debounced layout had assigned node positions — producing a NaN zoom transform and a permanently blank canvas on every re-render after the first. The d3/SVG port eliminates the bug class: the simulation is synchronous and centering guards unplaced nodes.

  • The UI sent its change-window picker values ("30") where the server compares ISO dates lexicographically, silently zeroing every change count. since now accepts both (day counts are normalized server-side) and the UI converts to ISO dates anyway.

  • Browsers freeze requestAnimationFrame in hidden iframes, so a graph seeded while the host had the widget hidden never got laid out by d3's simulation — every node rendered stacked at the origin. New nodes now get explicit starting positions next to their expansion source, every structural render ticks the layout synchronously once, and an IntersectionObserver reheats the simulation when the canvas becomes visible again.

  • With autoResize off, some hosts (Claude Desktop's app surface) still size the iframe from the app's reported height — the app now always reports a size after display-mode negotiation, using the host's containerDimensions when published, and re-reports on host-context changes.

How it works

  1. Daily collection (.github/workflows/collect.yml, 02:00 UTC) fetches $metadata for both endpoints — both are publicly accessible, no Entra app registration required.

  2. scripts/parse-csdl.js parses the CSDL XML into structured JSON (entity/complex/enum types, properties, navigation properties, entity sets, singletons, functions/actions).

  3. scripts/diff-snapshots.js compares today's parse against the most recent stored snapshot in snapshots/v1.0/ and snapshots/beta/ (committed to the repo as the audit trail).

  4. Detected changes are inserted into graph-atlas.db with source = 'self'; if any changes were found, scripts/create-release.js publishes an updated GitHub Release.

  5. MCP clients auto-download the latest release on startup if newer than their local cache.

Known limitations

  • Keyword search uses LIKE-based matching, not real BM25 — Node's bundled node:sqlite doesn't ship the FTS5 extension. Ranking is a simple term-coverage/frequency heuristic.

  • Semantic search requires OPENAI_API_KEY; vector storage uses sqlite-vec (bundled, no external vector DB).

  • $metadata diffing covers schema-level changes only — not behavioral, permission, or endpoint-level changes that don't show up in the CSDL itself.

  • Backfilled changelog records are feature-level ("Added the X resource type"), not property-level like the seed and self-collected data — the official changelog doesn't include CSDL fragments.

  • get_permission_context caps response size. A common object like user matches 190+ permissions, and broad permissions like Directory.ReadWrite.All list 300+ endpoints — an uncapped response hit 417KB in testing and caused a real MCP transport disconnect. Object-name queries are capped to 25 permissions (narrowest-first by resource count, limit param up to

    1. with total_matching_count telling you if more exist; each permission's graph_endpoints is capped to 10 with graph_endpoints_total_count/graph_endpoints_truncated. Filter to a specific permission_name to get one permission's full, untruncated detail.

  • grantable_by (role<->permission mapping) is a heuristic correlation, not an authoritative mapping. Microsoft doesn't publish an official crosswalk between Entra RBAC actions (microsoft.directory/*) and OAuth permission scopes (User.Read.All, etc.) — they're two separate authorization systems that happen to govern overlapping resource types. scripts/build-role-permission-map.js matches a permission's primary resource (derived from its own name, e.g. AdministrativeUnit.Read.All -> administrativeUnit) against roles' actions on that same resource. Verify grantable_by results before treating them as authoritative. Matching is by operation category (read/create/update/delete/restore/enable/disable/invite/ license/session/all), not a coarse read-vs-write binary — an earlier binary version produced a confirmed false positive ("Directory Writers" has create/update/enable/disable actions on users but no delete/restore action, yet appeared grantable_by for User.DeleteRestore.All simply because both were "write-tier"). Graph's own granular permission names (DeleteRestore, EnableDisableAccount, Invite, ReadUpdate, ...) are operation-specific by design, so permissionRequiredCategories() maps each verb segment to the specific action categories that satisfy it — verified against Microsoft's built-in roles reference across the full guest-lifecycle operation set (invite/create/update/enable-disable/delete-restore × Guest Inviter/Directory Writers/User Administrator, all 15 combinations exact). Unrecognized/ long-tail verbs (ReadWrite, Write, Manage, FullControl, and ~75 rarer Teams/Chat-specific variants) fall back to "any mutate action satisfies" — a broad permission genuinely is satisfied by partial write capability, so this remains a coarser signal for those specific verbs.

  • A few Entra roles publish no RBAC actions at all (currently the three Purview Workload Content roles) — their permissions are managed outside Entra via Microsoft Purview role groups and a first-party sync app, so no role↔permission mapping is possible. The visualiser and search label these "no published actions — managed outside Entra" rather than showing a misleading "grants 0 permissions".

  • Roles' Graph API route (GET /roleManagement/directory/roleDefinitions) requires an app registration with RoleManagement.Read.Directory + Application.Read.All that this project doesn't have configured — collect-roles.js uses the PRD's documented fallback (scraping the public Microsoft Learn permissions reference) instead.

  • permissions.combined_with (some endpoints require multiple scopes together, e.g. Application.Read.All and Policy.Read.All) isn't populated — Merill's page structure doesn't expose this reliably enough to scrape.

Acknowledgments

This project builds on data and design work from others in the Entra community — credited here as data sources and inspiration, not as project co-authors:

  • Eric — creator of changes.entra.ms, the CSDL-diff tracker that seeds our historical change data

  • Merill Fernando — creator of the Graph Permissions Explorer, the data source for permission enrichment (§6)

  • EntraPulse Polyarchy — Darren Robinson's own prior MCP; its d3 force-graph / MCP Apps architecture (design system, session cache, context-flip interaction model) is the foundation of the Graph Atlas visualiser

License

MIT

Available Tools

12 tools
expand_schema_nodeA

Expand one node of the schema graph and return a {nodes, edges, message} delta to merge into the canvas — the interactive companion to visualize_schema_graph. kind="EntityType" with view="entity" returns the schema neighborhood (navigation targets, base type, referrers); with view="permission" the permissions that touch the entity; with view="role" those permissions plus the roles granting them (heuristic role map). kind="Permission" returns touched entities plus the roles granting it. kind="Role" returns granted permissions and their entities.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYes
viewNoSteers EntityType expansion: schema neighborhood vs permission usageentity
sinceNoChange-activity window — ISO date or day count (e.g. "30")
node_idYesNode id — a lowercase entity type, or a permission or role name (casing ignored)
endpointNoOnly applies to EntityType schema neighborhoodsv1.0

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even without annotations, the description discloses the output shape, the variant-specific behaviors, and the fact that the role mapping is a 'heuristic role map.' It also makes clear result is a delta to merge into the canvas. A minor gap is that it doesn't explicitly state read-only/side-effect semantics, but the wording strongly implies a graph-query operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the main purpose and is information-dense without wasted words. It is a single long sentence, but the enumerations are clear and every clause adds behavioral value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations and no output schema, the description is unusually complete: it explains the return structure and all kind/view combinations. The only notable gap is that the effects of optional params like since and endpoint are not fully integrated into the behavior description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already high (80%), and the description adds further meaning beyond the schema by explaining exactly what each kind and view combination yields. The description particularly clarifies the ambiguous view parameter for EntityType and the difference between entity/permission/role expansion.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and resource: 'Expand one node of the schema graph' and clearly defines the return as a {nodes, edges, message} delta. It distinguishes itself from the sibling visualize_schema_graph by calling itself 'the interactive companion,' and it enumerates what each kind returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use it for expanding a single node with different views rather than the whole schema graph. It also explains which behavior to expect for EntityType vs Permission vs Role, although it does not explicitly name sibling tools as alternatives to avoid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_change_detailA

Full detail for a single change record, including related changes from the same snapshot/object, and permission context (required permissions, admin consent, grantable-by roles — see get_permission_context for the heuristic caveat).

ParametersJSON Schema
NameRequiredDescriptionDefault
change_idYesChange record ID

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and discloses key behavior: it returns related changes and permission context, and warns that the permission context is heuristic, pointing to another tool for the caveat. This adds valuable context beyond a simple 'get' operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that is front-loaded with the core purpose and then efficiently packs related details and a pointer to another tool. It is concise without being overly terse, though splitting into two sentences could improve readability slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with no output schema, the description adequately covers what is returned (full detail, related changes, permission context) and drawbacks (heuristic caveat). It is sufficiently complete for an AI agent to decide whether to use it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter is described adequately as 'Change record ID'. The description does not add further parameter-level detail, so the schema does the heavy lifting, meeting the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Full detail for a single change record' with a specific verb and resource, distinguishing it from sibling tools like get_recent_changes and search_changes. It further differentiates by mentioning related changes and permission context, explicitly pointing to get_permission_context for the heuristic caveat.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (when full detail on a single change record is needed) and references get_permission_context for a specific caveat, giving an alternative. It does not explicitly state when not to use it, but the context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_node_timelineA

Compact newest-first change timeline for one schema object, sized for the visualizer detail panel. App-facing companion to get_object_history.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sinceNoISO date or day count (e.g. "90")
node_idYesEntity type name (case-insensitive)
endpointNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the timeline is newest-first and compact, which is useful. But it does not describe what a 'change timeline' contains, how the limit parameter behaves, or whether it is read-only (though this is implied). More detail could be added without much cost.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose, and no redundant phrasing. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is adequate for a simple read tool but lacks details on return format or content. With no output schema, the agent must infer what a 'timeline' consists of. The reference to get_object_history helps, but more explicit information about the response shape would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%, and the description adds no information about parameters. It does not explain the meaning of 'limit' or 'endpoint', and 'since' is only briefly described in the schema. The description should compensate for half the parameters being undocumented, but it does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns a compact newest-first change timeline for a single schema object, and the phrase 'App-facing companion to get_object_history' distinguishes it from the sibling get_object_history tool. This is a specific verb+resource with clear scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description indicates it is the app-facing companion to get_object_history and is sized for the visualizer detail panel, which gives clear context for when to use it. However, it does not explicitly state when not to use it or mention alternatives like get_recent_changes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_object_historyA

Full change history for a specific Graph object type, oldest to newest — "what has happened to X over time?"

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceNoISO date (YYYY-MM-DD)
endpointNo
object_nameYese.g. group, application, accessPackage, conditionalAccessPolicy

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does disclose significant behavior: 'full history' and 'oldest to newest' (ordering). However, it omits any mention of read-only semantics, pagination, rate limits, or return format, which are common behavioral disclosures for history tools. The provided ordering is useful, but the lack of other context keeps it at a mid-range score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that succinctly communicates the tool's core functionality and ordering. There is no wasteful text, and the structure is clear and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of output schema and annotations, the description is somewhat thin. It conveys purpose and ordering but does not describe the response shape, any limitations, or prerequisites. For a 3-parameter tool, this is acceptable but leaves gaps that could confuse an agent expecting more operational detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67%, and the description does not compensate for the undocumented 'endpoint' parameter. The phrase 'specific Graph object type' loosely references object_name, but adds no real meaning beyond the schema's examples. The 'since' parameter is not mentioned, so the description adds little value to parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves 'full change history for a specific Graph object type, oldest to newest', which is a specific verb+resource. It also includes a user-oriented question ('what has happened to X over time?') and distinguishes from siblings like get_recent_changes by emphasizing 'full' and chronological order.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: when you need a complete historical timeline of a Graph object. It implies a contrast with recent-changes tools, but does not explicitly name alternatives or provide when-not-to-use guidance, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_permission_contextA

Two modes. (1) Pass object_name: which permissions touch a Graph object, what each unlocks, who can grant them, and its recent changes. (2) Pass permission_name alone (e.g. when comparing "is there a less-privileged alternative to Synchronization.ReadWrite.All"): that permission's detail plus other permissions with overlapping resource scope, annotated with resource_count and is_ownership_scoped (OwnedBy-suffixed permissions restrict to owned objects only) so you can reason about the tradeoff yourself — this does NOT rank or claim to compute "least privilege" automatically, since resource-type count and instance-level ownership scoping are different privilege axes. Role<->permission cross-referencing is a heuristic correlation (no official Microsoft crosswalk exists) — treat "grantable_by" as a strong signal to verify, not ground truth.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax permissions to return when using object_name (sorted narrowest-first by resource count); broad objects like "user" can match 100+
endpointNo
object_nameNoe.g. administrativeUnit, user, group, accessPackage, synchronizationJob
permission_nameNoA specific permission scope, e.g. AdministrativeUnit.Read.All or Synchronization.ReadWrite.All. If object_name is omitted, returns this permission's detail plus resource-overlapping alternatives to compare.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden for behavioral disclosure. It explicitly states that it does NOT rank or compute least privilege automatically, explains why resource count and ownership scoping are different axes, and warns that role-permission cross-referencing is heuristic and not ground truth. This gives the agent a realistic model of the tool's capabilities and limitations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but efficiently structured, opening with 'Two modes' and then detailing each mode and relevant caveats. Every sentence contributes value, including the anti-goal clarification about least privilege and the heuristic caveat. It is long but not wasteful, and front-loaded with the most important usage differentiator.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and lack of output schema, the description is remarkably complete. It describes what each mode returns, the fields used for reasoning, the notion of ownership scoping, and important failure modes (heuristic correlation). It even clarifies that the tool does not decide for the user, which sets expectations for downstream reasoning. The only minor gap is not detailing the behavior of 'recent changes', but this is not critical to selecting/invoking the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaningful context beyond the schema by explaining how object_name and permission_name mode switch, and what is_ownership_scoped means in the output. It does not elaborate on limit or endpoint, but limit has a schema description and endpoint is an enum. The addition clarifies the relationship between parameters and the output semantics, so it goes beyond the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function with specific verbs: it lists permissions touching a Graph object, what each unlocks, who can grant them, and recent changes. It also details the second mode for comparing a permission's detail with overlapping alternatives. This is distinct from sibling tools focused on history, schema, or change snapshots.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use each mode, including a concrete example comparing a less-privileged alternative. It implies when to use the tool (for permission analysis) and hints at limitations (does not rank or claim to compute least privilege). However, it does not explicitly name alternatives or exclusions relative to sibling tools, so it stops short of full usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recent_changesC

Structured, filterable query over the change history — filter by date, endpoint, object type/name, change kind, and source.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sinceNoISO date (YYYY-MM-DD); defaults to 7 days ago
sourceNo
endpointNo
change_kindNo
object_nameNoe.g. group, user, conditionalAccessPolicy
object_typeNoe.g. EntityType, EnumType, ComplexType, ObjectInstance

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It indicates a read-only query via the word 'query' but omits important behavior such as default date range, pagination, output format, or side effects. The description does not add meaningful context beyond the basic query nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that efficiently summarizes the tool's purpose and main features. There is no wasted wording, and it is easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 7 optional parameters, no output schema, and no annotations, the description is too sparse. It lacks critical context such as what 'recent' means (time range), default behavior, how results are returned, or how this differs from sibling tools like search_changes. The tool is not adequately specified for an agent to select and invoke it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 43%, so the description partially compensates by listing filter dimensions (date, endpoint, object type/name, change kind, source) that map to the parameters. However, it does not explain parameter meanings or formats beyond what's already in the schema, leaving some parameters like 'source' and 'endpoint' without additional semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a structured, filterable query over change history and lists the key filter dimensions (date, endpoint, object type/name, change kind, source). This is a specific verb+resource pairing, though it doesn't explicitly differentiate from the sibling search_changes, which may also query change history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like get_object_history or search_changes. It only implies usage through 'filterable query' but gives no context about which scenarios call for this tool over others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_server_infoA

About this server — running version, its changelog entry, data freshness (latest snapshots and newest detected changes), and how releases work: the snapshot DATABASE is re-released daily as calendar-tagged GitHub releases (e.g. v2026.08.07) when changes are detected, while the SERVER code ships on npm with semver versions (e.g. v0.1.0). Call for "what version is this?", "what's new in the latest Graph Atlas release?", or to check whether the local data is current.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It adds valuable context about release behavior: the database is re-released daily as calendar-tagged GitHub releases, while server code uses semver on npm. This goes beyond a simple label and helps set expectations, though it doesn't explicitly state the tool is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized: it starts with a clear heading phrase, lists content areas, explains release mechanics with examples, and ends with concrete use cases. Every sentence adds value, and the structure is logical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description is complete. It covers what information is available, how releases are versioned, and when to call it. No critical gaps are apparent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is trivially 100%. The description does not need to explain parameters, so the baseline of 4 applies. It correctly focuses on the informational content returned.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly defines the tool as providing server information: running version, changelog entry, data freshness, and release mechanics. It distinguishes from sibling tools by focusing on server-level info rather than schema objects or changes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly lists when to call the tool: 'what version is this?', 'what's new in the latest Graph Atlas release?', or to check data currency. While it doesn't explicitly name alternative tools or exclusions, the usage triggers are clear and sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_snapshot_summaryA

Snapshot metadata — entity/property/enum counts, CSDL size, change count. "How big is Graph API now?" and trend analysis.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoISO date (YYYY-MM-DD); defaults to latest
endpointNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of disclosing behavior. It states that the tool returns metadata counts and size, implying a read-only operation, but it does not explicitly confirm safety, explain response structure, or mention side effects. Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise—two clauses and a use-case question—with no filler. Every sentence adds context, and the structure is easily scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, with no required parameters and no output schema. The description covers the core return values (counts, size, change count) and mentions trend analysis, but lacks details on how to perform trend analysis (e.g., multiple dates) and the default behavior of 'date' is only in the schema. It is minimally viable but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%: the 'date' parameter is described in the schema, but 'endpoint' is not. The tool description adds no parameter information and does not clarify the meaning of 'endpoint' (e.g., which Graph API version). The enum provides allowed values, but semantics are incomplete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool's purpose: providing snapshot metadata with entity/property/enum counts, CSDL size, and change count. It also includes a concrete use case ('How big is Graph API now?'), which distinguishes it from siblings focused on history, changes, or schema graphs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for understanding overall snapshot size and trends. It gives context ('trend analysis') but does not explicitly exclude alternatives or mention when to choose this over related tools like get_recent_changes or schema_change_report. Still, the context is clear enough for a basic decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schema_change_reportA

Structured JSON of a schema/permission/role graph (nodes + edges) with change-activity counts, for reasoning over — no UI. view="entity": Graph entity types (focus_object = an entity like "group"). view="permission": permission scopes and the entities they touch (focus_object = a permission like "User.Invite.All"). view="role": Entra roles, the permissions they grant, and the entities those touch (focus_object = a role like "User Administrator") — use this to compare what different roles can actually do. Omit focus_object for an overview of the most consequential entities/permissions/roles. Same data as visualize_schema_graph, without rendering it.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoentity
limitNo
sinceNoISO date for the change-activity window; defaults to 30 days ago
endpointNoOnly applies to view=entityv1.0
object_nameNoFocus node — an entity type, permission name, or role name depending on view

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden. It discloses that the tool returns structured JSON (no UI), describes the three view modes, and notes that the endpoint parameter only applies to view=entity. However, it does not explicitly state whether this is a read-only operation or what side effects (if any) might occur, leaving some ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but each sentence adds value: it starts with a clear summary, then details each view and the relationship to visualize_schema_graph. It could be slightly better formatted but remains within a reasonable length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description gives a high-level view of the output (nodes+edges+change counts) and explains the main parameters. However, without an output schema, it doesn't fully specify the return structure, and details like limit semantics and change-activity count definitions are absent. Still, the 'same data as visualize_schema_graph' reference provides useful context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description enriches parameter meaning beyond the schema by explaining how view and object_name interact: view=entity focuses on an entity, view=permission on permission scopes, and view=role for comparing roles. It also clarifies that omitting focus_object yields an overview and that endpoint only applies to entity view, which the schema doesn't convey. The limit and since parameters remain largely described by the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool outputs a structured JSON graph with change-activity counts and explicitly differentiates from visualize_schema_graph by noting it provides the same data without rendering. It also defines three views and focus_object semantics, making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit guidance for each view: use role view to compare role capabilities, and suggests omitting focus_object for an overview. It also notes the difference from visualize_schema_graph, implying when to choose this tool over the visualization sibling, though it doesn't mention other change-related alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_changesA

Search Microsoft Graph API change history using natural-language or keyword queries across all sources (seed-entra-ms, backfill-graph-changelog, self). Hybrid BM25-style keyword + semantic search, fused via Reciprocal Rank Fusion; degrades to keyword-only without OPENAI_API_KEY configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoSearch mode — hybrid degrades to keyword automatically without an OpenAI keyhybrid
limitNoMax results (default 10, max 50)
queryYesNatural-language or keyword query, e.g. "groups API nesting", "ID Governance separation of duties"
endpointNoFilter to a specific Graph endpoint

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden. It reveals the hybrid algorithm (BM25 + semantic, Reciprocal Rank Fusion) and the fallback behavior when OPENAI_API_KEY is missing. It also identifies the data sources searched. This goes beyond a generic 'search' claim, though it doesn't detail return structure or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence that gets straight to the point. It covers purpose, scope, search mechanism, and a conditional dependency without wasted words. Every clause contributes meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides sufficient context for a search tool: it names the sources, explains the hybrid mode, and notes the fallback. With no output schema, it doesn't describe result format, but that is not critical for a search invocation. It lacks explicit guidance on when to use alternative search tools, but overall it is complete for most use cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description itself does not add parameter-level detail beyond the schema; it mentions natural-language/keyword queries and mode degradation, which are already present in the schema descriptions for 'query' and 'mode'. No additional meaning is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Search'), the resource ('Microsoft Graph API change history'), and the scope ('across all sources (seed-entra-ms, backfill-graph-changelog, self)'). This distinguishes it from sibling tools like search_schema_objects and get_recent_changes, which serve different purposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage ('Search Microsoft Graph API change history') but does not explicitly state when to prefer this tool over alternatives or provide exclusions. For example, it doesn't mention that search_schema_objects is for schema objects or get_change_detail for specific change details. However, the context is clear enough for an agent to infer common use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_schema_objectsA

Name search across Graph entity types, permission scopes, and Entra roles — resolves fuzzy names to canonical node ids for visualize_schema_graph / expand_schema_node. Returns ranked candidates {id, kind, label, sub}; prefix matches rank first.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindsNoRestrict to these kinds; default all
limitNo
queryYes
endpointNoSnapshot used for entity type namesv1.0

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It discloses ranking behavior ('prefix matches rank first'), return structure ('ranked candidates {id, kind, label, sub}'), and fuzzy matching. This is meaningful behavioral context. However, it does not mention edge cases like no results or query length constraints, so it is not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, then return behavior. Every phrase adds value (scope, downstream usage, output shape, ranking). No filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with 4 params and no output schema, the description explains the purpose, the kinds searched, the return format, ranking order, and downstream consumers. It is missing explicit guidance on limit and endpoint semantics, but those are partially covered by schema. Overall it provides enough context for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50% (kinds and endpoint have descriptions; query and limit do not). The description adds meaning for query ('fuzzy names') and kinds ('Graph entity types, permission scopes, and Entra roles'), but it does not clarify limit or endpoint beyond schema defaults. It partially compensates for the gap but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is very specific: 'Name search across Graph entity types, permission scopes, and Entra roles' names the verb, resources, and scope. It also states the outcome ('resolves fuzzy names to canonical node ids') and explicitly references sibling tools visualize_schema_graph / expand_schema_node, which clearly differentiates it from other search tools like search_changes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states the downstream use case ('for visualize_schema_graph / expand_schema_node'), telling the agent when to invoke this tool. It implies an alternative (for changing data, use search_changes or get_recent_changes), but it does not explicitly list when not to use it or name alternative tools. Clear context but not a full exclusionary set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

visualize_schema_graphA

Open the interactive Graph Atlas visualizer — a force-directed schema graph the user can search, expand node-by-node, and pivot across views. Pick the view that puts the pivot object in the right place for the question: "entity" for the Graph schema (nodes = entity types, colored by distance from the focus, with recent-change activity badges; edges = navigation properties/inheritance) — focus_object = an entity like "group". "permission" for a permission scope and the entities it touches plus the roles granting it — focus_object = a permission like "User.Invite.All". "role" for an Entra role, the permissions it grants, and the entities those touch — focus_object = a role like "User Administrator". Omit focus_object for an overview of the most consequential nodes. The user can continue exploring in the UI (expand_schema_node powers that); use schema_change_report for the same data without rendering.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoentity
sinceNoChange-activity window — ISO date or day count (e.g. "30"); defaults to 30 days ago
endpointNoOnly applies to view=entityv1.0
focus_objectNoFocus node — an entity type, permission name, or role name depending on view

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It thoroughly discloses the tool's interactive UI behavior, the semantics of nodes and edges (e.g., 'nodes = entity types, colored by distance from the focus, with recent-change activity badges'), and the fact that the user can continue exploring in the UI. It also clarifies the alternative schema_change_report does the same data without rendering, adding behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized for its complexity. It starts with the main purpose, then systematically explains each view, and ends with alternatives—every sentence contributes necessary information without redundancy or fluff. The structure is logical and easy to follow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite lacking annotations and an output schema, the description is remarkably complete. It covers the tool's purpose, all configurable aspects (view, focus_object), interaction model, and relationships to sibling tools. It even explains the visual details (color-by-distance, badges) and the non-rendered alternative, giving the agent enough context to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema includes descriptions for since, endpoint, and focus_object, the 'view' parameter has no schema description, and the description fills this gap with detailed semantic guidance. It maps each view to specific focus_object types, provides real-world examples, and explains the default when focus_object is omitted. This significantly exceeds what the schema offers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool opens the Graph Atlas visualizer, a force-directed schema graph, and distinguishes it from schema_change_report ('use schema_change_report for the same data without rendering'). It uses specific verbs ('Open', 'visualizer') and specifies the resource, making its purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance for each view ('entity', 'permission', 'role') with concrete examples of focus_object values (e.g., 'group', 'User.Invite.All'). It also instructs when to omit focus_object ('Omit focus_object for an overview') and names alternatives (expand_schema_node, schema_change_report), giving clear context for choosing this tool versus siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.3
    • Changedexpand_schema_node1 field changed
      • changedInput schema / properties / node_id / description
        Previous value: -"Node id — lowercase entity type, permission name, or role name"New value: +"Node id — a lowercase entity type, or a permission or role name (casing ignored)"
  2. 1 tool updatev0.1.1
    • Addedget_server_info
  3. 11 tool updatesv0.1.0
    • First observedexpand_schema_node
    • First observedget_change_detail
    • First observedget_node_timeline
    • First observedget_object_history
    • First observedget_permission_context
    • First observedget_recent_changes
    • First observedget_snapshot_summary
    • First observedschema_change_report
    • First observedsearch_changes
    • First observedsearch_schema_objects
    • First observedvisualize_schema_graph

TDQS

A3.8/5.0

Scored across 12 tools

Disambiguation3/5

Several tools have overlapping surfaces: search_changes, get_recent_changes, get_object_history, and get_node_timeline all return change-related data, and schema_change_report, visualize_schema_graph, and expand_schema_node all expose schema graph views. Descriptions are detailed enough to usually disambiguate, but an agent could struggle to choose between get_permission_context and the permission/role views of schema_change_report or expand_schema_node.

Naming Consistency4/5

Most tools follow a clear get_/search_/visualize_/expand_ pattern: get_recent_changes, get_object_history, search_schema_objects, etc. The outlier is schema_change_report, which uses a noun-noun form and doesn't fit the verb-prefix convention. Overall the naming is predictable and readable, with only minor deviation.

Tool Count5/5

12 tools is well within the ideal range for a specialized server. Each tool serves a distinct role in the workflow—searching, querying, drilling down, visualizing, and schema exploration—without feeling padded or redundant.

Completeness5/5

The tool surface covers the full journey from natural-language discovery through structured filters, object history, permission context, snapshot metadata, schema graph exploration/reporting, and visual interaction. No obvious dead ends: search_results can lead to detail tools, schema searches feed visualization/expansion, and server freshness is checkable. The domain appears fully covered for a read-only Graph API atlas.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol server for Microsoft 365 administration using Graph API application permissions, enabling security monitoring, identity audits, incident response, and service health management.
    85 npm
    12
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    A FastMCP server for interacting with Microsoft Entra ID via the Microsoft Graph API, enabling management of users, groups, sign-in logs, MFA, applications, devices, conditional access, and more.
    48
    MIT