Skip to main content
Glama

ms-graph-mcp

A Model Context Protocol server that gives an AI assistant access to your own Microsoft 365 data — Outlook mail and calendar, OneDrive, SharePoint, To Do, Planner, Teams chat, Entra ID and Intune — through the Microsoft Graph API. It runs locally over stdio, signs in as you with delegated permissions, and stores its token cache encrypted on your machine.

Not affiliated with Microsoft. This is an independent community project. Microsoft, Microsoft 365, Microsoft Graph, Outlook, OneDrive, SharePoint, Teams, Entra and Intune are trademarks of the Microsoft group of companies, used here only to describe what this software connects to.

Why an MCP server

Microsoft Graph is an ordinary HTTP API. Everything this server does could, in principle, be a curl command or a fifty-line script, and for a question you ask once it should be. This project exists for the other case: an assistant that reaches the same API many times a day, on your behalf, without being handed your credentials and without being told how Graph works on every turn.

Five things move from the conversation into the server.

The assistant never handles your token

For a model to call Graph directly, an access token has to reach the model — pasted into the conversation, returned by a shell command, or read out of a file the model can open. Once it is there it is in the transcript, in the context window, and in whatever logs that client keeps. Access tokens are bearer credentials: anyone holding one is you, for an hour, to the full extent of the scopes it carries.

Here the token never leaves the server process. The model sees tool names, JSON Schemas and results; the refresh token sits encrypted on disk and the access token exists only inside a request the model cannot observe. That boundary is the reason getToken refuses to become interactive mid-request, and the reason no tool returns a @microsoft.graph.downloadUrl — a pre-authenticated link that would hand file contents to anyone who read the transcript.

Graph's sharp edges are encoded once, in the tool descriptions

Graph is not uniform, and its inconsistencies are the kind a model rediscovers by getting them wrong. A few that this server already knows about, each of which cost a real debugging session to establish:

  • GET /chats/{id}/messages does not support $select. You cannot ask Graph for fewer fields; you get the whole chatMessage and trim it yourself.

  • On that same endpoint $filter is silently ignored unless $orderby names the same property. Not rejected — ignored. A date-bounded query returns the wrong window and no error, which is why chat_fetch_history pins the ordering rather than exposing it.

  • Channel messages are narrower still: no $filter, no $orderby, and an order derived from the reply chain rather than creation time. A date window there cannot be a server-side query or an early stop, so teams_fetch_channel_history filters while paging and tells you the window may be incomplete.

  • Page size caps at 50, and Teams allows roughly one request per second per chat or channel. A naive loop over a long history is throttled; the paginator paces itself.

  • Planner rejects every update and delete without an If-Match etag from a prior read.

  • Outlook $search takes a quoted term and supports no date range at all; a date-bounded mail query has to use $filter.

  • Directory queries using $count or $search need a ConsistencyLevel: eventual header that nothing in the URL suggests.

A model driving curl relearns these from error responses, or worse, from a 200 that quietly returned the wrong rows. Written into a tool description once, they are in front of the model before it makes the call.

Responses are projected down to something a model can read

A single chatMessage carries an HTML body, reactions, mentions, attachments and hosted-content references. Fifty of them is far more than a useful answer needs and more than many clients will accept — Claude Code truncates tool output near 25,000 tokens. Raw Graph responses spend that budget on markup.

Every tool here returns a projection instead: for a message, the sender, the timestamp, the body stripped of HTML and truncated to a caller-controlled budget, and a count of attachments. Long results carry a nextLink cursor so the model can continue deliberately rather than by re-requesting and hoping.

Guardrails a script does not have

  • Host pinning. graph_request lets the model choose a path, and every request carries your bearer token, so a path that escapes the Graph host leaks that token. Three checks sit between the two: the path is validated, the URL is built through the URL API rather than by concatenation, and the resulting host is compared against the pinned Graph hostname. The same check runs on every @odata.nextLink before it is followed, because a paging link comes from a server response rather than from you. This is not hypothetical: a comparable Graph MCP server shipped a string-concatenated path that allowed an @attacker.com host escape.

  • Read-only mode. --read-only removes write tools from the catalogue entirely, so a client never sees them.

  • Least-privilege consent. The scopes requested at sign-in are derived from the enabled groups and the tools inside them, so --groups mail --read-only asks for Mail.Read and nothing else.

  • Retry and backoff. 429 and 503 are retried with Retry-After honoured; a mutating request is replayed only when Graph said it did not process it.

One server, many clients

The same process serves Claude Code, Claude Desktop, VS Code and any other MCP client, over both the 2026-07-28 revision and the 2025-11-25 one, from a single factory. A shell script is bound to the one place it runs.

When you do not need this

If you want one answer once, use curl. If you are writing a program that talks to Graph, use the Microsoft Graph SDK — this is not a client library, and graph_request is a deliberate escape hatch rather than a general interface. The server earns its keep when the caller is a model, the access is ongoing, and the credential must not be in the conversation.

Worth being plain about the split: rather more than half of the code here is not MCP at all. It is the part that calls Graph correctly — retries, batching, pagination, path validation, scope derivation — and you would need it whatever the caller was. MCP is the thin, typed surface over the top that lets a model use it safely.

Related MCP server: Microsoft Graph MCP

Quick start

You need Node.js 20 or later. Sign in once, in a terminal:

npx ms-graph-mcp login

There is no application to register first: the server signs in with a shared multi-tenant Entra application published by this project. See Which application am I signing in to for what that means for you and for your tenant.

The shared registration is not published yet. The constant it will occupy, SHIPPED_CLIENT_ID in src/config.ts, is still empty, so this build has no default application to fall back on. login says so and stops before it contacts Entra, and status prints the same registration walkthrough. Until the real ID ships, register an application of your own — or use one your organisation already has — and name it on each command:

npx ms-graph-mcp login --client-id <your-client-id>

Register your own Entra application has the steps. When the shared ID lands, nothing else in this README changes: --client-id keeps working and keeps taking precedence over the shipped default.

Either way, your system browser opens on the Microsoft sign-in page. Pick the account you want the server to act as, approve the permissions it asks for, and the tab reports that sign-in is complete. Back in the terminal, the command has caught the redirect, exchanged it for tokens, and written the refresh token to an encrypted cache under your config directory.

On a machine with no browser to open — an SSH session, a container, a headless server — ask for the device code flow instead:

npx ms-graph-mcp login --auth-flow device

That prints a short code and a URL to open on any other device. Enter the code there and the terminal finishes on its own. The default, --auth-flow auto, already falls back to this when the browser cannot be opened; passing device explicitly skips the attempt that would fail. Both are OAuth 2.0 sign-ins and both end with the same delegated token — see How sign-in works.

Either way, check it worked:

npx ms-graph-mcp status

status prints the application ID in use and where it came from, the account it resolved, and the scopes this configuration will request. Then point an MCP client at the server.

As a Claude Code plugin

The plugin wires the server into Claude Code and asks you for its settings, so there is no MCP config to edit and nothing to export in a shell profile.

/plugin marketplace add devyhan/ms-graph-mcp
/plugin install ms-graph-mcp@devyhan

Claude Code prompts for four settings when the plugin is enabled, and fills in sensible values for three of them:

Setting

Default

What it does

Application (client) ID

none, and required

The Entra application to sign in with. The dialog will not accept an empty value, because there is nothing to fall back on.

Directory (tenant) ID

common

Suits most work and school accounts. Use consumers for a personal Microsoft account.

Tool groups

the personal set

Profile, mail, calendar, files, To Do, contacts and search. A shorter list means a smaller consent prompt.

Read-only

on

Hides every tool that writes and drops the write scopes from the consent request. Turn it off when you want the server to act, not just read.

Read-only defaults to on here, and to off on the command line. The plugin is the path someone takes without reading this file first, and an assistant that can send mail and delete files on a fresh install is the wrong first state; on the command line the choice is already explicit.

You can change any of them later from /config.

You still need your own Entra application — see Register your own Entra application — because this project publishes no shared one. Paste its Application (client) ID into the first prompt.

Sign-in remains a terminal step, once:

npx ms-graph-mcp login

The server will not open a browser from inside a Claude Code session. The MCP transport owns stdout, and a sign-in prompt in the middle of a tool call would corrupt the JSON-RPC stream, so it returns an error telling you to run login instead. See How sign-in works.

Everything works before you configure anything: the server starts, lists its tools, and status explains what is missing. An installed-but-unconfigured plugin shows a working server rather than a broken one.

If a setting does not take effect, run npx ms-graph-mcp status and read the Client ID from: line — it names which source won. Should a value arrive as the literal text ${user_config.client_id}, the placeholder was never substituted; the server refuses it and says so rather than passing it to Entra, where it would fail much later and blame something else.

Without the plugin

Every setting is also an MS365_MCP_* environment variable, which is what the plugin sets under the hood, and every one has a command-line flag — see Commands and flags. Use these when you run the server directly:

export MS365_MCP_CLIENT_ID="<your application (client) ID>"
export MS365_MCP_TENANT_ID="<your tenant ID>"
export MS365_MCP_GROUPS="mail,calendar,files"
export MS365_MCP_READ_ONLY=1

A client launched from a desktop icon rather than a terminal does not read your shell profile, so a variable exported there will not reach it. That is the failure the plugin's prompts exist to avoid; if you are configuring by hand, prefer the flags.

Claude Code

claude mcp add microsoft-graph -- npx -y ms-graph-mcp --preset work

Or add it to .mcp.json in the project root:

{
  "mcpServers": {
    "microsoft-graph": {
      "command": "npx",
      "args": ["-y", "ms-graph-mcp", "--preset", "work"]
    }
  }
}

Claude Desktop

Edit claude_desktop_config.json (Settings > Developer > Edit Config):

{
  "mcpServers": {
    "microsoft-graph": {
      "command": "npx",
      "args": ["-y", "ms-graph-mcp", "--preset", "work"]
    }
  }
}

VS Code

Add .vscode/mcp.json to the workspace:

{
  "servers": {
    "microsoft-graph": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "ms-graph-mcp", "--preset", "work"]
    }
  }
}

While the shared registration is unpublished, give each of these your own application ID as well: add "env": { "MS365_MCP_CLIENT_ID": "<your-client-id>" } beside args, or append "--client-id", "<your-client-id>" to args.

The server starts whether or not an application is configured. With none it writes a warning to stderr, lists its tools as normal, and fails every Graph call until you sign in.

Which application am I signing in to

A shared application published by this project. Unless you override it, the client ID the server presents to Entra is a multi-tenant registration this project publishes — the same one every other user of this package signs in with. The server picks one in this order, and stops at the first that is set:

  1. --client-id <id>

  2. MS365_MCP_CLIENT_ID

  3. the application shipped with the package

  4. nothing, in which case sign-in refuses to start and prints the registration steps

status reports which of the four it landed on, and login names the authority and the application on stderr before it opens the browser, so you can see whose application you are about to consent to while you can still stop. Shipping an application ID is the model Lokka and the Softeria MS-365 MCP server use, and it exists for one reason: registering an application is the step most people never get past.

First use in an organisation creates an enterprise application in that tenant. The first time anyone in a tenant consents to a multi-tenant app, Entra creates a service principal for it in that directory — an entry under Enterprise applications carrying this project's application name. Administrators can see it there, review the delegated permissions it has been granted, and disable or block it. From then on every request the server makes is attributed to that application, alongside your user, in the tenant's sign-in and Graph activity logs. This is a consequence of signing in with a shared application, not a footnote: if your organisation would object to an unfamiliar third-party application appearing in its directory, register your own before the first sign-in.

The application holds no secret and no data. It is a public client: there is no client secret anywhere in this package, and there could not be one, because a secret shipped to every user is not a secret. Every token Entra issues is issued to the signed-in user, is scoped to what that user can already reach, and is cached encrypted on that user's own machine (see Security). No server of ours sits between you and Microsoft, and neither the package nor the owner of the registration ever receives your tokens, mail, files or directory records. What the owner of a registration does control is the registration object itself, which is what the next two paragraphs are about.

Using your own registration instead. Pass --client-id (or set MS365_MCP_CLIENT_ID) and follow Register your own Entra application. Reasons to do it:

  • An enterprise policy that permits only applications registered in its own tenant, or that requires an internal owner and a review for every enterprise application.

  • A sovereign cloud. The shared registration exists in the global cloud only, so the server refuses to offer it to --cloud usgov, usgovdod or china and says why, rather than letting you discover it after typing your password. Register an application in that cloud and name it with --client-id.

  • A tenant that has blocked the shared application, or an administrator who will grant consent only to something they own.

If the shared registration is ever deleted or blocked, sign-in starts failing with AADSTS700016, AADSTS7000112 or AADSTS700054, and --client-id <your-id> is the entire fix. Nothing else changes: same flows, same scopes, same tool catalogue, same cache location. Run login once after switching, because the cached refresh token belongs to the application that obtained it.

Shipping an application ID removes the registration step. It does not remove the consent step. Entra still asks the signed-in user to approve every delegated scope the server requests, and the tenant's consent policy still decides which of those a user is allowed to approve without an administrator.

Work and school accounts in a default tenant. Under the Microsoft-managed default consent policy that new tenants get, an ordinary user cannot self-consent to Mail.Read, Calendars.Read, Calendars.ReadWrite, Calendars.Read.Shared, Chat.Read, Tasks.Read, Tasks.ReadWrite, Files.Read.All, Sites.Read.All or MailboxSettings.Read, among others — even though Microsoft's permissions reference marks every one of them as not requiring admin consent. That covers most of what the personal and work presets ask for. Sign-in fails at the consent screen, and the server prints which of your requested scopes fall under that policy, however small the request was. An administrator clears it once: Enterprise applications > (the application) > Permissions > Grant admin consent for the shared app, or App registrations > (your app) > API permissions > Grant admin consent for your own.

Personal Microsoft accounts consent for themselves — no administrator, no tenant policy. In exchange, a large part of the catalogue is unavailable to them at any consent level: the Teams chat and channel APIs are documented as not supported for delegated personal-account access, and Planner, SharePoint, the directory tools and Intune do not exist for a personal account at all. Use a narrow group set, and sign in against the personal-account authority with --tenant-id consumers; a refresh token issued through the common authority is rejected at its first refresh.

Ask for less, then widen. The scopes requested at sign-in are derived from the enabled groups, so start narrow and add:

npx ms-graph-mcp login --groups me,mail
npx ms-graph-mcp login --groups me,mail,calendar,files

Entra prompts again only for what you added; what was already granted stays granted. --read-only drops every write scope from the request. npx ms-graph-mcp permissions --preset work prints the exact scope list for a configuration, formatted for pasting into an admin consent request.

Register your own Entra application

Once the shared registration ships, most users can skip this section. It remains the supported fallback for the reasons listed in Which application am I signing in to, and until then it is the only way to sign in.

  1. Open the Microsoft Entra admin center and go to Applications > App registrations > New registration.

  2. Give it a name. Under Supported account types, pick the audience you need. A personal Microsoft account (outlook.com, hotmail.com) requires "Accounts in any organizational directory and personal Microsoft accounts"; a work or school account used only in its own tenant needs nothing more than the single-tenant option.

  3. Leave the redirect URI empty for now and click Register. Copy the Application (client) ID from the Overview page — that is the value for --client-id.

  4. Go to Authentication > Add a platform > Mobile and desktop applications and tick the redirect URI http://localhost. The browser flow, which is the default, redirects the finished sign-in there — to a listener on 127.0.0.1 — and fails without it.

  5. On the same page, scroll to Advanced settings and set Allow public client flows to Yes. Neither sign-in flow works without it.

  6. Optionally, under API permissions, add the delegated Microsoft Graph permissions for the tool groups you plan to enable (see the table below). This is not required for user-consentable scopes — you will be prompted to consent at first sign-in — but it is required for the admin-consent groups, and for anything the tenant's consent policy withholds from ordinary users, where an administrator must click Grant admin consent.

http://localhost is a wildcard: Entra accepts a redirect back to it on whatever port the machine happened to be listening on. Some tenants have policies that reject it and require an exact port. In that case register http://localhost:53682 (any free port will do) instead, and start the server with --auth-port 53682 so it binds the port the registration names.

No client secret is needed, and you should not create one. This is a public client running on your machine: it authenticates you interactively and stores a refresh token, and a secret shipped alongside it would not be a secret.

A personal Microsoft account also needs --tenant-id consumers at sign-in, whatever the registration looks like.

Registering a multi-tenant application

Step 2 above is enough for a registration you alone use. An organisation cloning this project's setup — one registration, many users, more than one tenant — needs the same shape the shared application has:

Manifest property

Value

Why

signInAudience

AzureADMultipleOrgs, or AzureADandPersonalMicrosoftAccount to include personal accounts

AzureADMyOrg exists only in the tenant that registered it and returns AADSTS700016 in every other one.

api.requestedAccessTokenVersion

2

Required by any audience that includes personal Microsoft accounts.

isFallbackPublicClient

true, shown as "Allow public client flows: Yes"

Both sign-in flows are public-client flows.

Redirect URI

http://localhost under Mobile and desktop applications

Where the browser flow's authorization code lands.

The ordering gotcha: if you change the audience to one that includes personal accounts while the token version is still 1, the portal rejects the save with "Property api.requestedAccessTokenVersion is invalid". Set api.requestedAccessTokenVersion to 2 in the manifest and save that on its own first, then change signInAudience.

A multi-tenant registration also means the enterprise application described in Which application am I signing in to appears in every tenant whose users sign in, including yours.

How sign-in works

Both sign-in flows are OAuth 2.0, and both end with the same delegated access token. They differ in how you prove who you are, not in what they are.

browser is the authorization code grant with PKCE (RFC 7636). The server binds a one-shot listener on the loopback address, 127.0.0.1, opens the system browser at the Entra authorize endpoint, and Entra sends the finished sign-in back to that listener as a redirect carrying an authorization code. The server exchanges the code, together with the proof key it generated before opening the browser, for tokens. The code is valid only on this machine and only for that one exchange.

device is the device authorization grant (RFC 8628). The server asks Entra for a user code, prints it with a URL, and polls the token endpoint while you enter the code in a browser somewhere else. It is no less an OAuth flow than the browser one; it exists for the case where the machine running the server has no browser it can open, and the sign-in has to happen on a different device.

auto is the default. It tries browser, and when that fails — no desktop session, no way to launch a browser, no loopback port — it writes the reason to stderr and runs device instead. Pass --auth-flow browser when you would rather see that error than a fallback, and --auth-flow device when you never want a browser opened.

Delegated permissions only. The server signs in as you and calls Graph as you. It never authenticates as an application, holds no client secret, and requests no application permissions, so it reaches exactly what your account reaches and nothing more. Every request it makes is attributable to your user in the tenant's sign-in logs.

The session is a refresh token in an encrypted cache. What sign-in leaves behind is the MSAL cache blob, encrypted with AES-256-GCM into token-cache.enc in your config directory (~/.config/microsoft-graph-mcp on macOS and Linux, %APPDATA%\microsoft-graph-mcp on Windows), with the 32-byte key beside it in cache.key at mode 0600. See Security for the details and for --cache-dir.

getToken never prompts. In serve mode the server refreshes access tokens silently and does nothing else. When the refresh token has expired, been revoked, or no longer covers a scope, the tool call returns an error telling you to run login again rather than starting a sign-in. That is deliberate: the MCP transport owns stdout, so a prompt or a browser launched in the middle of a request would corrupt the JSON-RPC stream. Sign-in happens out of band, in a terminal.

This is a local server. It does not implement the MCP authorization specification, and per that specification it should not: the spec covers HTTP transports and directs stdio servers to take credentials from the environment instead. So the server obtains user credentials itself, as an ordinary public OAuth client, and the MCP client is not involved in authentication at all. A remote HTTP mode — where the MCP client performs OAuth against Entra and the server exchanges that token for a Graph token on the user's behalf — is not implemented.

When the browser flow does not work

Nothing opens, or the command sits there. There is no desktop session to open a browser in, which is normal over SSH and inside containers. Use --auth-flow device and sign in from another machine. Under the default auto flow this resolves itself, with a line on stderr saying what failed.

The browser opens but the redirect is rejected (AADSTS50011, redirect URI mismatch). The app registration has no matching redirect URI. Add the Mobile and desktop applications platform with http://localhost, as in step 4 above.

The loopback listener cannot bind. With the default --auth-port 0 the operating system picks a free port, so this only comes up when a port has been pinned and something else already holds it, or when a local firewall blocks the listener. Choose another port with --auth-port <n>. Pin a port deliberately, and register http://localhost:<n> alongside it, when the tenant rejects the bare http://localhost wildcard.

Sign-in errors

Entra reports a failure as an AADSTS code inside the error text. These are the ones that come from the application identity or from consent, rather than from the browser leg.

Code

What it means

What fixes it

AADSTS700016

The application exists, but not in the tenant you signed in to. A single-tenant registration returns this to every tenant except its own; so does one the tenant has blocked, or whose enterprise application an administrator deleted.

Sign in to the tenant that owns the registration (--tenant-id <tenant-id>), or use a multi-tenant registration. For the shared application, --client-id with your own is the fallback.

AADSTS700038

Entra did not accept the value as an application identifier at all. A mistyped GUID, or one that was never registered.

Check what status prints against the Application (client) ID on the registration's Overview page, and correct --client-id or MS365_MCP_CLIENT_ID.

AADSTS50020

The account comes from a different identity provider than the application accepts: a personal Microsoft account at a work-only application, or the reverse.

--tenant-id consumers for a personal Microsoft account; otherwise sign in with a work or school account. The server names the --tenant-id the failed run used.

AADSTS9002332

The application accepts Microsoft Entra work or school users only, and you signed in with a personal Microsoft account.

Sign in with a work or school account, or pass --client-id for a registration whose audience includes personal accounts and add --tenant-id consumers.

AADSTS7000112, AADSTS700054

The application is disabled in that tenant — its enterprise application was disabled, or the service principal was blocked from sign-in.

Ask an administrator to re-enable it under Enterprise applications > Properties > "Enabled for users to sign-in", or pass --client-id with your own registration.

AADSTS65004

The consent screen was declined. Nothing was granted and no session was created.

Ask for less: a narrower --groups, or --read-only to drop the write scopes.

AADSTS90093

The requested permissions need an administrator, and the signed-in user is not allowed to grant them.

Drop the admin-consent groups (do not pass --org-mode) and narrow --groups, or have an administrator grant consent once, as in Consent.

The server sorts these into three kinds, and only one of them falls back.

Application rejections — the first five rows — are reported as Sign-in failed (<code>), followed by the likely cause, the flag that fixes it, and the first line of what Entra actually said. auto does not retry them on the device code path: an application that is absent, disabled, or wrong for your account type is exactly as absent on another device. The MSAL stack goes to stderr separately, prefixed [auth].

Consent decisions — the last two rows, plus AADSTS65001 and AADSTS900941 — print Sign-in was refused at the consent screen, the number of scopes requested, and the subset of them the default tenant consent policy withholds from ordinary users. auto does not fall back here either, because the device code flow shows the same consent screen and would be refused the same way.

Browser failures are everything else. Under auto the server writes Browser sign-in failed: ... to stderr and continues on the device code path. Under --auth-flow browser it stops and prints the three usual causes: no desktop session, a loopback redirect that could not be served, and a registration with no matching redirect URI.

Tools

101 tools across 14 groups. --read-only removes every write tool, leaving 64. The reference for each group is below; the descriptions here are the first line of what the model itself is shown.

Tool groups

Tools are grouped by product area. Enable only the groups you need — the scopes requested at sign-in are derived from the enabled groups, so a narrower selection means a narrower consent prompt.

Group

Product

Delegated scopes

Admin consent

Tools

me

Entra ID profile, Outlook mailbox settings

User.Read, MailboxSettings.Read

No

2

mail

Outlook mail

Mail.Read, Mail.ReadWrite, Mail.Send

No

12

calendar

Outlook calendar

Calendars.Read, Calendars.Read.Shared, Calendars.ReadWrite

No

9

files

OneDrive

Files.Read, Files.Read.All, Files.ReadWrite

No

10

todo

Microsoft To Do

Tasks.Read, Tasks.ReadWrite

No

8

planner

Microsoft Planner

Tasks.Read, Tasks.ReadWrite

No

9

contacts

Outlook contacts

Contacts.Read, Contacts.ReadWrite

No

6

chat

Teams one-to-one and group chats

Chat.Read, Chat.ReadWrite

No

6

sharepoint

SharePoint sites, libraries, lists

Sites.Read.All, Sites.ReadWrite.All

No

11

search

Microsoft Search across mail, files, sites

Mail.Read, Files.Read, Sites.Read.All, Calendars.Read, Chat.Read

No

1

teams

Teams teams, channels, channel messages

Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All, ChannelMessage.Send, TeamMember.Read.All

Yes

9

directory

Entra ID user and group lookups

User.Read.All, Group.Read.All

Yes

9

intune

Intune managed device inventory

DeviceManagementManagedDevices.Read.All

Yes

6

generic

Any Graph endpoint, plus introspection

reuses the union of the above

No

3

offline_access and User.Read are always requested: the first keeps refresh tokens working, the second identifies the account.

The three groups marked Yes request scopes that no ordinary user can consent to, so they stay disabled unless you pass --org-mode. Enabling them in a tenant where an administrator has not granted consent means sign-in fails outright, not that those tools quietly return errors.

The Admin consent column is Microsoft's own classification of each permission. A tenant's consent policy is a second, separate gate, and it withholds more than this column shows — Mail.Read and Calendars.Read among them. See Consent.

The generic group is always on and cannot be selected or removed. It holds graph_request (the escape hatch for endpoints no other tool covers), graph_schema (fetches one item from a path and reports its property names and types), and graph_list_permissions (reports the enabled groups, their scopes, and the signed-in account).

Tool reference

Tool

What it does

Arguments

me_get_profile

Returns the signed-in user's own Entra ID profile from /me: by default id, displayName, mail, userPrincipalName, jobTitle, officeLocation and preferredLanguage.

select

me_get_mailbox_settings

Returns the signed-in user's Outlook mailbox configuration: time zone, date and time format, locale, working hours, and the automatic-reply (out-of-office) setting.

replyBodyChars

Bodies are the expensive part of a mailbox, so list calls return bodyPreview only and mail_get_message fetches one message in full, HTML stripped to text by default.

Tool

What it does

Arguments

mail_list_messages

Lists Outlook messages newest-first, 10 per call by default (50 max), as a compact projection: id, subject, from, toRecipients, receivedDateTime, isRead, hasAttachments, bodyPreview and webLink.

folderId, top, skip, filter, orderby, select, unreadOnly

mail_search_messages

Finds messages by text, returning the same compact projection as mail_list_messages, 10 per call by default (50 max).

query, top, from, to, after, before, hasAttachments

mail_get_message

Returns one message with its body plus sender, recipients, timestamps, importance, conversationId and webLink.

id, format, maxBodyChars

mail_list_folders

Lists the top-level Outlook mail folders with their ids, unread counts and total counts, 50 per call by default.

top, includeChildren

mail_list_attachments

Lists attachment metadata for one message — id, name, contentType, size in bytes, whether it is inline, and its kind (file, item, or reference) — 20 per call by default.

id, top

mail_send

write

Sends a message immediately from the signed-in mailbox — there is no undo and no confirmation step, so confirm the recipients and text with the user first.

to, subject, body, cc, bcc, contentType, saveToSentItems

mail_create_draft

write

Creates an unsent draft in the Drafts folder and returns its id and webLink.

to, subject, body, cc, bcc, contentType

mail_reply

write

Sends a reply to an existing message immediately — it does not create a draft, and there is no undo, so confirm the text with the user first.

id, comment, replyAll

mail_forward

write

Forwards an existing message immediately, attachments included — it does not create a draft and there is no undo, so confirm the recipients with the user first.

id, to, comment

mail_move_message

write

Moves a message to another mail folder.

id, destinationId

mail_mark_read

write

Sets the read flag on one message.

id, isRead

mail_delete_message

write

Deletes a message.

id

calendar_list_events switches to /me/calendarView when you give it a date range, which is the only form that expands recurring series. calendar_get_schedule and calendar_find_meeting_times are POSTs that read rather than write.

Tool

What it does

Arguments

calendar_list_events

Lists events with subject, start, end, location, organizer and attendee count, plus a nextLink when more pages exist.

start, end, calendarId, top, select, orderby, timeZone

calendar_get_event

Returns one event in full: subject, start, end, location, organizer, the attendee list with each response, the description body (HTML converted to text and capped), recurrence summary, and the Outlook web link.

id, timeZone

calendar_list_calendars

Lists the signed-in user's calendars with id, name, colour, owner and whether they can be edited or shared.

top

calendar_get_schedule

Returns free/busy availability for up to 20 people or rooms over a time window, as an availabilityView string where each character covers one interval (0 free, 1 tentative, 2 busy, 3 out of office, 4 working elsewhere), plus working hours and any visible busy blocks.

schedules, start, end, availabilityViewInterval, timeZone

calendar_find_meeting_times

Suggests meeting slots that work for the signed-in user and the given attendees, ranked by confidence, with the attendees who are unavailable in each slot.

attendees, durationMinutes, start, end, maxCandidates, timeZone

calendar_create_event

write

Creates an event on the primary calendar and returns the created event.

subject, start, end, timeZone, attendees, body, bodyType, location, isAllDay, isOnlineMeeting

calendar_update_event

write

Patches the given fields on an event and returns the updated event; omitted fields are left alone.

id, subject, start, end, timeZone, attendees, body, bodyType, location, isAllDay, isOnlineMeeting, showAs, categories, reminderMinutesBeforeStart

calendar_delete_event

write

Deletes an event, moving it to Deleted Items.

id

calendar_respond_event

write

Accepts, declines, or tentatively accepts a meeting invitation, optionally with a comment to the organizer.

id, response, comment, sendResponse

Path-addressed calls encode each segment separately, so spaces and & in filenames work. files_read_text refuses binary types by extension before downloading, and no tool returns @microsoft.graph.downloadUrl, which is a pre-authenticated link to the file contents.

Tool

What it does

Arguments

files_list_children

Lists the direct children of a folder in the signed-in user's OneDrive, returning id, name, kind (file or folder), size, mime type, child count, last-modified time and webUrl per entry, plus count and nextLink when more pages exist.

itemId, path, top, orderby

files_get_item

Reads the metadata of one OneDrive file or folder: name, kind, size, mime type, created and last-modified times and authors, parent folder path and ids, and webUrl.

itemId, path

files_search

Searches the whole of the signed-in user's OneDrive for free text, matching file names and indexed file contents, and returns the same compact fields as files_list_children plus count and nextLink.

query, top

files_list_recent

Lists files the signed-in user recently opened or edited, most recent first, with count and nextLink.

top

files_list_shared

Lists files and folders other people have shared with the signed-in user, with count and nextLink.

top

files_read_text

Returns the contents of a text-like OneDrive file (plain text, Markdown, CSV, JSON, XML, source code, config) as a string, truncated to maxChars, which defaults to 20000.

itemId, maxChars

files_create_folder

write

Creates a folder in the signed-in user's OneDrive and returns the created item.

name, parentItemId, parentPath

files_upload_text

write

Writes a text file to the given path in the signed-in user's OneDrive and returns the stored item.

path, content

files_delete

write

Deletes a file or folder from the signed-in user's OneDrive.

itemId

files_create_link

write

Creates a sharing link for a OneDrive file or folder and returns its URL, permission type and scope.

itemId, type, scope

Tool

What it does

Arguments

todo_list_lists

Lists the signed-in user's Microsoft To Do lists with their id, display name and well-known name (for example defaultList for the built-in Tasks list).

none

todo_list_tasks

Lists tasks in one To Do list, returning id, title, status, importance, due and reminder times and a short body preview per task, plus count and nextLink when more pages exist.

listId, top, filter, includeCompleted

todo_get_task

Reads one To Do task in full: title, status, importance, reminder state, start/due/completed times, categories and the notes body (truncated).

listId, taskId

todo_create_task

write

Creates a task in a To Do list and returns the created task.

listId, title, body, dueDateTime, reminderDateTime, importance, timeZone

todo_update_task

write

Patches an existing To Do task and returns the updated task.

listId, taskId, title, body, status, importance, dueDateTime, reminderDateTime, clearDueDateTime, clearReminderDateTime, timeZone

todo_complete_task

write

Marks a To Do task completed by patching its status to 'completed', and returns the updated task including the completedDateTime Graph stamps on it.

listId, taskId

todo_delete_task

write

Deletes a To Do task permanently and returns a confirmation.

listId, taskId

todo_create_list

write

Creates a new To Do list and returns its id and display name.

displayName

Planner requires an If-Match etag on every update and delete. The tools fetch the item first and supply the etag themselves.

Tool

What it does

Arguments

planner_list_my_plans

Lists the Planner plans the signed-in user can see, with id, title, owning Microsoft 365 group id and container.

limit

planner_list_my_tasks

Lists Planner tasks assigned to the signed-in user across every plan, with title, planId, bucketId, due date, percentComplete and assignee ids.

limit

planner_get_plan

Returns one Planner plan: id, title, owning Microsoft 365 group id, container and creation time.

planId

planner_list_buckets

Lists the buckets (columns) of a plan with id, name and orderHint.

planId, limit

planner_list_plan_tasks

Lists every task in a plan regardless of assignee, with title, bucketId, due date, percentComplete and assignee ids.

planId, limit

planner_get_task

Returns one Planner task.

taskId, includeDetails

planner_create_task

write

Creates a task in a plan and returns it.

planId, title, bucketId, assigneeIds, dueDateTime, percentComplete, priority

planner_update_task

write

Updates a Planner task and returns it.

taskId, title, bucketId, assigneeIds, dueDateTime, clearDueDateTime, percentComplete, priority

planner_delete_task

write

Permanently deletes a Planner task; there is no recycle bin.

taskId

Tool

What it does

Arguments

contacts_list

Lists personal contacts from the signed-in user's default Outlook Contacts folder, 25 per page by default (max 100).

top, skip, filter, orderby, select

contacts_get

Returns one personal contact by id, with names, company, job title, department, every email address, phone numbers, postal addresses, birthday, categories and timestamps.

id

contacts_search

Full-text search over the default Contacts folder using Outlook $search, returning the same compact rows as contacts_list, 25 per page by default.

query, top, skip

contacts_create

write

Creates a personal contact in the signed-in user's default Contacts folder and returns the stored contact, including the new id.

givenName, surname, emailAddresses, mobilePhone, companyName, jobTitle

contacts_update

write

Updates the given fields of one personal contact and returns the stored result.

id, givenName, surname, displayName, emailAddresses, mobilePhone, companyName, jobTitle

contacts_delete

write

Deletes one personal contact.

id

Graph offers no $select and no date filter on chat messages, so projection happens here and date windows are applied while paging. chat_fetch_history is the one to reach for beyond a single page.

Tool

What it does

Arguments

chat_list_chats

Lists the Teams chats the signed-in user belongs to (one-to-one, group, and meeting chats — never channel conversations, which the teams group covers).

top, filter, expandMembers

chat_get_chat

Returns one Teams chat by id: topic, chatType, created and last-updated timestamps, the Teams deep link, whether the signed-in user has hidden it, how far they have read, and the meeting join URL for a meeting chat.

chatId

chat_list_messages

Reads recent messages from one Teams chat, newest first.

chatId, top, orderby

chat_list_members

Lists everyone in one Teams chat: the per-chat membership id, display name, email, directory user id, and roles (an owner of a group chat has ["owner"]; ordinary members have none).

chatId

chat_send_message

write

Posts a message to a Teams chat as the signed-in user.

chatId, content, contentType

chat_fetch_history

Reads a long run of one Teams chat, newest first, paging automatically so you do not have to follow nextLink yourself.

chatId, since, until, maxMessages, bodyChars, includeSystem, cursor

Tool

What it does

Arguments

sharepoint_search_sites

Searches SharePoint sites and returns id, display name, description and web URL for each match, plus a count and a nextLink when more pages exist.

query, top

sharepoint_get_site

Returns one site: its composite id, display name, description, web URL, hostname and timestamps.

siteId

sharepoint_list_drives

Lists the document libraries (drives) on a site with id, name, description, drive type and web URL, plus a count and a nextLink when more pages exist.

siteId, top

sharepoint_list_drive_items

Lists the children of a document-library folder: name, whether it is a file or a folder, size, child count, MIME type, last modified time and author, and the web URL, plus a count and a nextLink when more pages exist.

siteId, driveId, itemId, folderPath, top

sharepoint_list_lists

Lists the SharePoint lists on a site with id, display name, description, template and web URL, plus a count and a nextLink when more pages exist.

siteId, includeHidden, top

sharepoint_get_list

Returns one list: id, display name, description, template, web URL and timestamps.

siteId, listId, includeColumns

sharepoint_list_list_items

Lists items in a SharePoint list with their column values, plus a count and a nextLink when more pages exist.

siteId, listId, top, filter, fields

sharepoint_get_list_item

Returns one list item with its column values, creator, last editor, timestamps and web URL.

siteId, listId, itemId, fields

sharepoint_create_list_item

write

Creates an item in a SharePoint list and returns its new id, web URL and stored column values.

siteId, listId, fields

sharepoint_update_list_item

write

Updates column values on an existing list item and returns the stored values.

siteId, listId, itemId, fields

sharepoint_delete_list_item

write

Deletes one item from a SharePoint list.

siteId, listId, itemId

Tool

What it does

Arguments

search_query

Runs a relevance-ranked Microsoft Search query across Microsoft 365 and returns a flattened list of hits, each with its rank, a text summary and the resource's id, name or subject, web URL and last-modified time.

query, entityTypes, from, size, fields

Channel messages have an even narrower query surface than chats: no $filter, no $orderby, and an order based on the reply chain rather than creation time. teams_fetch_channel_history filters client-side for that reason and says so.

Tool

What it does

Arguments

teams_list_joined

Lists the Microsoft Teams teams the signed-in user is a member of, returning id, displayName, description, visibility and archived state.

none

teams_list_channels

Lists the channels of one team, returning id, displayName, description, membershipType and webUrl for each.

teamId, membershipType

teams_get_channel

Returns one channel: displayName, description, membershipType, creation time, the channel email address (empty unless the channel has one provisioned) and the deep link webUrl.

teamId, channelId

teams_list_channel_messages

Lists the top-level messages of a channel, newest first, with sender, timestamp, plain-text body (HTML stripped and truncated to bodyChars) and attachment, mention and reaction counts.

teamId, channelId, top, bodyChars

teams_get_channel_message

Returns one channel message in full: sender, timestamps, plain-text body truncated to bodyChars, attachment names, mention text and reaction types.

teamId, channelId, messageId, bodyChars

teams_list_message_replies

Lists the replies to one top-level channel message, newest first, with the same compact projection as teams_list_channel_messages.

teamId, channelId, messageId, top, bodyChars

teams_fetch_channel_history

Walks a channel's message history and returns a bounded page of root messages with sender, creation and modification times, plain-text body (HTML stripped, truncated to bodyChars) and attachment count.

teamId, channelId, since, until, maxMessages, bodyChars, includeReplies, cursor

teams_list_members

Lists the members of a team with displayName, email, the directory userId and their roles ("owner" for owners, empty for ordinary members, "guest" for guests).

teamId, top

teams_send_channel_message

write

Posts a new top-level message to a channel as the signed-in user and returns the created message id, timestamp and deep link.

teamId, channelId, content, contentType, subject, importance

Advanced queries against the directory need the ConsistencyLevel: eventual header; the client sets it automatically when a request uses $count or a directory $search.

Tool

What it does

Arguments

directory_list_users

Lists users in the Microsoft Entra ID tenant, 25 per page by default (max 999).

top, filter, select, orderby, skipToken

directory_search_users

Finds users by name or email address, returning the same compact rows as directory_list_users, 25 per page by default.

query, top, select, skipToken

directory_get_user

Returns one user by object id or userPrincipalName, with names, contact details, job title, department, office, employee id, account state, usage location and on-premises sync fields.

id

directory_get_user_manager

Returns the user's manager as a compact row (id, displayName, userPrincipalName, mail, jobTitle, department).

id

directory_list_direct_reports

Lists the users who report directly to the given user, 25 per page by default (max 999), as compact rows.

id, top, skipToken

directory_list_groups

Lists groups in the Microsoft Entra ID tenant, 25 per page by default (max 999).

top, filter, select, skipToken

directory_get_group

Returns one group by object id, with its description, mail nickname, type flags, visibility, classification, lifecycle dates, dynamic membership rule and on-premises sync fields.

id

directory_list_group_members

Lists the direct members of a group, 25 per page by default (max 999).

id, top, skipToken

directory_list_user_groups

Returns the ids of every group the user belongs to, including memberships inherited through nested groups.

id

Tool

What it does

Arguments

intune_list_managed_devices

Lists Intune-managed devices in the tenant with id, name, operating system and version, compliance state, last sync time, primary user, manufacturer and model, plus count and nextLink when more pages exist.

top, filter, select

intune_get_managed_device

Reads one Intune-managed device in detail: hardware identity, primary user, enrollment and management state, encryption and supervision flags, Exchange access state, storage and memory in GB, and the last sync time.

deviceId

intune_list_device_apps

Lists the applications Intune has detected on one managed device, returning display name, version, size in MB and the tenant-wide deviceCount for each, with count and nextLink.

deviceId, top

intune_list_compliance_policies

Lists the tenant's Intune device compliance policies with id, display name, platform-specific policyType (from the @odata.type discriminator, e.g.

top

intune_get_device_summary

Returns the tenant-wide Intune device counts in one call: total enrolled devices, MDM-enrolled and dual-enrolled counts, a per-operating-system breakdown, and the Exchange access state breakdown.

none

intune_list_noncompliant

Lists managed devices whose compliance state is exactly 'noncompliant', with the usual device fields plus the compliance grace period expiry, count and nextLink.

top

Always enabled and not selectable. graph_request is the escape hatch for endpoints no purpose-built tool covers.

Tool

What it does

Arguments

graph_request

write

Sends an arbitrary request to Microsoft Graph and returns the raw JSON response.

path, method, version, query, body, maxPages

graph_schema

Fetches one item from a Graph path ($top=1) and reports the property names it carries with their JSON types, plus the @odata.context that names the resource type.

entityPath, version

graph_list_permissions

Reports how this server is configured: which tool groups are enabled, the delegated Microsoft Graph scopes each one uses, which of them need a tenant administrator to consent, whether write tools are suppressed, and the signed-in account.

none

Presets

Preset

Groups

personal

me, mail, calendar, files, todo, contacts, search

work

personal plus chat, planner, sharepoint

admin

directory, intune, teams

all

every group

personal is the default when neither --groups nor --preset is given. --groups and --preset can be combined; their union is taken.

Commands and flags

ms-graph-mcp [command] [options]

Command

Effect

serve

Run the MCP server on stdio. The default when no command is given.

login

Sign in and write the token cache. Opens a browser by default; see --auth-flow.

logout

Clear the stored token cache.

status

Print the signed-in account and the resolved configuration.

permissions

Print the delegated scopes this configuration requests, grouped.

Every option has an MS365_MCP_* environment variable fallback; the flag wins. Boolean environment variables accept 1/0, true/false, yes/no, on/off. An unrecognised flag is a hard error rather than a silent no-op.

Flag

Environment variable

Default

Effect

--client-id <id>

MS365_MCP_CLIENT_ID

the shipped application

Entra application (client) ID. Overrides the shipped default, and is required in a build that has none, in a sovereign cloud, or wherever your tenant will not accept the shared app.

--tenant-id <id>

MS365_MCP_TENANT_ID

common

Tenant ID, or common / organizations / consumers. Personal Microsoft accounts need consumers.

--cloud <name>

MS365_MCP_CLOUD

global

Sovereign cloud: global, usgov, usgovdod, china. Anything but global needs --client-id.

--auth-flow <name>

MS365_MCP_AUTH_FLOW

auto

Interactive sign-in flow: auto, browser, device.

--auth-port <n>

MS365_MCP_AUTH_PORT

0

Loopback port for the browser flow's redirect. 0 lets the OS pick.

--groups <a,b,c>

MS365_MCP_GROUPS

see presets

Comma-separated tool groups to enable.

--preset <name>

MS365_MCP_PRESET

personal

Group bundle: personal, work, admin, all.

--read-only

MS365_MCP_READ_ONLY

off

Hide every tool that writes.

--org-mode

MS365_MCP_ORG_MODE

off

Enable the groups whose scopes need tenant admin consent.

--discovery

MS365_MCP_DISCOVERY

off

Expose discover_tools and call_tool instead of every tool.

--beta

MS365_MCP_ALLOW_BETA

off

Allow requests against the Graph beta endpoint.

--allow-generic-write

MS365_MCP_ALLOW_GENERIC_WRITE

off

Let graph_request send POST, PATCH, PUT and DELETE.

--max-output-chars <n>

MS365_MCP_MAX_OUTPUT_CHARS

60000

Truncate serialised tool output beyond this many characters.

--cache-dir <path>

MS365_MCP_CACHE_DIR

OS config directory

Directory holding the token cache.

--verbose, -v

MS365_MCP_VERBOSE

off

Log Graph requests to stderr.

--help, -h

Print help and exit.

--version

Print the package version and exit.

MS365_MCP_AUTH_FLOW=interactive, the undocumented value that used to select the browser flow, is still accepted as an alias for browser.

--discovery is worth knowing about: with every group enabled the server exposes 101 tools, and 101 tool schemas is a large, permanent cost on the first turn of every conversation. In discovery mode the client sees three tools instead — discover_tools searches the catalogue and returns names and descriptions without schemas, call_tool invokes one by name, and graph_list_permissions reports the configuration. The model pays for a tool's schema only when it actually calls it.

Security

Version 1.0 by default. Requests go to the v1.0 Graph endpoint. The beta endpoint is refused unless the server is started with --beta, because beta resources change without notice and without deprecation.

Host pinning on the generic tool. graph_request lets the model choose the request path, and every request this server sends carries your bearer token, so a path that escapes the Graph host leaks that token. Three independent checks stand between the two: the path is validated before use (absolute URLs, URI schemes, .. segments, percent-encoded separators and protocol-relative references are all rejected), the URL is then built through the URL API rather than string concatenation, and the resulting host is compared against the pinned Graph hostname for the selected cloud before the request goes out. The same host check is applied to every @odata.nextLink before it is followed, because a paging link is chosen by the server response rather than by you.

Read-only mode. --read-only removes every write tool from the catalogue, so a client never sees them and cannot call them. graph_request stays available but refuses every method except GET, and call_tool re-checks the target in case a write tool reached it another way.

Generic writes are opt-in separately. Even without --read-only, graph_request refuses POST, PATCH, PUT and DELETE unless --allow-generic-write is passed. A purpose-built tool states in its description exactly what it changes; an arbitrary write to an arbitrary path does not.

Least-privilege groups. The scopes requested at sign-in are derived from the enabled groups and their tools, so enabling --groups mail asks for mail permissions and nothing else. --read-only also drops the write scopes from the consent request, rather than consenting to permissions the server will never exercise. The three admin-consent groups are excluded unless --org-mode is passed, so a personal-account user is never shown a consent prompt they cannot satisfy.

A shared client ID is an identifier, not a credential. The application ID the server ships with is public by construction — it appears in every authorize URL — and it grants nothing on its own. Access still requires an interactive sign-in by a user, consent recorded in that user's tenant, and a refresh token held on that user's machine. What it does mean for a tenant is a service principal visible to its administrators; see Which application am I signing in to.

Where the token cache lives. The MSAL cache blob is encrypted with AES-256-GCM and written to token-cache.enc in your config directory, with the 32-byte key beside it in cache.key. Both files are created with mode 0600 inside a directory with mode 0700.

Platform

Default location

macOS, Linux

$XDG_CONFIG_HOME/microsoft-graph-mcp, or ~/.config/microsoft-graph-mcp

Windows

%APPDATA%\microsoft-graph-mcp

Override with --cache-dir. Run npx ms-graph-mcp status to see the resolved path, and logout to delete both files. Keeping the key next to the ciphertext protects against a stray backup or a file synced to the cloud, not against an attacker who already has read access to your home directory.

No secrets in configuration. The server is a public client and takes no client secret. The only credential it holds is the refresh token in the cache described above.

What this is not

This is a local, delegated-permission MCP server. It acts as you, with the permissions you have, over a stdio transport on your own machine. It is not a replacement for Microsoft's own Agent 365 MCP servers, which are remote, run inside Microsoft's tenant boundary, use application permissions and admin-managed agent identities, and require a Microsoft 365 Copilot licence. If you need agent identity, tenant-wide governance, or auditing that a tenant administrator controls, that is the product to look at.

It is also not a general Microsoft Graph client library. The tools cover the common read and write paths for each product area and project their results down to what a model can usefully read; graph_request exists for everything else, deliberately behind a flag.

Licence

MIT — see LICENSE.

Available Tools

51 tools
calendar_create_eventCreate a calendar eventA

Creates an event on the primary calendar and returns the created event. Listing attendees sends them a meeting invitation immediately, so confirm the details with the user first. A start or end without an explicit UTC offset is treated as local time in timeZone (UTC when that is omitted).

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesISO-8601 end, interpreted the same way as `start`.
bodyNoEvent description shown in the invitation.
startYesISO-8601 start. Without an offset it is read as local time in `timeZone`; with a Z or ±HH:MM offset it is an absolute instant.
subjectYesEvent subject line.
bodyTypeNoHow to interpret `body`. Defaults to 'text'.text
isAllDayNoMake this an all-day event. Graph then requires start and end to be midnight and at least 24h apart.
locationNoFree-text location, e.g. "Room 4B" or "Zurich office".
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.
attendeesNoPeople and rooms to invite. Creating the event sends them an invitation immediately.
isOnlineMeetingNoAttach a Microsoft Teams meeting link.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations, the description discloses critical behavioral details: the side effect of immediately sending invitations to attendees, the return of the created event, and the timezone interpretation for naive start/end values. This is exactly the kind of context an agent needs for a mutating tool.

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?

Three sentences, each earning its place: purpose/return, side-effect warning, and timezone behavior. The most important operational warning is front-loaded after the purpose, and there is no redundant or filler text.

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 10-parameter mutation tool with no output schema and minimal annotations, the description covers the non-obvious essentials: target calendar, return value, immediate invitation side effect, and ambiguous timezone handling. The remaining parameter details are already fully documented in the schema.

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 100%, so the baseline is 3. The description adds one meaningful clarification beyond the schema: when timeZone is omitted, naive times default to UTC. It does not repeat parameter docs, which is appropriate.

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 states a specific verb and resource: 'Creates an event on the primary calendar' and adds that it returns the created event. This clearly distinguishes it from update, delete, respond, and list tools in the sibling set.

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: creating a new calendar event on the primary calendar. It also provides explicit pre-call guidance by warning that attendees will receive invitations immediately and telling the agent to confirm details first. It does not explicitly name alternatives, but the usage context is clear.

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

calendar_delete_eventDelete a calendar eventA
Destructive

Deletes an event, moving it to Deleted Items. If the signed-in user organized a meeting, every attendee is sent a cancellation; if they were only invited, this removes it from their calendar without telling the organizer — use calendar_respond_event with decline for that. Deleting a series master deletes every occurrence.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesEvent id to delete.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true, but the description goes well beyond that. It discloses that the event is moved to Deleted Items, that attendees receive cancellations when the user organized, and that the invitee-only case removes it without notifying the organizer. It also explains series master behavior. This is rich behavioral context that annotations alone do not convey.

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 three sentences, each carrying distinct and essential information: the primary action and its outcome, the attendee vs organizer behavior, and the series master handling. It is front-loaded with the core action and has zero filler, making it efficient for an agent to parse.

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 complexity of the delete operation (different behavior for organizer vs invitee, series handling), the description covers all critical decision points an agent needs to invoke the tool correctly. There is no output schema, but a delete typically returns a standard success/failure, so no return format is necessary. The description is complete for safe and correct usage.

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 schema has a single 'id' parameter with full 100% coverage, and the description references the series master case, which gives additional meaning to that id: it may represent a series master and then all occurrences are deleted. While the description does not explicitly say 'if the id is a series master,' it implies it, adding value beyond the schema's minimal 'Event id to delete.' This warrants a 4 rather than the baseline 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 action: 'Deletes an event, moving it to Deleted Items.' It specifies the resource (calendar event) and the immediate effect. It also distinguishes itself from the sibling calendar_respond_event by explaining the attendee vs organizer scenario, which prevents an agent from confusing the two tools.

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 explicitly states when to use this tool versus the alternative: 'use calendar_respond_event with decline for that.' It also covers the series master case, clarifying that deleting a series master deletes all occurrences. This gives clear usage boundaries and eliminates guesswork about which tool fits the situation.

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

calendar_find_meeting_timesFind meeting timesA
Read-onlyIdempotent

Suggests meeting slots that work for the signed-in user and the given attendees, ranked by confidence, with the attendees who are unavailable in each slot. Returns 10 suggestions by default. Read-only despite being an HTTP POST. All attendees are treated as required, and an empty result comes back with emptySuggestionsReason explaining why (commonly "AttendeesUnavailable" or a window that is too narrow).

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoISO-8601 latest acceptable end. Must be given together with `start`.
startNoISO-8601 earliest acceptable start. Must be given together with `end`; omit both to let Graph pick the window.
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.
attendeesYesSMTP addresses of the required attendees. The signed-in user is the organizer and must not be listed.
maxCandidatesNoMaximum suggestions to return. Defaults to 10.
durationMinutesYesMeeting length in minutes.

TDQS

A4/5.0
Behavior4/5

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

The description adds meaningful behavioral context beyond the annotations: it notes the tool is 'Read-only despite being an HTTP POST' and explains that empty results include an 'emptySuggestionsReason' such as 'AttendeesUnavailable' or a too-narrow window. This discloses behavior that annotations alone do not convey.

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 three concise, front-loaded sentences. It opens with the core function, then adds key behavioral details without redundancy or fluff.

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?

Given the parameter schema and annotations, the description covers the main operational aspects: ranking, default count, required attendees, and empty-result behavior. With no output schema, it appropriately mentions the emptySuggestionsReason that callers would need to interpret results, though it could slightly expand on the shape of successful suggestions.

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 input schema already documents all parameters. The description adds minor clarifications (default of 10 suggestions, all attendees required) but does not substantially enrich parameter meaning beyond 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 uses a specific verb and resource: 'Suggests meeting slots that work for the signed-in user and the given attendees, ranked by confidence.' It clearly distinguishes this from sibling tools like calendar_get_schedule by focusing on proposing available times rather than reading existing events.

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: use this when you need to find meeting slots for a set of attendees. However, it does not explicitly state when to use this tool versus alternatives such as calendar_get_schedule or calendar_list_events, nor does it provide exclusion criteria.

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

calendar_get_eventGet a calendar eventA
Read-onlyIdempotent

Returns one event in full: subject, start, end, location, organizer, the attendee list with each response, the description body (HTML converted to text and capped), recurrence summary, and the Outlook web link. Use calendar_list_events first to find the id.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesEvent id, from calendar_list_events.
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, covering safety. The description adds valuable behavioral details beyond annotations: the description body is HTML-converted to text and capped (a truncation limit), and it mentions recurrence summary and the Outlook web link. This gives the agent a good sense of the return shape and transformation applied, going beyond the basic read-only 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?

Two sentences with no redundancy. The first sentence enumerates the return fields in a compact list, and the second gives the essential usage instruction. All content earns its place; nothing extraneous.

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 read tool with one required parameter, the description is quite complete. It lists all major return fields, explains the prerequisite, and the schema covers timezone handling. It doesn't mention error behavior (e.g., event not found) but that is standard and not critical for an agent to invoke correctly. Overall, an agent has enough to call it properly.

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%: both id and timeZone are fully described in the schema. The description does not add new parameter semantics, though it reiterates the id source ('from calendar_list_events') which is already in the schema. Baseline of 3 is appropriate given the schema carries the parameter documentation burden.

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 purpose: returns one event in full, listing the specific fields (subject, start, end, location, organizer, attendees, description, recurrence, link). This distinguishes it from sibling tools like calendar_list_events (which lists events) and calendar_get_schedule (which gets availability) by focusing on a single event's complete details.

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?

Provides explicit guidance to use calendar_list_events first to find the id, which is the key prerequisite. It clearly implies this tool is for retrieving a single event after identifying it. Does not explicitly contrast with alternatives like calendar_get_schedule, but the usage context is clear from the instruction.

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

calendar_get_scheduleGet free/busy scheduleA
Read-onlyIdempotent

Returns free/busy availability for up to 20 people or rooms over a time window, as an availabilityView string where each character covers one interval (0 free, 1 tentative, 2 busy, 3 out of office, 4 working elsewhere), plus working hours and any visible busy blocks. Read-only despite being an HTTP POST. Subject and location are only returned for people who share those details with you; everything else comes back as a bare busy block.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesISO-8601 end of the window. Keep the window under a few days: the availability string grows with it.
startYesISO-8601 start of the window to check, e.g. 2026-01-31T08:00:00Z.
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.
schedulesYesSMTP addresses of the people or rooms to check, at most 20 per call.
availabilityViewIntervalNoMinutes each character of availabilityView represents. Defaults to 30.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the readOnlyHint/idempotentHint annotations, the description adds genuinely useful behavioral detail: it is read-only despite being an HTTP POST, the availabilityView character encoding (0-4), the inclusion of working hours and busy blocks, and the visibility caveat for subject/location. This is substantial context an agent would not get from annotations alone.

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?

Three sentences, front-loaded with the core purposematic and then adding the encoding details and caveat. Every sentence carries essential information and there is no redundancy or filler.

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?

With no output schema, the description compensates by explaining the availabilityView encoding, working-hours return, busy blocks, and visibility behavior. It is slightly vague about the exact structure of 'visible busy blocks' but is otherwise sufficient for an agent to invoke and interpret the result.

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 parameters are already well-documented. The description reinforces some constraints (20 people, time window, interval characters) but does not add significant new parameter-level meaning beyond what the schema provides.

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 uses a specific verb ('returns') and clearly names the resource: free/busy availability for up to 20 people or rooms over a time window. It also details the output format, making it easy to distinguish from calendar_list_events or calendar_get_event.

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 clearly establishes its context: checking free/busy availability for multiple people/rooms over a time window. It does not explicitly name sibling alternatives or exclusion conditions, but the purpose is distinct enough that an agent can infer when to use it, particularly against calendar_find_meeting_times.

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

calendar_list_calendarsList calendarsA
Read-onlyIdempotent

Lists the signed-in user's calendars with id, name, colour, owner and whether they can be edited or shared. Returns 50 by default. Use the returned id as calendarId in calendar_list_events.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum calendars to return. Defaults to 50.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds that it 'Returns 50 by default' (pagination limit) and further explains the return payload fields. These are behavioral traits not in the annotations, adding value beyond the structured metadata. No contradictions found.

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 only two sentences, with the core purpose front-loaded and the default behavior and chaining guidance included in the second sentence. No fluff, no redundant repetition of schema or annotations. Every sentence earns its place.

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 simple list tool with one optional parameter and no output schema, the description is complete. It tells the agent what it returns (fields), the default page size, how to use the results (via calendarId), and implicitly that it operates on the signed-in user's calendars. Nothing essential is missing.

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?

The schema description coverage is 100%, and the only parameter `top` is fully documented in the schema (maximum, default, meaning). The description repeats the default of 50 but does not add any new meaning beyond the schema. Per the rubric, a baseline of 3 is appropriate when the schema already covers parameter semantics.

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 verb 'Lists' and the resource 'the signed-in user's calendars', enumerating the fields returned (id, name, colour, owner, edit/share flags). This is specific and distinguishes it from sibling tools like calendar_get_event (which fetches a single calendar) and calendar_list_events (which lists events). The scope is unambiguous.

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 usage context by saying 'Use the returned id as calendarId in calendar_list_events', which tells the agent a common workflow. It does not explicitly contrast with alternatives like calendar_get_event, nor state when not to use it, but the chaining instruction gives a definite purpose. This merits a 4 (clear context, but no exclusions).

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

calendar_list_eventsList calendar eventsA
Read-onlyIdempotent

Lists events with subject, start, end, location, organizer and attendee count, plus a nextLink when more pages exist. Returns 25 events by default. Passing both start and end switches to calendarView, which expands recurring meetings into their individual occurrences; without them the raw event list is returned, where a recurring series appears once as its series master. Times without an explicit offset in start/end are read as UTC — pass a timeZone to control how returned times are rendered.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoISO-8601 end of the window. Must be given together with `start`.
topNoMaximum events to return in this page. Defaults to 25.
startNoISO-8601 start of the window, e.g. 2026-01-31T00:00:00Z. Must be given together with `end`; supplying both switches to calendarView, which expands recurring series into individual occurrences.
selectNoGraph field names to return, e.g. ["id","subject","start"]. When given, the raw selected fields are returned instead of the compact projection.
orderbyNoOData sort expression, e.g. "start/dateTime desc". Defaults to "start/dateTime" ascending.
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.
calendarIdNoCalendar to read from, from calendar_list_calendars. Defaults to the primary calendar.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already indicate a safe read-only operation, and the description adds valuable non-obvious behaviors: default page size of 25, nextLink pagination, calendarView expansion of recurring meetings, and UTC interpretation of naive times with timeZone rendering control. This goes well beyond the structured annotations.

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?

Three sentences, each earning its place: the first states output payload, the second states pagination default, the third explains the critical start/end and timeZone behavior. Information is front-loaded and dense without being verbose.

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 (7 optional params, no output schema, read-only safe annotations), the description covers return fields, pagination, recurring behavior, defaults, and timezone handling. An agent has enough to invoke it correctly without further research.

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 input schema covers all 7 parameters with descriptions, the tool description adds crucial cross-parameter semantics: start and end must be used together to trigger calendarView, and timeZone affects interpretation of naive values and rendering. This meaning is not present in the schema and materially improves correct invocation.

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 uses a specific verb ('Lists events') and details the exact output fields (subject, start, end, location, organizer, attendee count, nextLink), making the tool's purpose unmistakable. It is clearly distinct from siblings like calendar_get_event (single event) and calendar_list_calendars (calendar list).

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, explicit guidance on how to use the start/end parameters to switch between raw event list and calendarView, including the behavioral difference for recurring series. While it does not name alternative tools, the usage context is unambiguous and the parameter-level when/when-not guidance is strong enough for an agent to call it correctly.

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

calendar_respond_eventRespond to a meeting invitationA
Destructive

Accepts, declines, or tentatively accepts a meeting invitation, optionally with a comment to the organizer. Graph returns no content on success. Only works on events where the signed-in user is an attendee — responding to an event they organized fails. Proposing a new time is not supported.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesEvent id of the invitation to respond to.
commentNoOptional message included with the reply.
responseYesThe reply to send.
sendResponseNoWhether the organizer is notified. Defaults to true.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true nhận readOnlyHint=false, but the description adds meaningful behavior beyond that: 'Graph returns no content on success,' the attendee-only constraint, response failure for organizer-created events, and the inability to propose a new time. This gives an agent a realistic picture of side effects 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?

Three sentences with no wasted words. The main action is front-loaded, followed by the success return behavior awaited then the critical constraints. Every sentence earns its place.

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 mutation tool with no output schema, this description covers the essential facts: what the reply does, the success response (empty content), attendee precondition, and unsupported proposal flow. An agent has enough to decide when and how to call the tool without encountering surprises.

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%, and each parameter (id, comment, response, sendResponse) already has a clear schema description. The tool description adds little parameter-specific meaning beyond restating the response options and the optional comment, so the baseline 3 is appropriate.

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 opens with a specific verb and resource: 'Accepts, declines, or tentatively accepts a meeting invitation...' This clearly distinguishes the tool from siblings like calendar_create_event or calendar_update_event. The additional note that proposing a new time is not supported further sharpens its 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 gives clear context: responding only works when the signed-in user is an attendee, and it explicitly fails for events the user organized. It also names the unsupported 'propose new time' flow. However, it does not explicitly point to alternatives or say 'use calendar_update_event for edits,' so the when-not-to-use guidance is not fully explicit.

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

calendar_update_eventUpdate a calendar eventA
Idempotent

Patches the given fields on an event and returns the updated event; omitted fields are left alone. Two traps: sending attendees replaces the whole list, so anyone left out is uninvited, and changing the time or attendees of a meeting sends an update to everyone invited. Updating a recurring series master changes every occurrence.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesEvent id to update.
endNoNew ISO-8601 end.
bodyNoReplacement event description.
startNoNew ISO-8601 start. Send `end` too whenever the new start would land after the existing end.
showAsNoHow the event shows on the free/busy view.
subjectNoNew subject line.
bodyTypeNoHow to interpret `body`. Defaults to 'text'.text
isAllDayNoSwitch the event to or from all-day.
locationNoReplacement location.
timeZoneNoIANA or Windows time-zone name (e.g. "Europe/Berlin", "Pacific Standard Time") used to interpret naive start/end values and to render returned times.
attendeesNoReplaces the entire attendee list — anyone omitted is uninvited, so send the full list, not just additions.
categoriesNoReplaces the category list.
isOnlineMeetingNoAdd a Teams meeting link. Removing one after the fact is not supported.
reminderMinutesBeforeStartNoReminder lead time in minutes.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already indicate idempotentHint=true (safe to retry), readOnlyHint=false and destructiveHint=false (mutation but not destructive). The description adds behavioral context beyond annotations: it explicitly warns about side effects (emails to attendees, impact on series), and states that omitted fields are left alone, which clarifies idempotency and partial update behavior. It doesn't mention auth requirements, but that's likely covered elsewhere. No contradiction with annotations.

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 compact: three sentences, front-loaded with the core patch semantics, followed by the most critical traps. Every sentence carries operational weight. It avoids boilerplate and directly addresses the highest-risk aspects of the tool. No fluff.

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?

Given the tool's complexity (14 params, many with nuanced behavior), the description covers the most critical operational details: partial update semantics, the attendees replacement issue, and notification side effects. It does not cover every parameter (e.g., timeZone interpretation, isOnlineMeeting removal limitation), but the schema descriptions provide that. With annotations covering idempotency, and high schema coverage, the description is sufficiently complete for correct invocation. It could mention recurring series implications more explicitly, but the warning about updating the series master covers it.

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 description coverage is 100%, so the schema already documents each parameter. The description adds value by highlighting the 'attendees' replacement trap, which is not fully captured in the schema description (schema says 'replaces the entire attendee list' but description reinforces it with the 'uninvited' consequence). It also adds the context that changing start/end triggers notifications. For a complex tool with 14 params, this extra guidance is valuable beyond 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 that it patches given fields on an event and returns the updated event, with a clear verb ('patches') and resource ('event'). It distinguishes itself from sibling tools like calendar_create_event (creates new) and calendar_delete_event (removes), and from read-only tools like calendar_get_event. The description also emphasizes partial update semantics, which is key for an update tool.

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 explicitly warns about common pitfalls: sending 'attendees' replaces the whole list (so users must send the full list), changing time/attendees sends updates to invitees, and updating a recurring series master affects all occurrences. It doesn't explicitly name alternatives, but given the unrelated sibling set (files, mail, todo), the context is clear. The warnings provide critical when-to-be-careful guidance.

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

contacts_createCreate a contactA

Creates a personal contact in the signed-in user's default Contacts folder and returns the stored contact, including the new id. Outlook builds displayName from givenName and surname. Outlook holds at most 3 email addresses per contact. Graph does not de-duplicate: calling this twice creates two contacts, so search first when the contact may already exist.

ParametersJSON Schema
NameRequiredDescriptionDefault
surnameNoThe contact's last name.
jobTitleNoJob title at that organisation.
givenNameYesThe contact's first name.
companyNameNoEmployer or organisation.
mobilePhoneNoMobile phone number, as free text, e.g. "+1 425 555 0109".
emailAddressesNoUp to 3 email addresses, in Outlook slot order (Email 1, 2, 3). Outlook has no fourth slot.

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false. The description adds crucial behavior: displayName is derived from givenName/surname, max 3 emails, and no de-duplication. These are non-obvious and critical for correct invocation, going well beyond the annotation hints.

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?

Three sentences with zero fluff. The primary action and return value are front-loaded, followed by two essential constraints (displayName construction, email limit, de-duplication warning). Every sentence earns its place.

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 creation tool with 6 parameters, no output schema, and critical platform-specific behaviors, the description covers all essential context: what it does, what it returns, and pitfalls (de-duplication, displayName, email limits). An agent has everything needed to call it 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?

Schema coverage is 100%, but the description enriches parameter meaning: explains that givenName and surname together form displayName, and that emailAddresses is capped at 3 due to Outlook's slot limitation. This adds semantic relationships not present in 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?

States a specific verb (creates), resource (personal contact in signed-in user's default Contacts folder), and the return value (stored contact with new id). It clearly distinguishes from sibling tools like contacts_update or contacts_delete by focusing on creation and explicitly naming the de-duplication caveat.

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?

Explicitly describes when to use the tool (create a contact) and when not to (search first if contact may exist, due to lack of de-duplication). This provides clear guidance for an agent to choose correctly among contact-related tools.

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

contacts_deleteDelete a contactA
Destructive

Deletes one personal contact. The contact moves to the Deleted Items folder, so it is recoverable from Outlook but not through these tools, and Graph returns no body — only a confirmation of the id. Deleting an id that is already gone fails with 404 ErrorItemNotFound.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe contact id, as returned by contacts_list or contacts_search. This is the long opaque Outlook item id, not an email address or display name.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint=true, idempotentHint=false), the description adds critical behavior: the contact moves to Deleted Items, recovery is only via Outlook, Graph returns no body, and deleting an already-gone id yields 404. This enriches the agent's understanding of side effects and error handling without contradicting any annotation.

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?

Three tight sentences that front-load the primary action, then cover side effects, response, and error behavior. No redundant phrasing; every sentence contributes value.

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 simple one-parameter delete tool, the description covers the outcome, recoverability, response shape, and failure mode. No output schema exists, but the response is described. It is fully sufficient for an agent to call 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 100% and already specifies the id must come from contacts_list or contacts_search and be the opaque Outlook item id. The description adds nothing beyond that, so it does not improve parameter understanding beyond the schema's 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 opens with 'Deletes one personal contact,' a specific verb and resource that clearly differentiates it from the other contact tools (list, get, search, create, update). It leaves no ambiguity about what action the tool performs.

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 context by stating the id must come from contacts_list or contacts_search and clarifying that deletion is permanent within these tools (recoverable only via Outlook). It does not explicitly name alternatives, but it's the sole contact-deletion tool among siblings, so the guidance is adequate though not exhaustive.

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

contacts_getGet a contactA
Read-onlyIdempotent

Returns one personal contact by id, with names, company, job title, department, every email address, phone numbers, postal addresses, birthday, categories and timestamps. Personal notes are truncated to 1000 characters. Properties Graph reports as empty are omitted, so a missing key means the field is not set. An id from a different mailbox or a deleted contact fails with 404 ErrorItemNotFound.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe contact id, as returned by contacts_list or contacts_search. This is the long opaque Outlook item id, not an email address or display name.

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare readOnlyHint and idempotentHint, but the description adds valuable behavioral context: personal notes are truncated to 1000 characters, empty properties are omitted, a missing key means the field is not set, and wrong-mailbox/deleted ids fail with 404 ErrorItemNotFound. No contradiction with annotations.

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?

Four sentences, each earning its place: return-field list, truncation behavior, omission semantics, and failure mode. The core purpose is front-loaded, and there is no filler or repetition of annotations.

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 one-parameter, read-only getter with no output schema, the description covers the returned fields, important data-shaping behavior, and error semantics. An agent has enough information to invoke the tool and interpret its response 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?

The input schema has 100% description coverage for the single id parameter, including its source and what it is not. The description only restates that the operation is by id and adds no additional parameter-level meaning beyond the schema, so the baseline 3 applies.

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?

States a specific verb ('Returns') and resource ('one personal contact by id'), and enumerates the exact fields returned. This clearly distinguishes it from collection-returning siblings like contacts_list and contacts_search and from mutating siblings like contacts_create or contacts_delete.

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 and parameter schema imply that the agent must already have an opaque contact id from contacts_list or contacts_search, but it does not explicitly state when to prefer this tool over alternatives or when not to use it. The usage context is implied rather than stated.

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

contacts_listList contactsA
Read-onlyIdempotent

Lists personal contacts from the signed-in user's default Outlook Contacts folder, 25 per page by default (max 100). Each row carries id, displayName, given/surname, company, job title, email addresses and phone numbers; pass select for different properties. A nextLink in the result means more pages exist — call again with skip set to the number already seen. Contacts stored in a custom contact folder are not included.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoHow many contacts to return in this page. Graph itself defaults to 10.
skipNoHow many contacts to skip before this page, for paging: pass the running total already seen. Only meaningful while `nextLink` is present in the previous result.
filterNoRaw OData $filter over `contact` properties, e.g. "companyName eq 'Contoso'" or "startswith(surname,'Mc')". Single quotes inside a literal must be doubled. Filtering on emailAddresses is not supported by Outlook — use contacts_search for that.
selectNoGraph `contact` property names to return instead of the default compact projection, e.g. ["displayName","department","birthday"]. Bare property names only; OData expressions and navigation paths are rejected. `id` is always included.
orderbyNoSort order, e.g. "displayName" or "lastModifiedDateTime desc". Bare property names only. Omit to get Outlook's own ordering.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnly, idempotent, and non-destructive, so the tool's safety profile is covered. The description adds valuable behavior beyond annotations: default page size, the default row projection, nextLink-based paging with skip, and the exclusion of custom contact folders.

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 front-loaded with the core purpose and then efficiently covers output shape, pagination, and scope limitations. Every sentence earns its place without unnecessary padding.

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?

With no output schema, the description still tells the agent what fields each row carries and how to request different properties. Pagination is fully explained, and the custom-folder exclusion prevents misuse, making the tool callable without hidden assumptions.

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%, and the schema already documents top, skip, filter, select, and orderby in detail. The description restates the default page size, select behavior, and nextLink skip pattern, but adds little parameter-level meaning beyond the custom-folder scope caveat.

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 first sentence names a specific verb and resource: it lists personal contacts from the signed-in user's default Outlook Contacts folder. The final sentence also clarifies what is not included, which helps distinguish it from tools that search across custom folders.

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 explicitly tells the agent to use contacts_search when filtering on emailAddresses is needed, and it flags that custom contact folders are out of scope. This gives clear when-to-use and when-not-to-use guidance relative to alternatives.

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

contacts_updateUpdate a contactA
Idempotent

Updates the given fields of one personal contact and returns the stored result. Omitted fields are left alone, but emailAddresses is a collection: supplying it REPLACES every address on the contact, so read the contact first and resend the ones to keep. There is no optimistic-concurrency check here — a concurrent edit from Outlook is silently overwritten. At least one field besides id is required.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe contact id, as returned by contacts_list or contacts_search. This is the long opaque Outlook item id, not an email address or display name.
surnameNoThe contact's last name.
jobTitleNoJob title at that organisation.
givenNameNoThe contact's first name.
companyNameNoEmployer or organisation.
displayNameNoThe name Outlook files the contact under. Outlook derives it from the given and surname when it has never been set explicitly; setting it here stops that.
mobilePhoneNoMobile phone number, as free text.
emailAddressesNoReplacement list of up to 3 email addresses. This REPLACES every existing address rather than adding to them, so include the ones to keep. Read the contact first if unsure.

TDQS

A4.6/5.0
Behavior5/5

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

The description goes far beyond the annotations by disclosing patch semantics (omitted fields left alone), the replacement behavior of emailAddresses, and the lack of optimistic concurrency checking with silent overwrites. These are critical behavioral traits that the annotations alone do not convey.

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 three sentences, each earning its place: the main purpose, the critical emailAddresses replacement warning, and the concurrency caveat. It is front-loaded and free of redundant phrasing.

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 output schema, the description adequately notes that it returns the stored result and covers the most important behavioral pitfalls. It does not mention error cases (e.g., contact not found) or provide details about the return structure, but given the schema richness and clear warnings, it is substantially complete.

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 100% and each parameter has a rich description. The overall description adds collective semantic value: 'Omitted fields are left alone' and 'At least one field besides id is required' are not stated in the schema and provide crucial update semantics beyond the individual property descriptions.

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 states a specific verb ('Updates') and resource ('one personal contact'), making the tool's purpose unmistakable. It naturally distinguishes itself from sibling tools like contacts_create, contacts_delete, contacts_get, and contacts_list by focusing on partial modification of existing contacts.

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, including the requirement that at least one field besides id be provided, and warns about emailAddresses replacement behavior. It does not explicitly mention when NOT to use this tool versus alternatives, but the update semantics are evident from the description and name.

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

files_create_folderCreate a OneDrive folderA

Creates a folder in the signed-in user's OneDrive and returns the created item. Give the parent as parentItemId or parentPath, or omit both for the drive root. A name collision does not fail: Graph renames the new folder with a numeric suffix, so read the returned name rather than assuming it.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName of the new folder. An existing folder of the same name does not cause a failure; the new one gets a numeric suffix.
parentPathNoPath of the parent folder from the drive root, e.g. "Documents/Reports". Mutually exclusive with parentItemId. Omit both to create in the drive root.
parentItemIdNoId of the parent folder. Mutually exclusive with parentPath. Omit both to create in the drive root.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations indicate a mutating, non-idempotent operation. The description adds valuable context by disclosing collision behavior (numeric suffix rename) and that the created item is returned, which goes beyond what annotations provide.

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 with no fluff. Purpose is front-loaded, followed by parameter guidance and a key behavioral warning. Every sentence earns its place.

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 covers essential behaviors: what it creates, parent specification, collision handling, and return of the created item. Given full schema coverage and no output schema, it is sufficiently complete, though return fields could be specified.

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%, so all three parameters are already described. The description repeats mutual exclusivity and root omission but does not add new meaning beyond the schema. Baseline of 3 applies.

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 states the verb 'Creates' and the resource 'folder in the signed-in user's OneDrive', making the purpose unambiguous. It doesn't explicitly contrast with sibling file tools, but the folder-specific action is distinct enough to differentiate.

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 explains how to specify the parent (parentItemId or parentPath, omit both for root), which is parameter usage, but it does not provide guidance on when to choose this tool over alternatives like files_upload_text or files_create_link. Usage context is implied rather than explicit.

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

files_deleteDelete a OneDrive itemA
Destructive

Deletes a file or folder from the signed-in user's OneDrive. Deleting a folder deletes everything inside it. The item goes to the OneDrive recycle bin rather than being destroyed, but this server has no tool to restore it, so confirm the id with files_get_item first.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemIdYesId of the file or folder to delete. Deleting a folder deletes everything inside it.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already mark this as destructive and non-idempotent, and the description adds valuable behavior beyond that: folder deletion removes contents, items go to the recycle bin, and no restore tool exists. There is no contradiction with the annotations.

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?

Three dense, purposeful sentences: the core action first, then the folder caveat, then the safety and recovery warning. Every sentence earns its place with no redundant wording.

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 simple one-parameter destructive tool, the description covers what is deleted, the scope of deletion, the recycle-bin behavior, the lack of restore capability, and the recommended pre-check. No critical information is missing.

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 schema already documents itemId at 100% coverage, so the baseline is 3. The description adds extra meaning by advising the agent to confirm the id with files_get_item first, which helps the agent supply a valid parameter value.

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 verb 'Deletes' and the resource 'file or folder from the signed-in user's OneDrive'. It also calls out the folder-recursion consequence, which helps distinguish this tool from other delete tools among the siblings.

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 gives explicit pre-use guidance: confirm the id with files_get_item first and be aware there is no restore tool. This is strong practical context, though it doesn't explicitly list alternatives or conditions when not to use this tool.

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

files_get_itemGet a OneDrive itemA
Read-onlyIdempotent

Reads the metadata of one OneDrive file or folder: name, kind, size, mime type, created and last-modified times and authors, parent folder path and ids, and webUrl. Address it by itemId or by path, not both. The pre-authenticated download URL is deliberately not returned; use files_read_text for text contents or files_create_link to share the item.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoPath from the OneDrive root, e.g. "Documents/Reports/q3.docx". Leading slashes are ignored. Mutually exclusive with itemId.
itemIdNoDrive item id, as returned by any files_* listing tool. Mutually exclusive with path.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already establish the safety profile (readOnly=true, idempotent=true, destructive=false). The description adds meaningful behavioral context beyond that by disclosing that the pre-authenticated download URL is deliberately not returned and listing the metadata fields that are. It could still say more about error cases or permission expectations, but the read-only annotations lower the bar.

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?

Three tightly written sentences: the first establishes what and which fields, the second covers addressing mode, and the third handles an important caveat plus alternatives. There is no filler or redundant restating of the title.

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 simple read-only metadata tool with only two optional parameters and no output schema, the description is sufficient: it lists the return fields, explains how to address the item, and clarifies the notable missing field (download URL) with fallback tools. An agent can call this tool correctly without needing the schema.

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 parameters are already well documented. The description reinforces the mutual exclusivity of itemId and path, but that constraint is already present in the schema. No new parameter-level meaning is added, so the baseline 3 applies.

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 opens with a specific verb and resource: 'Reads the metadata of one OneDrive file or folder' and enumerates exactly which fields are returned. It also distinguishes itself from content/download tools by noting the download URL is intentionally absent and pointing to files_read_text and files_create_link.

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?

It states the tool is for reading metadata of a single item, explains the addressing constraint ('by itemId or by path, not both'), and explicitly names alternatives when the pre-authenticated download URL is expected: files_read_text for contents and files_create_link for sharing. This gives an agent clear when/when-not guidance.

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

files_list_childrenList OneDrive folder contentsA
Read-onlyIdempotent

Lists the direct children of a folder in the signed-in user's OneDrive, returning id, name, kind (file or folder), size, mime type, child count, last-modified time and webUrl per entry, plus count and nextLink when more pages exist. Address the folder by itemId or by path; omit both for the drive root. Page size defaults to 50. This is not recursive: use files_search to look through the whole drive.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of children to return in this page. Defaults to 50.
pathNoPath of the folder to list, e.g. "Documents/Reports". Path from the OneDrive root, e.g. "Documents/Reports/q3.docx". Leading slashes are ignored. Mutually exclusive with itemId. Omit both to list the drive root.
itemIdNoId of the folder to list. Drive item id, as returned by any files_* listing tool. Mutually exclusive with path. Omit both to list the drive root.
orderbyNoSort order for the children. Graph defaults to name ascending. OneDrive for Business (SharePoint-backed) drives silently ignore some sorts, notably by size.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety and idempotency. The description adds valuable behavioral context: non-recursive nature, pagination via nextLink, default page size, and the fact that it returns multiple entries. It also notes that SharePoint-backed drives may ignore some sorts, which is a useful caveat. The only minor gap is lack of detail on error handling or rate limits, but with strong annotations, this is above baseline.

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 two sentences: the first is information-dense, covering return fields, addressing, and pagination; the second clarifies non-recursion and points to the alternative. It is concise, front-loaded with the primary purpose, and every sentence earns its place without redundancy.

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 moderate complexity (4 params, no required params, decisive annotations), the description is complete: it explains return fields, pagination, default page size, non-recursion, and alternate addressing. No output schema exists, but the description lists all return fields, making it self-sufficient. There is no missing guidance for an agent to call this 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 100%, so all parameters are fully described in the schema. The description adds context by explicitly mentioning the mutual exclusivity of itemId and path, and the omission for root, which reinforces but does not extend the schema. Since coverage is high, baseline 3 is appropriate; no significant added meaning.

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 lists direct children of a folder in OneDrive, enumerates the exact fields returned, and distinguishes it from recursive search by naming files_search as the non-recursive alternative. This is a specific verb+resource with sufficient detail to differentiate from siblings.

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 explicitly states when to use this tool (list direct children) and when not to (use files_search for whole-drive search). It also clarifies how to address the folder (by itemId, by path, or omit for root), which serves as usage guidance. No exclusions are needed beyond that.

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

files_list_recentList recent OneDrive filesA
Read-onlyIdempotent

Lists files the signed-in user recently opened or edited, most recent first, with count and nextLink. Defaults to 25 items. Entries can come from other people's drives or from SharePoint; those carry remoteDriveId and remoteItemId, and their plain id will not resolve against your own drive.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of recent items to return. Defaults to 25.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare the tool read-only, idempotent, and non-destructive. The description adds valuable behavior beyond this: results include count and nextLink, default to 25 items, and may include remote items from other drives or SharePoint with an important caveat about remote IDs not resolving against the user's own drive.

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?

Three sentences with no filler, front-loading the core action and output, then providing the default limit and the remote-item caveat. Every sentence contributes necessary information for correct invocation.

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 one-parameter read-only listing tool with no output schema, the description is complete: it states what is returned (items, count, nextLink), the sort order, the default count, and a non-obvious remote-item edge case. An agent has enough to call it correctly without further inference.

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% for the single 'top' parameter, so the schema already documents its meaning, default, and bounds. The description adds context like 'most recent first' and 'defaults to 25 items,' but the latter is already in the schema, so the added parameter-specific value is minimal.

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 uses a specific verb and resource: 'Lists files the signed-in user recently opened or edited.' It clearly distinguishes this from sibling tools like files_search (search-based), files_list_shared (shared items), and files_list_children (folder contents) by focusing on recency and the user's own activity.

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 usage context is implied rather than explicit: the tool is for retrieving recently opened or edited files. However, it does not explicitly state when to prefer this tool over files_list_shared or files_search, nor does it mention any exclusions or alternative conditions.

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

files_list_sharedList files shared with meA
Read-onlyIdempotent

Lists files and folders other people have shared with the signed-in user, with count and nextLink. Defaults to 25 items. These entries are stubs pointing into the owner's drive: use remoteDriveId together with remoteItemId to identify one, or open its webUrl. The other files_* tools address only your own OneDrive, so they cannot read these items by id. Needs the Files.Read.All scope, which a user can consent to without an administrator.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of shared items to return. Defaults to 25. sharedWithMe applies this loosely and may return a different number.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare this as read-only, idempotent, and non-destructive. The description adds substantial behavioral context beyond that: returned entries are stubs into the owner's drive, results include count and nextLink, default item count is 25, and Files.Read.All scope is required. No contradictions with annotations.

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?

Four sentences, all information-dense and relevant. The core action is stated first, followed by operational caveats, sibling differentiation, and scope requirement. No filler or redundancy.

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 one-parameter list operation with clear annotations candidate output schema, this is complete. It explains what is returned (count, nextLink, shared stubs), how to reference items, the limitation of sibling tools, and the permission requirement. An agent has enough to invoke it 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?

There is only one optional parameter and schema description coverage is 100%, so the schema already fully documents top's meaning, default, bounds, and loose behavior. The tool description reinforces the 25-item default but adds no genuinely new parameter semantics beyond what the schema provides.

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 states a specific verb ('Lists') and resource ('files and folders other people have shared with the signed-in user'), and immediately distinguishes itself from sibling files_* tools by noting those only address the user's own OneDrive. An agent can clearly tell this apart from files_list_recent or files_list_children.

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 explicitly explains when this tool is appropriate (shared-with-me items) and provides a concrete exclusion: other files_* tools cannot read these items by id. It also gives the correct handling path via remoteDriveId/remoteItemId or webUrl, plus the required scope. This is strong routing guidance.

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

files_read_textRead a text file from OneDriveA
Read-onlyIdempotent

Returns the contents of a text-like OneDrive file (plain text, Markdown, CSV, JSON, XML, source code, config) as a string, truncated to maxChars, which defaults to 20000. Reads the file metadata first and refuses binary formats — PDFs, images, Office documents, archives, media — with an explanation, because their bytes are not readable as text. Word, Excel and PowerPoint files are zip containers and cannot be read here.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemIdYesId of the file to read, as returned by files_list_children or files_search.
maxCharsNoMaximum characters of file content to return. Defaults to 20000; longer files are truncated with a marker.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the readOnly/idempotent/non-destructive annotations, the description discloses meaningful behavior: it reads metadata first, refuses binary formats with an explanation, truncates to maxChars with a default, and explains that Office files are zip containers. This gives the agent an accurate model of what the tool will and will not do.

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?

Three sentences, front-loaded with the core return behavior, then the binary-format refusal and the Office-file explanation. Every sentence contributes actionable guidance with no filler or redundancy.

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 relatively simple read tool with well-documented parameters and strong annotations, the description covers what it returns, how it truncates, what it refuses, and why. The absence of an output schema is compensated by the explicit 'returns a string' statement, making the description complete for invocation.

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 schema already documents itemId and maxChars, including default, range, and truncation marker. The description reinforces the truncation behavior but adds little beyond what the schema provides; the baseline 3 is appropriate.

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 states a precise action — 'returns the contents of a text-like OneDrive file' — and clearly scopes the resource to text-like formats while excluding binaries. This distinguishes it from sibling tools like files_get_item (metadata) and files_upload_text (writing) without ambiguity.

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 gives clear when-to-use context (plain text, Markdown, CSV, JSON, XML, source code, config) and explicit when-not-to-use context (PDFs, images, Office documents, archives, media). It does not name alternative sibling tools, but the exclusion criteria are concrete enough for an agent to select this tool correctly.

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

files_upload_textUpload a text file to OneDriveA

Writes a text file to the given path in the signed-in user's OneDrive and returns the stored item. Missing parent folders are created automatically. An existing file at that path is REPLACED, not merged or appended, so read it with files_read_text first if you mean to edit it. Text only, up to 4 MB; larger or binary uploads need a resumable upload session, which this server does not expose.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesDestination path from the OneDrive root including the file name, e.g. "Notes/meeting-2026-09-03.md". Missing parent folders are created automatically.
contentYesThe full text to write. This replaces the file contents; there is no append mode.

TDQS

A4.7/5.0
Behavior5/5

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

Despite annotations not marking destructiveHint, the description clearly discloses that an existing file is REPLACED, not merged or appended, and warns about size limits and binary content. This goes well beyond the minimal annotation info and fully informs the agent of side effects.

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?

Three sentences with no fluff. The primary action is stated first, followed by critical behavioral warnings and limits. Information is front-loaded and every sentence adds value.

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 write operation with two parameters, no output schema, and minimal annotations, the description covers the core behavior, side effects, limits, and alternatives. An agent has all necessary information to call it correctly without ambiguity.

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%, so both parameters are already documented. The description adds a note about automatic folder creation and replacement semantics, but these are also echoed in the schema descriptions. The description doesn't significantly enhance parameter meaning beyond the schema, so a baseline 3 is appropriate.

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 states a specific verb ('Writes') and resource ('a text file to the given path in the signed-in user's OneDrive'), and distinguishes it from siblings like files_read_text and files_create_folder. It is immediately clear what the tool does and how it differs from related file operations.

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 explicitly explains when to use it (text files up to 4 MB) and when not to (larger or binary uploads need a resumable session not exposed). It also advises reading the file first with files_read_text before editing, giving clear usage and exclusion criteria.

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

graph_list_permissionsList granted permissionsA
Read-onlyIdempotent

Reports how this server is configured: which tool groups are enabled, the delegated Microsoft Graph scopes each one uses, which of them need a tenant administrator to consent, whether write tools are suppressed, and the signed-in account. Call it when a request fails with 403 or "insufficient privileges" to see whether the needed area is switched on at all. Reads only the signed-in account from Graph.

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?

The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description reinforces this by adding 'Reads only the signed-in account from Graph,' which tells the agent the call has a narrow read footprint rather than enumerating all permissions or making changes. This adds behavioral context beyond the annotations without contradicting them.

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 three sentences with no filler. It front-loads the core purpose ('Reports how this server is configured'), then lists the concrete output categories, gives a practical usage trigger, and closes with the read scope. Every sentence earns its place.

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-argument, read-only diagnostic tool, the description is complete. It tells the agent what the tool reveals, when to call it, and what side effects it has. Although there is no output schema, the description sufficiently characterizes the return content for an agent to decide whether this tool fits the situation.

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 the schema confirms an empty properties object with 100% coverage. With no parameters to describe, the baseline of 4 applies; the description appropriately avoids inventing parameter-related noise.

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 opens with 'Reports how this server is configured' and enumerates exactly what it covers: enabled tool groups, delegated Graph scopes, admin consent requirements, write-tool suppression, and the signed-in account. This clearly distinguishes it from the sibling tools, which perform actions on mail, files, calendar, and contacts rather than inspecting server permission configuration.

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 an explicit trigger: 'Call it when a request fails with 403 or "insufficient privileges" to see whether the needed area is switched on at all.' This is a clear context for use. It does not explicitly name alternative tools or say when not to use it, but the diagnostic purpose is distinct from the action-oriented sibling tools, so no exclusion is necessary.

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

graph_requestCall Microsoft Graph directlyA
Read-onlyIdempotent

Sends an arbitrary request to Microsoft Graph and returns the raw JSON response. Use this only when no purpose-built tool covers the endpoint: the dedicated tools project and trim their results, while this one returns everything Graph sends, which is often far more text. The host is fixed to this tenant's Graph endpoint and path must be relative, so an absolute URL is rejected. GET is always available; the write methods require --allow-generic-write. Pass maxPages to follow @odata.nextLink, and prefer $select and $top in query to keep the response small.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNoRequest body for a write method, as JSON. Ignored for GET. A string is sent as raw bytes (which is what Graph content endpoints expect); anything else is JSON-encoded.
pathYesGraph-relative path beginning with "/", e.g. "/me/messages" or "/users/alice@contoso.com/drive/root/children". Never a full URL: the host is fixed and an absolute URL is rejected. A "?query" suffix is accepted and merged with the `query` argument, but passing options in `query` is clearer.
queryNoQuery string parameters, e.g. {"$select":"id,subject","$top":"10"}. Values are sent verbatim, so OData operators belong here rather than spliced into `path`.
methodNoHTTP method. Defaults to GET. The write methods are refused unless the server was started with --allow-generic-write, and always under --read-only.
versionNoGraph endpoint. Defaults to the server default (v1.0). "beta" is refused unless the server was started with --beta; beta resources can change without notice.
maxPagesNoHow many pages of a collection to follow via @odata.nextLink, 1-5. Defaults to 1 (no paging). Pages are merged into a single value array.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it returns raw unprojected JSON ('often far more text'), follows @odata.nextLink when maxPages is set, merges pages into a single value array, and rejects absolute URLs. It also discloses that write methods are refused under --read-only. The only minor gap is not detailing error response shapes, but the description adds substantial context beyond the annotations.

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 compact and front-loaded: the core purpose and the key caveat ('returns everything Graph sends, which is often far more text') appear in the first two sentences. Every sentence earns its place, covering when to use, host/path constraints, write-method gating, and response-size control. 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.

Completeness5/5

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

For a generic passthrough tool with 6 parameters, full schema coverage, and no output schema, the description covers everything an agent needs to call it correctly: when to use it, path constraints, method gating, paging behavior, and response-size guidance. The output is raw JSON, which the description states, so no output schema is needed. The only thing not detailed is error handling, but that is minor for a passthrough 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?

Schema description coverage is 100%, so the schema already documents all 6 parameters thoroughly. The description adds meaningful semantics beyond the schema: it explains the host is fixed and path must be relative, that a '?query' suffix in path is merged with the query argument, that query values are sent verbatim, and that body strings are sent as raw bytes for content endpoints. This goes beyond the baseline 3 for full schema coverage.

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 states a specific verb ('Sends an arbitrary request to Microsoft Graph') and resource ('Microsoft Graph'), and explicitly distinguishes itself from purpose-built tools by noting they 'project and trim their results' while this returns raw JSON. This clearly differentiates it from the many sibling tools like mail_list_messages or files_get_item.

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 explicitly says 'Use this only when no purpose-built tool covers the endpoint' and names the alternative class ('the dedicated tools'). It also gives concrete guidance on when write methods are allowed (--allow-generic-write), when beta is refused (--beta), and how to keep responses small ($select, $top, maxPages). This is exemplary usage guidance.

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

graph_schemaInspect a Graph resource shapeA
Read-onlyIdempotent

Fetches one item from a Graph path ($top=1) and reports the property names it carries with their JSON types, plus the @odata.context that names the resource type. Use it before graph_request to learn what $select and $filter can reference. It reports the shape of one real item, so properties that happen to be null on that item are absent from the list, and an empty collection yields no properties at all. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
versionNoGraph endpoint to probe. Defaults to the server default (v1.0).
entityPathYesGraph-relative path to a collection or a single entity, e.g. "/me/messages", "/me/drive/root/children" or "/me". Must begin with "/".

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already establish read-only/idempotent/non-destructive behavior. The description adds meaningful behavioral detail beyond that: it fetches only one item via $top=1, reports the shape of a real item, omits null properties, and returns no properties for an empty collection. This helps set expectations about incomplete results.

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 four sentences and front-loads the core function in the first sentence. The caveats about null properties and empty collections are necessary and earn their place. The final 'Read-only' is redundant with annotations but not harmful.

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 simple two-parameter probe tool with no output schema, the description covers what the tool returns, how it behaves with real data, and when to use it relative to graph_request. Nothing an agent needs to invoke it correctly is missing.

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 schema already documents both parameters. The description mentions the Graph path concept and $top=1 but does not add significant parameter-level meaning beyond what the input schema provides. Baseline 3 is appropriate.

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 names a specific verb and resource: it fetches one item from a Graph path and reports property names, JSON types, and @odata.context. It also explicitly positions itself against graph_request by saying it is meant to be used before that tool to learn what $select and $filter can reference.

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: 'Use it before graph_request to learn what $select and $filter can reference.' This names the alternative tool and the condition for using graph_schema. It does not explicitly state when not to use it, but the intended workflow is clear.

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

mail_create_draftCreate a mail draftA

Creates an unsent draft in the Drafts folder and returns its id and webLink. Nothing is transmitted — this tool cannot send, and there is no companion tool that sends an existing draft, so the user must send it from Outlook (or you can use mail_send instead). Recipients are optional on a draft.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNoCarbon-copy recipients.
toNoPrimary recipients. Optional — a draft may be saved without any.
bccNoBlind carbon-copy recipients.
bodyYesMessage body, in the format given by contentType.
subjectYesSubject line.
contentTypeNoHow to interpret body. "Text" (default) is safest; "HTML" renders markup.Text

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already indicate this is a mutating, non-idempotent, non-destructive operation. The description adds valuable context beyond annotations: nothing is transmitted, the draft is unsent, and the tool returns id and webLink. This meaningfully clarifies the tool's side effects.

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?

Three sentences with no filler. The core behavior is front-loaded, and each sentence adds distinct value: what it creates, what it cannot do, and how recipients behave.

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 create-draft tool with a fully documented schema, the description covers the essential behavioral context: return values, non-sending behavior, and the fallback path. It does not explain error conditions or permissions, but those are not necessary for correct invocation here.

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 schema already documents all six parameters. The description adds the useful note that recipients are optional, but does not need to explain each parameter further. Baseline 3 is appropriate.

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?

States a specific verb and resource: creates an unsent draft in the Drafts folder. It explicitly differentiates itself from mail_send by noting it cannot send, so an agent can distinguish it from the sibling tools without opening schemas.

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?

Provides explicit guidance on when to use this tool versus mail_send, and notes that there is no companion tool to send an existing draft. It also clarifies that recipients are optional, which is directly useful for invocation decisions.

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

mail_delete_messageDelete a messageA
Destructive

Deletes a message. This is a soft delete: the message moves to Deleted Items and the user can restore it from Outlook, but this server has no tool to undo it, so confirm with the user first. Deleting a message already in Deleted Items removes it permanently.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesId of the message to delete.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the destructiveHint annotation, the description discloses critical behavioral details: the operation is a soft delete, the message is recoverable in Outlook, no server-side undo exists, and deleting from Deleted Items is permanent. This gives the agent the full side-effect picture needed to decide safely.

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?

Three short sentences, each carrying essential information: the action, the soft-delete behavior and recoverability, the lack of server-side undo with a confirmation instruction, and the permanent-deletion edge case. No filler or repetition; the most important warning is front-loaded.

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 destructive single-id operation with one documented parameter and no output schema, the description covers the key contextual needs: what happens, what the user can do to recover, what the server cannot do, and when deletion becomes permanent. The agent has enough information to invoke the tool responsibly.

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?

The schema already documents the single required id parameter with full coverage and a clear description ('Id of the message to delete'). The tool description adds no additional parameter-level semantics, so the baseline of 3 is appropriate.

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 opens with 'Deletes a message,' a specific verb and resource that clearly identifies the operation. It further clarifies the exact behavior (soft delete moving the message to Deleted Items), which distinguishes this from sibling tools like mail_move_message or mail_mark_read. The purpose is unambiguous and immediately actionable.

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 practical guidance: confirm with the user first, since the server has no undo tool, and warns that deleting a message already in Deleted Items is permanent. This establishes when caution is required, though it does not explicitly compare to alternatives like mail_move_message or state when not to use this tool.

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

mail_forwardForward a messageA
Destructive

Forwards an existing message immediately, attachments included — it does not create a draft and there is no undo, so confirm the recipients with the user first. Your comment, if any, is placed above the forwarded content. Sending needs the Mail.Send permission, which is separate from read/write access.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesId of the message being forwarded.
toYesWho to forward it to. At least one is required.
commentNoOptional note above the forwarded message.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already mark destructive and non-idempotent, and the description adds meaningful behavioral detail: immediate sending, no undo, attachments included, comment placement, and the separate Mail.Send permission requirement. No contradiction with annotations.

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?

Three tight sentences front-load the core behavior and warning, then add only necessary context about comment placement and permissions. Every clause contributes actionable information with no filler.

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 3-parameter tool with no output schema, the description covers what the action does, side effects, safety guidance, and required permission. An agent has enough to decide whether to call it and what to tell the user before invoking.

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 schema already documents id, to, and comment. The description adds only that attachments are included and that no undo exists, which is behavioral context rather than new parameter semantics; the comment placement detail essentially repeats the schema description.

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?

States a specific verb, resource, and mode ('Forwards an existing message immediately, attachments included') and explicitly distinguishes itself from draft creation. An agent can reliably tell this apart from mail_send, mail_create_draft, and mail_reply.

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?

Gives clear context: the tool acts immediately, includes attachments, and is not a draft; it also tells the agent to confirm recipients with the user first because there is no undo. It does not explicitly name alternative tools or state 'use X instead', but the actionable guidance is strong.

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

mail_get_messageGet one mail messageA
Read-onlyIdempotent

Returns one message with its body plus sender, recipients, timestamps, importance, conversationId and webLink. The body defaults to plain text and is capped at 8000 characters; raise maxBodyChars for a long thread, or pass format:"preview" to skip the body when you only need to identify the message. Attachment contents are never included — use mail_list_attachments. Reading a message here does not mark it read; use mail_mark_read for that.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe message id, as returned by mail_list_messages.
formatNoHow to return the body. "text" (default) asks Graph for plain text and strips any HTML that comes back anyway. "html" returns the raw markup, which costs several times more tokens. "preview" skips the body entirely and returns only the 255-character bodyPreview — use it when you just need to confirm you have the right message.text
maxBodyCharsNoCharacter budget for the body. Defaults to 8000, which covers most messages. The server's own output cap still applies on top of this.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is known. The description adds valuable behavioral context beyond annotations: the body caps at 8000 characters (with maxBodyChars override), preview skips the body, attachment contents are never included, and reading does not change read state. No contradictions with annotations.

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?

Three sentences with zero filler: the first fronts the core return value, the second covers body format and size, and the third handles attachments and read-state side effects. Every sentence earns its place, and the most important information (what the tool returns) comes first.

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 1-required-parameter tool with no output schema, the description covers all essential aspects: return fields, body format and truncation, the preview mode, exclusion of attachments, and the lack of a read-mark side effect. It also names the relevant sibling tools for follow-up actions. Nothing an agent needs to call this tool correctly is missing.

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 100% and the schema already documents all three parameters well. The description adds practical guidance beyond the schema by explaining when to raise maxBodyChars ('for a long thread') and when to use format:'preview' ('when you only need to identify the message'), which helps the agent choose correct values in context. This exceeds the baseline of 3 for full schema coverage.

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 states a specific verb ('Returns') and resource ('one message') and enumerates the returned fields (body, sender, recipients, timestamps, importance, conversationId, webLink). It clearly differentiates from siblings by noting attachments are excluded and reading does not mark as read, so an agent can distinguish it from mail_list_messages, mail_list_attachments, and mail_mark_read without opening schemas.

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 and when-not-to-use guidance: it tells the agent to use mail_list_attachments when attachment contents are needed, mail_mark_read to mark as read, and format:'preview' when only identifying the message. These are direct routing instructions to sibling tools, leaving nothing to inference.

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

mail_list_attachmentsList message attachmentsA
Read-onlyIdempotent

Lists attachment metadata for one message — id, name, contentType, size in bytes, whether it is inline, and its kind (file, item, or reference) — 20 per call by default. File contents are deliberately never returned: a single attachment would exceed the output budget many times over. Check hasAttachments on the message first; inline images count as attachments, so a message with no visible attachment can still list several.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe message id, as returned by mail_list_messages.
topNoHow many attachments to return. Defaults to 20.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the annotations (readOnly, idempotent, non-destructive), the description discloses that file contents are never returned and explains why (output budget), plus notes the default limit of 20 per call. This adds valuable behavioral context that the annotations do not cover, with no contradictions.

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 well-structured, front-loading the main purpose and fields, then adding the important caveats about file contents and inline images. It is slightly verbose with the output budget explanation, but every sentence earns its place by conveying essential behavior.

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 list tool with no output schema, the description fully explains the return metadata, pagination default, and a necessary prerequisite. It is complete enough for an agent to call the tool correctly without additional context.

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?

The schema already describes both parameters (id and top) with full coverage (100%). The description reinforces the default of 20 per call but does not add new semantic meaning beyond the schema. Baseline of 3 is appropriate when the schema carries the parameter documentation.

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 action ('Lists attachment metadata for one message') and enumerates the specific fields returned (id, name, contentType, size, inline flag, kind). It is unambiguous and distinguishes itself from other mail tools by scoping to a single message's attachments.

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 a clear usage guideline: 'Check hasAttachments on the message first' and warns that inline images count as attachments, which is a practical caveat. It doesn't explicitly mention alternatives or when not to use it, but the prerequisite and the clarification about inline images offer sufficient guidance for typical use.

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

mail_list_foldersList mail foldersA
Read-onlyIdempotent

Lists the top-level Outlook mail folders with their ids, unread counts and total counts, 50 per call by default. Pass includeChildren to also get one level of subfolders. Only top-level folders are returned otherwise, so a nested folder needs a second call. Use an id from here as folderId in mail_list_messages, though the well-known names (inbox, archive, sentitems) work there without looking anything up.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoHow many top-level folders to return. Defaults to 50.
includeChildrenNoAlso return one level of subfolders under each top-level folder. Nesting deeper than one level needs a second call with that folder as the parent.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, the description discloses pagination behavior (50 per call by default), the nesting limitation (only one level with includeChildren), and the requirement for a second call otherwise. It also reveals the output fields (ids, counts) and cross-tool contract (folderId reuse), giving an agent a clear picture of runtime behavior without needing to inspect schemas.

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?

Three sentences, each carrying distinct information: what is returned and default page size, how to expand nesting, and how to use the result with a sibling tool. The most critical facts are front-loaded, and there is no filler or redundancy.

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 lack of an output schema, the description names the fields returned (ids, unread counts, total counts), states the default pagination, explains the nesting behavior, and points to the dependent sibling – everything an agent needs to decide whether to call it and to interpret the result. The only minor omission is explicit error/edge-case handling, but that is not essential for a simple list tool with strong input schema coverage.

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?

The input schema already provides high-quality descriptions for both parameters (top default/range, includeChildren behavior), and the description's parameter mentions largely mirror that. The description adds minor value by reinforcing the 50-default and the second-call nesting nuance, but it does not meaningfully extend parameter meaning beyond the schema. Baseline 3 is appropriate.

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 (lists), the resource (top-level Outlook mail folders), and the specific fields returned (ids, unread counts, total counts). It also distinguishes this tool from mail_list_messages by explaining how folder IDs feed into that sibling, avoiding ambiguity about which tool handles folders vs messages.

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 gives explicit usage context: it clarifies that only top-level folders are returned by default, that includeChildren adds one subfolder level, and that a nested folder requires a second call. It also directly names the sibling tool (mail_list_messages) and explains when to use it with well-known folder names, providing a clear when-to-use and when-not-to-use alternative.

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

mail_list_messagesList mail messagesA
Read-onlyIdempotent

Lists Outlook messages newest-first, 10 per call by default (50 max), as a compact projection: id, subject, from, toRecipients, receivedDateTime, isRead, hasAttachments, bodyPreview and webLink. Bodies are never included — bodyPreview is Graph's first 255 characters, and mail_get_message returns the rest. Page with skip. Note that Exchange rejects some filter/orderby combinations with "The restriction or sort order is too complex"; when that happens, drop orderby or sort on the same property you filtered.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoHow many messages to return. Defaults to 10; 50 is the ceiling.
skipNoMessages to skip before returning results. Use it to page: 0, then 10, then 20.
filterNoRaw OData $filter, e.g. "importance eq 'high'" or "receivedDateTime ge 2026-01-01T00:00:00Z". Combined with unreadOnly using and.
selectNoGraph message property names to return instead of the default projection, e.g. ["subject","importance","conversationId"]. id is always included. Do not ask for "body" here — use mail_get_message.
orderbyNoSort order. Defaults to "receivedDateTime desc" (newest first).receivedDateTime desc
folderIdNoRestrict to one mail folder. Accepts a folder id from mail_list_folders or a well-known name: inbox, drafts, sentitems, deleteditems, archive, junkemail, outbox, clutter, conversationhistory, scheduled. Omit to list the whole mailbox.
unreadOnlyNoReturn only unread messages (adds "isRead eq false" to the filter).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, so the description doesn't need to repeat safety. It adds valuable behavioral context: bodies are never included, bodyPreview is only the first 255 characters, pagination uses skip, and it warns about Exchange filter/orderby restrictions with a concrete workaround. This goes beyond the annotations without contradicting them.

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 concise, front-loaded with the core behavior, then covers body handling, pagination, and a caveat in a logical order. Every sentence adds value; there is 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.

Completeness5/5

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

For a read-only listing tool with seven optional parameters and no output schema, the description is remarkably complete. It covers the default projection, how to retrieve full bodies (delegating to mail_get_message), pagination mechanics, folder scoping (including well-known names), and a known error scenario with a workaround. An agent has everything needed to call it correctly.

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 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining the compact projection, that bodyPreview is a preview, and that bodies are intentionally excluded. It also contextualizes the 'skip' parameter for paging and hints at the filter/orderby interplay, which enriches 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 verb (Lists), the resource (Outlook messages), and specific behavioral details (newest-first, 10 per call, compact projection). It explicitly distinguishes itself from mail_get_message by noting bodies are never included and that mail_get_message returns the rest, effectively differentiating from a key sibling.

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: it lists messages in a folder or mailbox with optional filtering and paging. It explicitly points to mail_get_message for full body content, which serves as an alternative. However, it does not explicitly contrast with mail_search_messages or other listing tools, so the when-not-to-use guidance is implicit rather than explicit.

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

mail_mark_readMark a message read or unreadA
Idempotent

Sets the read flag on one message. Defaults to marking it read; pass isRead:false to mark it unread again. Reading a message with mail_get_message does not change this flag, so unread counts stay accurate until you call this.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesId of the message to flag.
isReadNoTrue marks it read, false marks it unread.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds meaningful behavioral context: the default is read, isRead:false flips it back, and reading via mail_get_message has no effect on the flag, which helps the agent understand side effects.

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 with no filler. The core action is front-loaded, the optional parameter is explained clearly, and the relationship to mail_get_message is stated in one efficient clause.

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 simple two-parameter mutation with annotations covering safety and idempotency, the description provides everything needed to invoke it correctly. No output schema is present, so explaining return values is not required.

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%, so the schema already documents both parameters and the default for isRead. The description restates the default behavior but adds little beyond the schema, making a baseline 3 appropriate.

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 uses a specific verb and resource: 'Sets the read flag on one message.' It clearly distinguishes the tool from mail_get_message, mail_list_messages, and mail_delete_message by focusing on the read-flag mutation.

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 explains the default behavior and how to invert it with isRead:false. It also gives useful context by noting that mail_get_message does not alter the flag, implying this tool is the way to change read state, though it does not explicitly list exclusions or alternatives.

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

mail_move_messageMove a message to a folderA
Idempotent

Moves a message to another mail folder. The move assigns the message a NEW id — the old one stops resolving, so use the id returned here for any follow-up call. destinationId accepts a folder id from mail_list_folders or a well-known name such as archive or deleteditems; moving to deleteditems is how you soft-delete without mail_delete_message.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesId of the message to move.
destinationIdYesTarget folder id from mail_list_folders, or a well-known name: inbox, archive, deleteditems, junkemail, drafts, sentitems.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only indicate readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds critical behavioral disclosure not covered by annotations: the move reassigns a new id, invalidating the old one and requiring the returned id for follow-ups. It also clarifies the soft-delete semantics of the deleteditems destination. This is valuable, non-obvious behavior that an agent must know.

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 three sentences of high information density. It front-loads the core action, then the most critical behavioral caveat (new id), then the parameter-specific guidance. Every sentence adds value, and there is no redundant fluff or restating of the tool's name or title.

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 simplicity (2 simple params, no output schema, no nested objects), the description covers all essential contexts: the action, the id reassignment side effect, the referral to mail_list_folders, and the soft-delete use case. An agent has everything needed to invoke it correctly and interpret the result. No critical information is missing.

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 100%, so both id and destinationId are documented. The description adds meaning for destinationId by referencing mail_list_folders and the soft-delete nuance, which helps an agent choose the right value. For id, it explains the consequence (new id) but that's more about output than the parameter itself. It supplements the schema meaningfully without repeating it, justifying above-baseline scoring.

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 opens with a specific verb+resource: 'Moves a message to another mail folder.' It clearly distinguishes this from sibling tools like mail_delete_message (a delete, not a move) and mail_mark_read (a state change). The unique consequence of the move—the message receiving a NEW id—is stated up front, further differentiating it.

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 on when to use this tool: it references mail_list_folders for obtaining destinationId and explicitly explains that 'moving to deleteditems is how you soft-delete without mail_delete_message.' This provides a usage nuance relative to the delete tool, though it doesn't explicitly enumerate all alternative tools or exclusions. Overall, it offers solid guidance beyond the schema.

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

mail_replyReply to a messageA
Destructive

Sends a reply to an existing message immediately — it does not create a draft, and there is no undo, so confirm the text with the user first. Your comment is placed above the quoted original as plain text; Graph builds the subject and recipients itself. replyAll includes every original recipient. Sending needs the Mail.Send permission, which is separate from read/write access.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesId of the message being replied to.
commentYesYour reply text. It is placed above the quoted original as plain text.
replyAllNoReply to every recipient rather than only the sender. Defaults to false.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations declare destructiveHint=true, and the description adds significant context: immediate send, no undo, and the Mail.Send permission requirement. It also explains how the comment is placed above the quoted original and that Graph builds subject and recipients. This goes beyond the annotations and covers key behavioral traits, though it doesn't mention potential failures or idempotency nuances (already covered by idempotentHint=false).

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 three sentences with no filler. The most critical caveat (immediate send, no undo, confirm first) is front-loaded, followed by formatting details and permission requirements. Every sentence earns its place and the structure is logical and efficient.

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 3-parameter tool with no output schema, the description covers the essential aspects: behavior, permission, formatting, and recipient semantics. It lacks explicit mention of return values or error handling, but these are not critical for a basic reply action. The description is sufficiently complete for an agent to call the tool correctly.

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 100%, so baseline is 3. The description adds value by explaining that the comment is placed above the quoted original as plain text, and that replyAll includes every original recipient. This clarifies the semantics of comment and replyAll beyond their schema descriptions. The id parameter is self-explanatory and needs no extra context.

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 sends a reply to an existing message immediately, and explicitly contrasts with creating a draft. It names the specific resource (message) and the action (reply), making it distinct from siblings like mail_create_draft and mail_send. The verb 'sends' is specific and unambiguous.

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 usage guidance by stating it sends immediately, has no undo, and requires confirmation with the user first. It implies when to use this tool (when an immediate send is desired) and contrasts with draft creation. However, it does not explicitly name alternative sibling tools (e.g., mail_create_draft) as the recommended path for draft scenarios, leaving some inference to the agent.

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

mail_search_messagesSearch mail messagesA
Read-onlyIdempotent

Finds messages by text, returning the same compact projection as mail_list_messages, 10 per call by default (50 max). Two modes, because Graph will not combine them: with no date range it uses $search, a relevance-ranked KQL search over subject, body and participants (results are NOT in date order, and $search supports no date syntax). Passing after or before switches to $filter on receivedDateTime, which sorts newest-first but can only match query as a substring of the subject — body text is not searched in that mode. The response reports which mode ran. To search body text within a period, search first and filter the dates yourself.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoOnly messages addressed to this exact address.
topNoHow many messages to return. Defaults to 10; 50 is the ceiling.
fromNoOnly messages sent by this exact address.
afterNoOnly messages received at or after this ISO-8601 date or datetime, e.g. "2026-01-01" or "2026-01-01T09:00:00Z". A bare date starts at 00:00:00Z. Supplying this switches the tool to $filter mode.
queryYesWords to look for. Without a date range this is a KQL search across subject, body, and participants, so "subject:budget" or "quarterly review" both work. With after/before it degrades to a subject substring match — see the tool description.
beforeNoOnly messages received at or before this ISO-8601 date or datetime. A bare date ends at 23:59:59Z that day. Supplying this switches the tool to $filter mode.
hasAttachmentsNoOnly messages with (or without) attachments.

TDQS

A5/5.0
Behavior5/5

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

Annotations already cover readOnly, idempotent, and non-destructive behavior, so the burden is on behavior beyond that. The description adds high-value traits: results are not in date order in $search mode, $search supports no date syntax, $filter only matches subject substrings, and the response reports which mode ran. This is substantial behavioral disclosure that structured fields cannot convey.

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 dense but every clause earns its place: projection, pagination, mode selection, ordering, and a workaround for the body-text-with-date limitation. The most important scoping fact (text search) is front-loaded, and there is no filler or restatement of obvious annotation data.

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 search tool with no output schema, the description tells the agent what projection to expect (via mail_list_messages), the default page size and cap, the mode behavior, and how to compensate for mode limitations. Nothing an agent needs to invoke it correctly or interpret its response is missing.

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 schema coverage is 100%, the description adds meaning the schema alone cannot: after and before are not just date filters but mode switches, and query changes semantics depending on whether a date range is present. This directly affects correct invocation and interpretation of results, going well beyond the schema's property-level descriptions.

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 opens with a specific verb and resource: "Finds messages by text," and immediately distinguishes it from mail_list_messages via the "same compact projection" reference. The two-mode explanation further separates it from both a plain list operation and a generic search, so an agent can select it confidently.

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 explicitly states when to use each mode: no date range triggers $search, while passing after/before triggers $filter, and it explains the trade-offs of each. It even gives a concrete fallback strategy for searching body text within a period, which is exactly the kind of actionable usage guidance an agent needs.

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

mail_sendSend mailA
Destructive

Sends a message immediately from the signed-in mailbox — there is no undo and no confirmation step, so confirm the recipients and text with the user first. Graph returns no message id for a send: if you need one, use mail_create_draft instead. A copy lands in Sent Items unless saveToSentItems is false. Sending needs the Mail.Send permission, which is separate from read/write access.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNoCarbon-copy recipients.
toYesPrimary recipients. At least one is required.
bccNoBlind carbon-copy recipients.
bodyYesMessage body, in the format given by contentType.
subjectYesSubject line.
contentTypeNoHow to interpret body. "Text" (default) is safest; "HTML" renders markup.Text
saveToSentItemsNoKeep a copy in Sent Items. Defaults to true.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (non-read-only, non-idempotent, destructive), the description discloses critical behavior: no undo or confirmation step, no returned message id, a copy in Sent Items unless saveToSentItems is false, and a specific permission requirement. This goes well beyond what the annotations alone convey and gives the agent a realistic model of the operation's consequences.

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 four sentences, front-loads the core behavior first, and then adds the most decision-relevant caveats (no undo, no id, Sent Items behavior, permission). Every sentence earns its place; there is no filler or repetition of schema content.

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 send-message tool with no output schema, the description covers the operational essentials: side effects, failure-relevant behavior, permission requirements, and an explicit sibling alternative. The input schema handles parameter details, and the annotations handle the low-level safety profile, so nothing an agent needs to call this tool correctly is missing.

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 input schema fully documents every parameter. The description adds only modest semantic color, such as the saveToSentItems behavior and the overall emphasis on confirming recipients, but it does not materially extend the schema's parameter explanations. Baseline 3 is appropriate.

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 states a specific action and resource: 'Sends a message immediately from the signed-in mailbox.' It also distinguishes itself from the sibling mail_create_draft by noting that a send returns no message id and that creating a draft is the alternative. This makes the tool's purpose unambiguous and clearly differentiated.

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 explicitly tells the agent when to use this tool and when not to: confirm recipients and text because there is no undo, and use mail_create_draft when a message id is needed. It also warns about the separate Mail.Send permission requirement, giving practical usage context beyond a simple 'send a message' statement.

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

me_get_mailbox_settingsGet my mailbox settingsA
Read-onlyIdempotent

Returns the signed-in user's Outlook mailbox configuration: time zone, date and time format, locale, working hours, and the automatic-reply (out-of-office) setting. Automatic-reply bodies are HTML in Graph and come back stripped to plain text and truncated to replyBodyChars. The scheduled start and end times are only meaningful when status is "scheduled" — when status is "alwaysEnabled" or "disabled" they are stale leftovers from the last schedule. Accounts with no Exchange Online mailbox fail with 404 MailboxNotEnabledForRESTAPI.

ParametersJSON Schema
NameRequiredDescriptionDefault
replyBodyCharsNoMaximum characters of each automatic-reply message to return after HTML is stripped. Use 0 to omit the reply bodies entirely and keep only the status and schedule.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already mark the tool read-only and idempotent, and the description adds substantial behavior beyond that: reply bodies are stripped to plain text and truncated to replyBodyChars, scheduled start/end times are only meaningful when status is 'scheduled,' and missing mailboxes surface as a specific 404. This is exactly the contextual detail an agent needs.

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?

Four sentences, each with a distinct job: scope, reply-body behavior, schedule semantics, and error condition. The most decision-relevant information is front-loaded in the first sentence, with no filler.

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?

Even without an output schema, the description covers what is returned, the only parameter's effect, edge-case semantics for scheduled replies, and the failure mode. Nothing an agent needs to call and interpret this tool correctly is omitted.

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%, so replyBodyChars is already fully documented in the schema, including the 0-omits-bodies behavior. The description adds that bodies are 'HTML in Graph' and are truncated, but this largely restates the schema's semantics rather than providing new meaning.

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 opens with a specific verb-plus-resource phrase, 'Returns the signed-in user's Outlook mailbox configuration,' and enumerates the exact fields returned. This makes the tool distinguishable from sibling tools like me_get_profile or mail_get_message without inspecting the schema.

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 clearly establishes when the tool applies: signed-in user's mailbox settings. It also flags a boundary case with 'Accounts with no Exchange Online mailbox fail with 404 MailboxNotEnabledForRESTAPI,' but it does not explicitly name sibling alternatives or say when not to use this tool.

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

me_get_profileGet my profileA
Read-onlyIdempotent

Returns the signed-in user's own Entra ID profile from /me: by default id, displayName, mail, userPrincipalName, jobTitle, officeLocation and preferredLanguage. Pass select to ask for different properties instead. Properties Graph returns as null or empty are omitted, so a missing key means "not set" rather than "not requested". mail is null for accounts without an Exchange mailbox and personal Microsoft accounts leave the work fields empty — userPrincipalName is the identifier that is always present.

ParametersJSON Schema
NameRequiredDescriptionDefault
selectNoGraph `user` property names to return instead of the default set, e.g. ["displayName","department","mobilePhone"]. Bare property names only: navigation paths such as "manager/displayName" and any other OData expression are rejected. Omit for the compact default projection.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, the description discloses important behavioral nuances: null/empty properties are omitted, 'mail' is null for accounts without Exchange mailboxes, personal accounts return empty work fields, and userPrincipalName is always present. This adds meaningful runtime expectations the schema cannot convey.

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 compact and every sentence earns its place: default set, how to override, omission semantics, and field-specific edge cases. It is front-loaded with the core purpose and avoids repetition or fluff.

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?

With only one optional parameter, no output schema, and strong annotations, the description fully covers what an agent needs to call it correctly: default projection, selection behavior, and interpretation of absent keys. No critical operational detail is missing.

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 schema already thoroughly describes the select parameter, its format, examples, validation, and default behavior. The description's 'Pass select to ask for different properties instead' is helpful but does not substantially exceed what the schema already documents.

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 opens with a specific verb and resource: 'Returns the signed-in user's own Entra ID profile from /me'. It clearly scopes the operation to the caller's own profile intest and enumerates the default fields, making it easy to distinguish from sibling tools like me_get_mailbox_settings.

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: this is the tool for the signed-in user's own profile. It does not explicitly name alternatives, but the '/me' scoping and default property list are enough to signal when it is appropriate. No exclusion guidance is provided, so slightly 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.

search_querySearch Microsoft 365A
Read-onlyIdempotent

Runs a relevance-ranked Microsoft Search query across Microsoft 365 and returns a flattened list of hits, each with its rank, a text summary and the resource's id, name or subject, web URL and last-modified time. Defaults to 10 hits per entity-type group over ['message','driveItem']; page with from. Traps: chatMessage cannot be combined with other entity types, so a mixed request is split into two calls and merged, and its hits ignore fields; searching driveItem, listItem or site needs Sites.Read.All, event needs Calendars.Read and chatMessage needs Chat.Read, so enable the matching tool group or the split for that type fails on its own while the rest still return; results are ranked, not sorted by date, and freshly changed items may not be indexed yet. This is read-only despite using POST.

ParametersJSON Schema
NameRequiredDescriptionDefault
fromNoZero-based offset of the first hit to return; use it to page. Defaults to 0.
sizeNoMaximum hits to return per entity-type group. Defaults to 10, capped at 25.
queryYesThe search terms, in Microsoft Search KQL. Free text works ("quarterly budget"), as do property restrictions such as "subject:budget", "from:sara@contoso.com", "filetype:pptx" and "lastModifiedTime>=2026-01-01", combined with AND/OR/NOT.
fieldsNoExtra resource properties to retrieve and include on each hit, for example ["from","importance"] or a SharePoint managed property. Ignored for chatMessage, which does not support field selection.
entityTypesNoWhich kinds of content to search. Defaults to ['message','driveItem'] (Outlook mail plus OneDrive/SharePoint files).

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already mark the tool as read-only, idempotent, and non-destructive, but the description adds substantial behavior beyond that: results are ranked not date-sorted, fresh items may not be indexed, chatMessage cannot combine with other types, and mixed requests are split into two calls. It also explains the read-only nature despite POST, which directly complements the annotation.

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 dense but well front-loaded with the main purpose and return shape, then defaults, then traps. Every sentence adds necessary information, though the long trap section is a single block and could benefit from clearer bullet structure.

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 complex tool with multiple entity types, permissions, paging, and splitting behavior, the description covers all necessary operational details: defaults, paging, per-type permission needs, result ordering caveats, and the read-only POST behavior. Even without an output schema, it enumerates the returned fields.

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 schema coverage is 100%, the description meaningfully extends parameter understanding with KQL syntax examples, the per-entity-type-group meaning of size, paging via from, and the chatMessage exception for fields. This goes well beyond the schema's property descriptions.

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 states a specific verb and resource: it runs a relevance-ranked Microsoft Search query across Microsoft 365 and returns a flattened list of hits with concrete fields. It distinguishes itself from more scoped sibling tools by emphasizing cross-Microsoft-365 coverage over multiple entity types.

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 on defaults, paging, entity-type groups, and permission requirements, making it evident this is the cross-entity search tool. It does not explicitly name alternatives like mail_search_messages or files_search for single-entity searches, so it falls just short of fully explicit when-not-to-use guidance.

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

todo_complete_taskComplete a To Do taskA
Idempotent

Marks a To Do task completed by patching its status to 'completed', and returns the updated task including the completedDateTime Graph stamps on it. Recurring tasks are rolled forward by the service rather than closed outright.

ParametersJSON Schema
NameRequiredDescriptionDefault
listIdYesId of the To Do list that holds the task.
taskIdYesId of the task to mark completed.

TDQS

A4.3/5.0
Behavior5/5

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

The description goes beyond the annotations by clarifying that the operation patches status, that the updated task with completedDateTime stamps is returned, and that recurring tasks are rolled forward rather than closed. This adds meaningful behavioral context beyond readOnlyHint/idempotentHint/destructiveHint.

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 with no filler. The primary action and return value are front-loaded, and the second sentence adds a valuable edge case about recurring tasks without bloat.

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 low-complexity mutation with two simple parametersley and no output schema, the description covers the action, the return value, and the notable recurring-task behavior. Nothing critical is missing for an agent to call this 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 100%, and both parameters are simple string IDs with clear descriptions. The description does not add parameter-specific details, but the schema already documents the parameters adequately, so baseline 3 is appropriate.

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 uses a specific verb ('Marks'), a clear resource ('a To Do task'), and an explicit outcome ('completed by patching its status to completed'). It also distinguishes this completion action from sibling tools like todo_update_task and todo_delete_task by narrowing the operation to marking complete, not generic updating.

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 intended use is implied: use this tool when you want to complete a To Do task. However, the description does not explicitly state when not to use it or mention alternatives such as todo_update_task for broader status changes, leaving some routing to inference.

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

todo_create_listCreate a To Do listA

Creates a new To Do list and returns its id and display name. Display names are not required to be unique, so check todo_list_lists first if the user expects one list per name.

ParametersJSON Schema
NameRequiredDescriptionDefault
displayNameYesName of the new To Do list, as it appears in the To Do apps.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already indicate readOnly=false and idempotent=false, and the description adds the important behavioral detail that display names are not unique. It also clarifies the return values, which are not in the schema or annotations. No contradiction exists.

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 concise sentences with no filler. The core action is front-loaded, and the important uniqueness caveat is included without redundancy.

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 simple one-parameter creation tool with no output schema, the description is complete: it states what is created, what is returned, and the key behavioral caveat about duplicate names. Nothing essential is missing.

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?

The schema has 100% coverage for the single displayName parameter, including a helpful description. The tool description adds little beyond the schema, so the baseline score of 3 applies.

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 creates a new To Do list and returns its id and display name, using a specific verb and resource. It is easily distinguished from sibling tools like todo_list_lists and todo_create_task.

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 explicit guidance to check todo_list_lists first when uniqueness is expected, which is a useful pre-condition. It does not fully enumerate when to use this tool versus alternatives, but the context is clear for a create operation.

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

todo_create_taskCreate a To Do taskA

Creates a task in a To Do list and returns the created task. Only title is required. Due and reminder values are sent as Graph dateTimeTimeZone objects using the timeZone argument (default UTC), and a date-only dueDateTime becomes midnight, matching how the To Do apps store all-day due dates. Supplying reminderDateTime also switches the reminder on, since Graph leaves isReminderOn false otherwise.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNoPlain-text notes stored on the task body.
titleYesTask title. This is the only required task field.
listIdYesId of the To Do list to create the task in.
timeZoneNoTime zone the due and reminder wall-clock times are expressed in, e.g. 'UTC' or 'Pacific Standard Time'. Ignored for values that already carry a UTC offset.UTC
importanceNoTask importance. Graph defaults to normal.
dueDateTimeNoDue date, '2026-09-10' or a full ISO 8601 date-time. Use 'YYYY-MM-DD' or a full ISO 8601 date-time such as '2026-09-10T14:30:00'.
reminderDateTimeNoReminder date-time. Supplying this also turns the reminder on.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations declare this as a write operation (readOnlyHint=false) and non-idempotent. The description adds value by disclosing specifics: it returns the created task, normalizes date-only due dates to midnight, and turns on reminder when reminderDateTime is supplied because Graph defaults isReminderOn to false. These behaviors are not apparent from the schema or annotations alone.

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 concisely structured, leading with the primary action and return value, then adding essential details about required fields and date handling. Each sentence contributes value without redundancy.

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?

Given the tool's complexity (7 params, date-time nuances, no output schema), the description covers the critical edge cases (timezone handling, all-day dates, reminder enabling) and clearly states the return of the created task. It is sufficient for an agent to invoke correctly, though it omits potential error conditions and auth details, which are not always required.

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 covers all parameters with descriptions, so baseline is 3. The description adds nuance: explains that due/reminder values are converted to Graph dateTimeTimeZone using the timeZone argument, and clarifies the midnight behavior for all-day dates. This goes beyond the schema's notes, enhancing the agent's 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 states a specific verb ('Creates'), a resource ('task in a To Do list'), and a return value ('returns the created task'). It clearly distinguishes from sibling tools like todo_update_task and todo_delete_task by naming the create action. No ambiguity.

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 guidance on required fields ('Only title is required') and explains the handling of due and reminder dates, which is essential for correct usage. However, it does not explicitly contrast with alternative tools (e.g., todo_update_task) or state when not to use it. Still, the context is strong.

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

todo_delete_taskDelete a To Do taskA
Destructive

Deletes a To Do task permanently and returns a confirmation. There is no recycle bin for To Do tasks, so prefer todo_complete_task when the user only wants it out of the way.

ParametersJSON Schema
NameRequiredDescriptionDefault
listIdYesId of the To Do list that holds the task.
taskIdYesId of the task to delete permanently.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already indicate destructiveHint: true, but the description adds critical context: 'permanently' and 'There is no recycle bin for To Do tasks.' This reinforces the irreversibility and gives the agent a stronger reason to prefer the completion tool when appropriate. It also notes the tool returns a confirmation.

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 with no filler. The core action and permanence are front-loaded, followed by the alternative usage guidance. Every word earns its place.

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 simple delete operation with two straightforward parameters, the description fully covers what it does, the irreversibility, the return of a confirmation, and when to choose an alternative. Nothing essential is missing.

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%, and both parameters have clear descriptions (listId and taskId). The tool description adds no additional parameter semantics beyond the schema, so the baseline of 3 is appropriate.

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 (deletes a To Do task), the resource (To Do task), and the key characteristic (permanently). It also differentiates from the sibling todo_complete_task by explicitly noting the alternative for non-permanent removal, making the purpose unambiguous.

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 explicitly instructs when to use this tool versus the alternative: 'prefer todo_complete_task when the user only wants it out of the way.' This direct guidance leaves no ambiguity about selection.

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

todo_get_taskGet a To Do taskA
Read-onlyIdempotent

Reads one To Do task in full: title, status, importance, reminder state, start/due/completed times, categories and the notes body (truncated). Needs both the list id and the task id, which come from todo_list_lists and todo_list_tasks.

ParametersJSON Schema
NameRequiredDescriptionDefault
listIdYesId of the To Do list that holds the task.
taskIdYesId of the task, as returned by todo_list_tasks.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety. The description adds a key behavioral detail beyond annotations: the notes body is truncated, informing the agent that the returned content is not fully complete. This is valuable context for a read operation.

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, no fluff. The core purpose is front-loaded, followed by a precise list of returned fields and the ID prerequisite. Every word earns its place.

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 simple read tool with two parameters, full schema coverage, and annotations covering safety, the description is complete. It conveys the returned fields, warns about truncation, and explains the dependency on sibling tool outputs. No gap that an agent needs to call it correctly.

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 100%, so both parameters are already documented with descriptions. The description adds source information—that the IDs come from specific sibling tools—which the schema does not provide, enhancing the agent's ability to fill parameters correctly.

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 states a specific verb ('Reads') and resource ('one To Do task') and enumerates the exact fields returned (title, status, importance, etc.), making it clear this is a single-task fetch distinct from todo_list_tasks and the mutation tools.

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 says the tool needs both listId and taskId, and tells the agent where those come from (todo_list_lists and todo_list_tasks). While it doesn't explicitly name when not to use it, the prerequisite and purpose make the usage context evident.

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

todo_list_listsList To Do listsA
Read-onlyIdempotent

Lists the signed-in user's Microsoft To Do lists with their id, display name and well-known name (for example defaultList for the built-in Tasks list). Follows up to three pages, which covers any realistic number of lists. Use the returned id as listId for every other todo tool; To Do is delegated-only, so these are always the caller's own lists.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, the description discloses pagination behavior ('Follows up to three pages'), the delegated-only ownership model, and the output fields. This adds meaningful behavioral context an agent needs before calling.

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?

Three sentences, each earning its place: purpose and output, pagination behavior, and cross-tool usage. Information is front-loaded and there is no filler.

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 parameterless list tool with no output schema, the description is complete: it states what is returned, how many pages are followed, and how the result should be used with other tools. No critical information is missing.

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, so there is no parameter semantics to explain. The description appropriately focuses on output fields and usage instead, matching the baseline for a no-parameter tool.

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 uses a specific verb ('Lists') and resource ('signed-in user's Microsoft To Do lists'), and names the exact returned fields (id, display name, well-known name). It clearly distinguishes from sibling tools like todo_list_tasks by focusing on lists rather than tasks.

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 explicit usage guidance: 'Use the returned id as listId for every other todo tool.' It also clarifies scope with 'these are always the caller's own lists.' It does not explicitly name alternatives, but the list-vs-task distinction is clear from context.

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

todo_list_tasksList To Do tasksA
Read-onlyIdempotent

Lists tasks in one To Do list, returning id, title, status, importance, due and reminder times and a short body preview per task, plus count and nextLink when more pages exist. Page size defaults to 50. Completed tasks are excluded unless includeCompleted is true. To Do tasks do not support $search: narrow with filter instead, and note that dueDateTime is a complex type, so a date filter reads dueDateTime/dateTime ge '2026-01-01T00:00:00'.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of tasks to return in this page. Defaults to 50.
filterNoRaw OData $filter, ANDed with the completed-task filter. Example: "importance eq 'high'" or "dueDateTime/dateTime ge '2026-01-01T00:00:00'".
listIdYesId of the To Do list, as returned by todo_list_lists.
includeCompletedNoInclude completed tasks. Defaults to false, which adds status ne 'completed' to the filter.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already cover readOnly, idempotent, and non-destructive hints. The description adds value by disclosing pagination (count and nextLink), page size default (50), and the default exclusion of completed tasks. It does not contradict annotations, and the added context enriches the behavioral picture without requiring the agent to infer from schema alone.

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 every sentence earns its place: return fields, pagination, defaults, exclusions, and filter guidance. It is front-loaded with the core purpose and each subsequent sentence adds a distinct useful detail. No fluff or redundancy.

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 list operation with no output schema, the description covers all essential aspects: the exact data returned, pagination details, default page size, completion filtering, and a critical filter caveat about complex types. An agent has everything needed to call this tool correctly without consulting additional documentation.

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 description coverage is 100%, so baseline is 3. The description goes beyond by clarifying the filter syntax for dueDateTime as a complex type, giving a concrete example, and reasserting the top default. It also explains the interaction between includeCompleted and the filter, which is not fully explicit in 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 states a specific verb ('Lists'), a specific resource ('tasks in one To Do list'), and enumerates the exact fields returned (id, title, status, importance, due and reminder times, body preview). It clearly distinguishes from sibling tools like todo_list_lists (lists lists) and todo_get_task (single task) by focusing on the list-task scope.

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 explicitly tells when to use the filter and what not to use ($search), including a concrete example for the complex dueDateTime type. It also explains the includeCompleted default behavior, giving clear conditions for when to set it. This goes beyond mere context and provides actionable alternatives.

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

todo_update_taskUpdate a To Do taskA
Idempotent

Patches an existing To Do task and returns the updated task. Only the supplied fields change; omitting dueDateTime or reminderDateTime leaves the existing value alone, so use clearDueDateTime or clearReminderDateTime to remove one. Due and reminder values are sent as Graph dateTimeTimeZone objects using the timeZone argument (default UTC).

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNoReplacement plain-text notes. Pass an empty string to clear them.
titleNoNew task title.
listIdYesId of the To Do list that holds the task.
statusNoNew task status. Use todo_complete_task for the common completed case.
taskIdYesId of the task to update.
timeZoneNoTime zone for the due and reminder wall-clock times. Ignored for values that already carry a UTC offset.UTC
importanceNoNew task importance.
dueDateTimeNoNew due date. Use 'YYYY-MM-DD' or a full ISO 8601 date-time such as '2026-09-10T14:30:00'.
clearDueDateTimeNoRemove the due date. Omitting dueDateTime alone never clears it.
reminderDateTimeNoNew reminder date-time. Supplying this also turns the reminder on.
clearReminderDateTimeNoRemove the reminder and turn it off.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses important behavior: omitted due/reminder fields are preserved, clearing requires dedicated flags, and date-time values are sent as Graph dateTimeTimeZone objects with a default UTC timeZone. This meaningfully explains how the patch behaves without contradicting the annotations.

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?

Three sentences, each earning its place: the first states the core operation and return value, the second explains partial-update and clearing behavior, and the third clarifies the date-time serialization and timezone default. 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.

Completeness5/5

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

Given 11 parameters, no output schema, and annotations covering safety/idempotence, the description plus schema is complete enough for correct invocation. It explains patch semantics, clearing behavior, timezone handling, and the return value ('returns the updated task'), leaving no critical gap for an agent deciding how to call it.

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?

Schema description coverage is 100%, so the baseline is 3, but the description adds crucial semantics that the schema alone does not make obvious: omitting dueDateTime/reminderDateTime leaves existing values untouched, clearing requires separate boolean flags, and timeZone governs how wall-clock values are interpreted. This is genuinely additive value.

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 opens with 'Patches an existing To Do task and returns the updated task,' which names a specific verb, resource, and operation style. It clearly distinguishes this from todo_create_task, todo_delete_task, and todo_complete_task, and the status enum even points to todo_complete_task for the common completed case.

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 patch semantics ('Only the supplied fields change') and explicit guidance for clearing fields via clearDueDateTime/clearReminderDateTime. The schema adds a direct alternative recommendation for todo_complete_task when setting status to completed, though the tool description itself does not fully enumerate when to prefer this tool over all sibling update/create paths.

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. 51 tool updatesv0.1.0
    • First observedcalendar_create_event
    • First observedcalendar_delete_event
    • First observedcalendar_find_meeting_times
    • First observedcalendar_get_event
    • First observedcalendar_get_schedule
    • First observedcalendar_list_calendars
    • First observedcalendar_list_events
    • First observedcalendar_respond_event
    • First observedcalendar_update_event
    • First observedcontacts_create
    • First observedcontacts_delete
    • First observedcontacts_get
    • First observedcontacts_list
    • First observedcontacts_search
    • First observedcontacts_update
    • First observedfiles_create_folder
    • First observedfiles_create_link
    • First observedfiles_delete
    • First observedfiles_get_item
    • First observedfiles_list_children
    • First observedfiles_list_recent
    • First observedfiles_list_shared
    • First observedfiles_read_text
    • First observedfiles_search
    • First observedfiles_upload_text
    • First observedgraph_list_permissions
    • First observedgraph_request
    • First observedgraph_schema
    • First observedmail_create_draft
    • First observedmail_delete_message
    • First observedmail_forward
    • First observedmail_get_message
    • First observedmail_list_attachments
    • First observedmail_list_folders
    • First observedmail_list_messages
    • First observedmail_mark_read
    • First observedmail_move_message
    • First observedmail_reply
    • First observedmail_search_messages
    • First observedmail_send
    • First observedme_get_mailbox_settings
    • First observedme_get_profile
    • First observedsearch_query
    • First observedtodo_complete_task
    • First observedtodo_create_list
    • First observedtodo_create_task
    • First observedtodo_delete_task
    • First observedtodo_get_task
    • First observedtodo_list_lists
    • First observedtodo_list_tasks
    • First observedtodo_update_task

TDQS

A4.3/5.0

Scored across 51 tools

Disambiguation5/5

The 51 tools are organized into clear domains (todo, mail, files, calendar, contacts, me, graph) with each tool addressing a distinct resource-action pair. Even within rich domains like mail, tools like mail_list_messages, mail_search_messages, and mail_get_message have clearly separated purposes (listing, searching, and fetching full content). The only generic tool, graph_request, is explicitly positioned as a fallback for uncovered endpoints, and its description clarifies its distinct role.

Naming Consistency5/5

Every tool follows a strict domain_verb_noun (or domain_noun_verb) snake_case pattern, consistently using the domain prefix (todo_, mail_, files_, calendar_, contacts_, me_, graph_, search_). Verbs are uniform across similar operations (list_, get_, create_, update_, delete_, send_, etc.). This creates a highly predictable naming convention that lets an agent infer tool purposes without reading descriptions.

Tool Count4/5

51 tools is a large surface, but the scope is a broad Microsoft Graph integration covering mail, calendar, files, contacts, To Do, user profile, and search. Each domain has a focused, manageable set (3–10 tools per area) that justifies the total count. It is slightly on the heavy side, but the breadth of the domain makes it reasonable rather than excessive.

Completeness4/5

The tool surface provides full CRUD coverage for contacts, To Do tasks, calendar events, and basic file operations, plus send/reply/forward/move for mail. Notable gaps exist: no way to send an existing draft, no file rename/move/copy, no todo list deletion or update, and no binary file download. These are acknowledged in descriptions as deliberate limitations, so agents can work around them, but they prevent a perfect score.

Related MCP Connectors

Related MCP Servers