Skip to main content
Glama
outlook-mcp

outlook-mcp

by ajs117

outlook-mcp

A local MCP server for a personal Outlook.com / Hotmail / Live account (not a work/school Microsoft 365 account). It talks to Microsoft Graph directly using an OAuth device-code login, so it runs entirely on your own machine — no third-party service sees your mail.

Tools it exposes: list_folders, inbox_summary, list_messages, get_message, archive_message, move_message, delete_message, mark_read, create_reply_draft, bulk variants bulk_mark_read, bulk_move_messages, bulk_archive_messages, bulk_delete_messages (all backed by Graph's $batch endpoint, chunked to 20 ops/call), bulk_by_query (match + act in one call, ids never leave the server), create_draft (compose a new draft), create_folder, sender_summary (per-sender counts and read rates), find_newsletters, unsubscribe, unsubscribe_many and protected_senders (a keep-list bulk ops won't touch).

Common workflows

  • Decide what to keep — measure, don't guess. sender_summary groups a folder by exact sending address and reports count, read, unread and read_pct per sender. A sender nobody opens is evidence; a sender whose name sounds like junk is not. Rows carry a heuristic brand label for display only — grouping is always by the full address, and brand_shared flags addresses whose brand collides with another, because hello@edfenergy.com (bills) and hello@home.edfenergy.com (marketing) are two different senders that must never be merged.

  • Triage a big folder / clear old mail. Use bulk_by_query with a search term and received_before to sweep, e.g. delete old shipping notifications: action="delete", search="delivery", received_before="2026-06-01". It runs dry_run first (count + sample), then executes on the second call. Custom folders work by name — action="move", destination_folder="Receipts" resolves the name to its id (create it first with create_folder if needed).

  • Unsubscribe from newsletters. find_newsletters lists bulk senders (grouped by sender, with read counts and the best unsubscribe method for each); unsubscribe_many(refs, execute=True) then does the whole sweep in one call. RFC 8058 one-click senders are unsubscribed with a single POST (no browser); mailto senders get an unsubscribe draft to send; link-only senders — and one-click endpoints that reject the POST, which some privacy portals do with a 405 — come back under needs_browser with a URL to open yourself (never auto-fetched). The List-Unsubscribe header means "bulk sender", not "junk": order confirmations, delivery updates, bank statements and voucher codes all carry it, so treat the output as candidates to show a human, never as a sweep list. Then clear the wanted ones with bulk_by_query(action="archive", only_newsletters=True) — the only_newsletters filter keeps just the bulk mail (List-Unsubscribe header) among the matches, so you can e.g. archive every newsletter older than a week. Note: unsubscribing confirms your address is live — do it for legitimate senders; for real spam, just delete/block.

  • Protect the mail you can't afford to lose. protected_senders(add=[...]) stores a keep-list — benefits, medical, legal, bills, anything with a case number. A pattern with */? is a glob over the whole address (*@edfenergy.com, which deliberately does not match a marketing subdomain); one without is a substring test (dwp). bulk_by_query then excludes protected senders from every sweep and reports how many it held back (on_protected="error" to abort instead, "include" to ignore the list), and bulk_delete_messages refuses outright unless called with allow_protected=True. The list lives in ~/.outlook_mcp_config.json (override with OUTLOOK_MCP_CONFIG).

  • Act on specific senders. bulk_by_query(senders_only=[...]) filters matches to an exact set of addresses client-side — Graph rejects a sender $filter alongside $orderby, so this is the supported route.

  • Draft an email. create_draft(to, subject, body) saves to Drafts and never sends — you review and send from Outlook. (This server holds Mail.ReadWrite, which can create drafts but deliberately cannot send.) list_messages also takes fetch_all=True to page past the default 25-message limit (up to max_results, default 500) instead of returning a single page.

Token efficiency

Graph message ids are ~150 characters of opaque base64 each, which dominates token cost when listing or bulk-triaging a mailbox. To keep tool traffic small:

  • Short refs. Listings return a compact ref (e.g. m12) per message instead of the raw id. Every tool accepts a ref in place of an id and resolves it server-side, so you pass m12, not a 150-char string. Refs are stable for the life of the server process; after a restart, just re-list.

  • Lean listings. list_messages returns only triage fields by default. For content, prefer include_keywords=True (a short salient-word list per message — denser than a preview) and reach for get_message for a full read. include_preview=True still attaches the full plaintext preview when wanted.

  • Plaintext, truncated bodies. get_message asks Graph for the plaintext body (not raw HTML) and truncates to max_chars (default 4000); include_body=False gives metadata only.

  • Compact bulk results. The bulk_* tools return {"ok": <count>, "failed_count": <n>, "failed": [...]} — succeeded ids are counted, not echoed back.

  • Filter-and-act — ids never touch the conversation. bulk_by_query matches messages by folder/filter_query/search and applies one action (archive/delete/mark_read/mark_unread/move) to all of them server-side, returning just a count. This is the cheapest way to triage: no id list is ever streamed through the model. It runs dry_run=True by default (returns a count + small sample and does nothing) so a bad filter can't silently nuke the wrong mail — call again with dry_run=False to execute.

1. Create a free Azure app registration (one-time, ~10 min)

You need this to get a client_id. It costs nothing — no Azure subscription or credit card required for this.

  1. Go to https://portal.azure.com and sign in with your Microsoft account (your outlook.com account works fine as the sign-in).

  2. Search for "App registrations" and click New registration.

  3. Name it anything, e.g. outlook-mcp-personal.

  4. Under Supported account types, choose: "Personal Microsoft accounts only" (or the "any organizational directory and personal Microsoft accounts" option — either works).

  5. Leave Redirect URI blank for now. Click Register.

  6. Copy the Application (client) ID shown on the Overview page — you'll need it below.

  7. In the left nav, go to Authentication → Add a platform → Mobile and desktop applications → check the https://login.microsoftonline.com/common/oauth2/nativeclient box → Configure.

  8. Still on the Authentication page, scroll down to Advanced settings and set "Allow public client flows" to Yes. Save.

  9. In the left nav, go to API permissions → Add a permission → Microsoft Graph → Delegated permissions → add Mail.ReadWrite, MailboxSettings.Read, User.Read, offline_access (offline_access is usually pre-added). Click Add permissions. (No admin consent needed for a personal account signing into their own app.)

That's it — no client secret needed, this is a "public client."

Related MCP server: email-mcp

2. Install

cd outlook-mcp
pip install -e .

3. Configure

Set the client ID from step 1:

export OUTLOOK_MCP_CLIENT_ID="<your-application-client-id>"

(Put this in your shell profile so it persists.)

4. Add to Claude Desktop / Cowork

Edit your Claude Desktop MCP config (Settings → Developer → Edit Config, or directly at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS) and add:

{
  "mcpServers": {
    "outlook-personal": {
      "command": "outlook-mcp",
      "env": {
        "OUTLOOK_MCP_CLIENT_ID": "<your-application-client-id>"
      }
    }
  }
}

Restart Claude Desktop. The first time you call a tool, the server prints a device-login URL and code — open the URL in a browser, enter the code, sign in with your outlook.com account, and approve. After that, tokens refresh silently and you won't be prompted again (cached in ~/.outlook_mcp_token_cache.json, permissions 600).

Notes / limitations

  • delete_message is a soft delete (moves to Deleted Items), matching how Graph's message DELETE actually behaves — nothing is purged permanently by this tool.

  • create_reply_draft only creates a draft; it never sends mail on its own.

  • This is a personal single-user tool: the token cache is a plain JSON file on disk, meant for your own machine, not a shared/multi-user deployment.

  • If you ever want to turn this into a shareable connector, the gap to close is: move off device-code flow to a proper auth-code + PKCE flow with a redirect, host it somewhere, get Microsoft's app verification for the requested scopes, and register it in Claude's MCP directory.

Available Tools

21 tools
archive_messageB

Move a message (by ref or raw id) to the Archive folder.

NameRequiredDescriptionDefault
message_idYes

TDQS

B3.3/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It discloses the outcome location (Archive folder) but says nothing about permissions, idempotency when the message is already archived, reversibility, or failure behavior for invalid ids.

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?

One short sentence, front-loaded with the action and destination, with zero wasted words.

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

Completeness3/5

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

For a one-parameter mutation tool with no output schema the definition is minimally workable, but the missing id-format detail and lack of any behavioral notes leave an agent with gaps it would have to discover by trial.

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 0%, so the description must compensate. It does add value by noting message_id accepts either a ref or a raw id, but it never defines what a 'ref' looks like or whether both forms are accepted everywhere, leaving the single parameter partly specified.

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?

States a specific verb (move/archive) and resource (message) plus a concrete destination (Archive folder), which implicitly separates it from generic move_message. It never explicitly names a sibling, so it falls short of a 5.

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?

Single-message scope is implied by the name and the destination implies a lighter-touch alternative to delete_message, but there is no explicit when/when-not guidance or mention of bulk_archive_messages / move_message as alternatives.

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

bulk_archive_messagesB

Move many messages (refs or raw ids) to the Archive folder in one call.

NameRequiredDescriptionDefault
message_idsYes

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It says messages are moved to Archive but omits whether the operation is reversible, permission requirements, partial-failure behavior for invalid ids, and any batch size limits — significant gaps for a bulk mutation 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?

A single front-loaded sentence that puts the action and scope first, with zero filler. Nothing in it repeats structured fields verbatim.

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

Completeness2/5

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

For a bulk mutation tool with no annotations and no output schema, the description is too thin — an agent cannot tell how failures are reported or what happens to a batch with partially invalid ids. The absence of any annotation safety signal leaves the behavioral profile largely undescribed.

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 one parameter with 0% schema description coverage, so the schema says nothing about the argument. The description partially compensates by stating the array accepts 'refs or raw ids', which is genuinely useful identifier-format guidance beyond the schema, but it says nothing about array size limits or empty-list behavior.

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?

States a specific verb (move) and resource (many messages) plus the destination (Archive folder) and the batching intent ('in one call'). It differentiates from the singular sibling archive_message through 'many', though it never names the sibling explicitly.

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?

'in one call' implies this is the batch alternative to archive_message, but the description never states when to prefer the bulk form or whether individual calls are ever appropriate. No exclusions or preconditions are mentioned.

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

bulk_by_queryA

Find every message matching a query and apply one action to all of them in a single call — the message ids never enter the conversation, so this is by far the cheapest way to triage in bulk.

action: one of archive, delete, mark_read, mark_unread, move (move requires destination_folder, which may be a folder display name). folder / filter_query / search: same matching semantics as list_messages (fetches all matches up to max_results). received_before / received_after: ISO dates (e.g. "2026-01-01"); applied client-side AFTER matching, so they compose with search — which Graph itself won't combine with a date $filter. Use these for "old " sweeps, e.g. search="delivery" + received_before to clear old shipping mail. only_newsletters: keep only bulk/newsletter mail (messages with a List-Unsubscribe header) among the matches, e.g. archive all newsletters older than a week. Costs an extra batched header pass over the matches. Note this is a bulk-sender signal, not a junk one — plenty of wanted mail (order updates, voucher codes, statements) carries the header too. senders_only: keep only matches from these sending addresses (exact, case-insensitive). Graph rejects a sender $filter combined with $orderby, so this is applied client-side — it is the supported way to act per sender. Pair it with sender_summary to pick the addresses. on_protected: what to do about matches from protected senders (see protected_senders): "exclude" (default, skip them and report), "error" (do nothing at all and report), "include" (ignore the list). dry_run: TRUE by default — returns how many messages would be affected plus a small sample of subjects/senders, and does nothing. Review it, then call again with dry_run=False to actually run the action. This guards against a bad filter nuking the wrong mail.

NameRequiredDescriptionDefault
actionYes
folderNoinbox
searchNo
dry_runNo
max_resultsNo
filter_queryNo
on_protectedNoexclude
senders_onlyNo
received_afterNo
received_beforeNo
only_newslettersNo
destination_folderNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does most of it: it discloses that dry_run is TRUE by default and what it returns, that on_protected skips protected senders by default, that date/sender filters are applied client-side, and that only_newsletters costs an extra header pass. It stops short of stating whether delete is permanent or recoverable and what the final report looks like.

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?

Long but front-loaded and organized as one labeled block per parameter, so an agent can skim to the field it needs. A few parenthetical asides (the 'old <topic>' sweep example, the newsletter-vs-junk lecture) run longer than strictly necessary, but nothing is wasted 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?

For a 12-parameter, no-annotation, no-output-schema mutation tool this is close to complete: safety defaults, filtering composition rules, and protected-sender behavior are all covered. The remaining gaps are max_results truncation behavior and the shape of the non-dry-run result.

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 0%, so the description must compensate for all 12 parameters, and it explains roughly ten of them including the undocumented-in-schema action enum values and the destination_folder requirement for move. max_results is only mentioned in passing as an upper bound with no default or truncation semantics, and folder's default of inbox is left implicit.

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 — find every message matching a query and apply one action to all of them in a single call — plus the distinguishing benefit (ids never enter the conversation). It is clearly the general filter-driven counterpart to the action-specific siblings (bulk_archive_messages, bulk_move_messages, etc.).

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 prescribes the dry_run-then-rerun workflow, spells out the on_protected policy choices, and tells the agent when to prefer received_before/after over a Graph date $filter and when to use senders_only instead of a sender $filter. It even routes the agent to sender_summary for picking addresses.

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

bulk_delete_messagesA

Move many messages (refs or raw ids) to Deleted Items in one call, marking them read first (mark_as_read=False to keep them unread).

Refuses and deletes nothing if any message is from a protected sender (see protected_senders) — re-call with allow_protected=True to override. Senders are only known for messages this server has already listed or read; refs it has never seen cannot be checked.

NameRequiredDescriptionDefault
message_idsYes
mark_as_readNo
allow_protectedNo

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses the default side effect (marks read first), the all-or-nothing refusal semantics ('deletes nothing if any message is from a protected sender'), the override flag, and a real limitation (senders unknown for unlisted refs). That is non-obvious, decision-critical behavior an agent cannot infer from the schema.

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?

Roughly three short sentences, front-loaded with the action and destination, then the refusal rule and the data-availability caveat. No filler; every clause adds information.

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

Completeness4/5

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

Covers action, defaults, failure mode, and override for a mutation tool with no annotations and no output schema. It omits what the call returns (counts, per-id results) and how unknown or malformed ids are handled, but the 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.

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate and does: message_ids accepts 'refs or raw ids', mark_as_read defaults true with the False case explained, and allow_protected is tied to the protected-sender refusal. All three parameters get meaning beyond their bare type and default.

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 with scope: 'Move many messages (refs or raw ids) to Deleted Items in one call.' The bulk framing plus the destination folder distinguishes it implicitly from the singular delete_message and from bulk_move_messages, which targets arbitrary folders.

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 an explicit conditional path: if the call refuses due to a protected sender, 're-call with allow_protected=True to override.' It does not explicitly route the agent to delete_message for single messages or bulk_move_messages for other folders, so it falls short of full when/when-not coverage.

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

bulk_mark_readB

Mark many messages (refs or raw ids) read/unread in one call (Graph $batch).

NameRequiredDescriptionDefault
is_readNo
message_idsYes

TDQS

B3.4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden. It usefully discloses the underlying Graph $batch mechanism and that the operation toggles rather than only sets read state, but says nothing about per-message failure handling, batch limits, or required permissions.

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?

A single front-loaded sentence with no filler. The only cost is terse jargon ('refs', '$batch') that may need unpacking.

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

Completeness3/5

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

For a 2-parameter bulk mutation with no annotations and no output schema, the description covers the core action but leaves out failure semantics and batching constraints an agent would need to call it safely.

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 0%, so the description must compensate. It does add real meaning for message_ids by noting 'refs or raw ids', and 'read/unread' hints at the is_read boolean, but is_read is never named and no format details or default (true) are given in prose.

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?

States a specific verb and resource ('Mark many messages ... read/unread in one call') and the parenthetical '(refs or raw ids)' plus 'many ... in one call' implicitly separates it from the singular mark_read sibling. It does not explicitly name the alternative, so it stops short of a 5.

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?

Usage is only implied: 'many ... in one call' signals this is the bulk/efficient path versus mark_read, but the description never says when to prefer it, whether there is a batch size limit, or when to fall back to the single-message tool.

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

bulk_move_messagesB

Move many messages (refs or raw ids) to a folder (id or well-known name) in one call.

NameRequiredDescriptionDefault
message_idsYes
destination_folderYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full disclosure burden. It signals batching ('in one call') but says nothing about permissions needed, behavior on unknown message ids or missing folders, whether the batch is atomic or partially applied, or batch size limits — significant gaps for a mutation tool.

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?

One sentence, front-loaded with the verb and resource, with zero filler. It is efficient, though the terseness leaves little room for the behavioral and parameter detail a bulk mutation tool arguably needs.

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

Completeness2/5

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

With no annotations, no output schema, and 0% schema description coverage, the description should cover more: mutation semantics, failure modes, and return/confirmation behavior are all absent. An agent can form a call but cannot anticipate how errors or partial failures are handled.

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 0%, so the description must compensate, and it does partially: message_ids accepts 'refs or raw ids' and destination_folder accepts an 'id or well-known name.' This adds real meaning beyond the bare string/array types, but leaves 'ref' undefined and gives no examples for either parameter.

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?

States a specific verb and resource ('Move many messages') plus the bulk scope 'in one call,' which implicitly separates it from the sibling move_message. It does not explicitly name that sibling, but an agent can distinguish bulk from single-message moves without reading 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 Guidelines3/5

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

Usage is implied by 'many messages ... in one call,' suggesting it is for batch relocation rather than single moves. However, there is no explicit when-to-use/when-not guidance, no mention of when to prefer bulk_by_query or move_message, and no note on prerequisites such as folder existence.

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

create_draftA

Compose a brand-new draft email (NOT a reply). It is saved to Drafts and never sent — you review and send it from Outlook.

Args: to: recipient email addresses. subject: subject line. body: message body (plain text by default; set html=True to send HTML). cc: optional cc email addresses. html: treat body as HTML instead of plain text.

NameRequiredDescriptionDefault
ccNo
toYes
bodyYes
htmlNo
subjectYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It usefully discloses that the message is saved to Drafts and never sent, but it does not mention permissions/auth needs, return behavior, or what happens on invalid recipients.

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?

Front-loads the key purpose and non-sending behavior, then uses a compact Args list for parameters. There is no wasted text.

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 no annotations and no output schema, the description is mostly complete for calling the tool: it explains the action, non-send guarantee, storage location, and all parameters. It could be stronger with auth/error or return details, but the core invocation needs are covered.

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 0%, so the description must compensate, and it does document all five parameters: to, subject, body, optional cc, and html. It adds useful semantics such as body being plain text by default and html=True making it HTML, though array/string details are left to 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 and resource (compose a brand-new draft email) and explicitly excludes replies, which distinguishes it from the sibling create_reply_draft. It also clarifies that the draft is saved, not sent.

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 usage context: brand-new email, not a reply, saved to Drafts and not sent. The alternative create_reply_draft is strongly implied by 'NOT a reply,' though not explicitly named as the tool to use instead.

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

create_folderB

Create a mail folder. parent_folder (id or display name) nests it; omit for a top-level folder. Useful before moving mail into a new folder.

NameRequiredDescriptionDefault
display_nameYes
parent_folderNo

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It does not say what happens on a duplicate display_name, whether creation is idempotent, what permissions are required, or what the call returns (a folder id would plausibly be needed for later moves). For a mutation tool with zero annotation coverage this is a substantial gap.

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?

Two sentences with the core action and the key parameter behavior front-loaded, followed by a short usage hint. Nothing is padded, though the trailing usage sentence is thinner than it could be.

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

Completeness3/5

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

With no annotations, no output schema, and 0% schema description coverage, the definition should explain return value and duplicate-name behavior. It covers the parameters' meaning adequately but leaves the agent guessing about failure modes and what it gets back.

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 0%, so the description must compensate, and it does half the job: parent_folder is explained as accepting an id or display name and being omittable for a top-level folder, which the schema does not convey. display_name is only implicitly characterized as the folder's name; no constraints (uniqueness, length, allowed characters) are given.

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?

States a specific verb and resource ('Create a mail folder'), which no sibling shares — list_folders reads, create_folder writes. It also distinguishes the nested vs top-level case. It stops short of noting what the call returns or how it differs from other creation tools like create_draft, but the resource 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 Guidelines3/5

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

The phrase 'Useful before moving mail into a new folder' implies the workflow (create_folder then move_message) but never names move_message or states when not to use it. Usage context is implied rather than spelled out, so an agent must infer the sequencing.

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

create_reply_draftA

Create a draft reply to a message (by ref or raw id). Does NOT send it; a human reviews/sends from Outlook.

NameRequiredDescriptionDefault
commentNo
message_idYes

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does disclose the crucial non-sending, human-review behavior. It omits whether it produces a reply vs reply-all, and whether existing draft conflicts overwrite anything.

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 compact sentences, front-loaded with the action and immediately followed by the non-send caveat. No filler.

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

Completeness3/5

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

For a simple 2-param tool with no output schema this is nearly adequate, but the undefined 'comment' parameter and no guidance on return value or draft location leave a real gap.

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

Parameters2/5

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

Schema coverage is 0%, so both parameters are undocumented in structured data. The description explains message_id accepts 'ref or raw id', but the 'comment' parameter is never mentioned, leaving its role (reply body?) entirely unclear.

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?

States a specific verb and resource ('Create a draft reply to a message') with an explicit parenthetical on id format. It is distinguishable from create_draft, though it doesn't explicitly contrast with that sibling.

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 clause 'Does NOT send it; a human reviews/sends from Outlook' implies this is the right choice when you want a human-gated reply rather than a send. However, it never explicitly says when to use this versus create_draft or which message types are eligible.

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

delete_messageA

Move a message (by ref or raw id) to Deleted Items — recoverable from there until you empty it. Marks it read first (mark_as_read=False to keep it unread) so deleted mail doesn't linger in your unread count.

NameRequiredDescriptionDefault
message_idYes
mark_as_readNo

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does real work: it discloses the soft-delete/recoverability model ('recoverable from there until you empty it') and an otherwise invisible side effect (message is marked read before deletion, configurable via mark_as_read). It stops short of error behavior for already-deleted or missing messages.

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 filler: destination and recoverability first, then the side effect and its override. Every clause 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?

For a two-parameter mutation with no annotations and no output schema, the description covers destination, reversibility, and side effects. What remains unstated (error/idempotency behavior on an already-deleted message, return value) is minor but not zero.

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 0%, so the description must compensate, and it does for mark_as_read — naming the default's purpose (keep deleted mail out of the unread count) and the opt-out (mark_as_read=False). It also clarifies that message_id accepts either a reference or a raw id, which the bare 'string' schema does not convey.

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 ('Move a message ... to Deleted Items') plus the accepted identifier forms ('by ref or raw id'), which distinguishes it from move_message (arbitrary destination) and bulk_delete_messages (plural). An agent can pick it without opening 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 Guidelines3/5

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

The recoverable-vs-permanent distinction implies this is a soft delete, but it never states when to prefer delete_message over archive_message, move_message, or bulk_delete_messages, nor any precondition (e.g. message must not already be deleted). Usage 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.

find_newslettersA

Scan a folder for bulk mail (messages carrying a List-Unsubscribe header) and report how each sender can be unsubscribed.

Grouped by sender by default, because unsubscribing is per sender while the underlying listing is per message — the ungrouped form makes the model dedupe 200 rows by hand to reach the ~50 decisions that actually exist. Each row carries read/unread counts so a sender can be judged on engagement rather than on what its name suggests.

IMPORTANT: the List-Unsubscribe header marks a bulk sender, not junk. Order confirmations, delivery updates, statements and voucher codes all carry it. Treat this as a list of candidates to show the user, never as a list to sweep.

Returns {checked, headers_ok, header_fetch_failed, newsletter_messages, senders: [...]}. The header counts are there so a discrepancy between this and bulk_by_query(only_newsletters=True) is visible rather than mysterious: header sub-requests that fail are silently dropped from the scan.

Args: folder: folder id or well-known name. max_check: how many recent messages to scan. group_by_sender: set False for the raw per-message rows.

NameRequiredDescriptionDefault
folderNoinbox
max_checkNo
group_by_senderNo

TDQS

A4.6/5.0
Behavior5/5

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

No annotations exist, so the description carries the full burden and does: it discloses that failing header sub-requests are silently dropped, explains the resulting discrepancy against bulk_by_query(only_newsletters=True), and warns that the List-Unsubscribe header marks bulk senders rather than junk. This is exactly the kind of failure-mode and misinterpretation context 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.

Conciseness4/5

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

Front-loaded with the action and the detection rule, then the IMPORTANT caveat, then the return shape, then args — a sound ordering. It runs a little long, and the sentence about the model deduping 200 rows by hand is motivational rather than operational, but nothing is 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 annotations and no output schema, the description supplies the return shape ({checked, headers_ok, header_fetch_failed, newsletter_messages, senders}), the rationale for those fields, and the semantic trap to avoid. Nothing an agent needs in order to call it or interpret it 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 description coverage is 0%, so the description must compensate, and it documents all three parameters: folder accepts an id or well-known name, max_check bounds how many recent messages are scanned, and group_by_sender=False yields raw per-message rows. It does not give an example of a well-known folder name, which would have closed the gap fully.

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

Purpose5/5

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

States a specific verb and resource ('Scan a folder for bulk mail... and report how each sender can be unsubscribed') and pins down the detection criterion (List-Unsubscribe header). It is clearly distinct from unsubscribe/unsubscribe_many (discovery, not action) and from bulk_by_query, which it names explicitly.

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 a strong exclusion ('Treat this as a list of candidates to show the user, never as a list to sweep') and explains why grouping is the default and when to set group_by_sender=False. It stops short of explicitly naming the sibling that performs the unsubscribe, leaving that hop implicit.

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

get_messageA

Get one message by ref (or raw id). Body is returned as plaintext and truncated to max_chars to keep it token-cheap.

Args: message_id: a short ref from list_messages (e.g. "m12"), or a raw Graph id. include_body: set False to get metadata only (subject/from/date), no body. max_chars: truncate the plaintext body to this many characters (0 = no limit).

NameRequiredDescriptionDefault
max_charsNo
message_idYes
include_bodyNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations the description carries the full load, and it discloses non-obvious traits: body is converted to plaintext, truncated, and the truncation exists for token economy. It does not cover invalid/expired ref behavior or whether attachments/HTML structure are dropped, which are the remaining gaps for a read tool.

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?

Front-loaded sentence states purpose and the two most important behaviors (plaintext, truncation) before the Args breakdown. The Args block is tight, though it slightly duplicates the schema's field names.

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?

No output schema exists, and the description covers what comes back: subject/from/date in metadata-only mode and a plaintext body otherwise, plus the size cap. Error handling and ref lifetime are the only notable omissions for a single-item read 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 0%, so the description must compensate, and it does: it explains the accepted id formats, the effect of include_body, and the semantics of max_chars including the 0 sentinel. It omits the actual default values (4000 and true) that the schema declares, so an agent must open the schema for those.

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 ('Get one message by ref') and pins the identifier form ('a short ref from list_messages, or a raw Graph id'). It is clearly differentiable from list_messages, which is named as the source of refs.

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 actionable per-parameter usage: include_body=False for metadata-only, max_chars=0 for no limit. The ref-from-list_messages hint establishes the workflow. It stops short of explicit when-not-to-use guidance (e.g., use list_messages for searching, or bulk tools for many messages).

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

inbox_summaryA

Quick counts for the inbox: total messages and unread messages.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

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

No annotations are supplied, so the description must carry behavioral disclosure. It does say what the tool returns (two counts), implying a lightweight read, but it does not state whether the operation is read-only, whether counts are scoped to a folder, or how counts are affected by unread state — modest but not rich transparency.

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?

A single front-loaded sentence that identifies the tool and its output with zero wasted words.

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 no-parameter summary tool with no output schema, the description conveys the essentials of what is returned. It could clarify scope (which inbox/folder) and read-only nature, but it is close to complete for this complexity level.

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 zero parameters and 100% coverage, so there is nothing for the description to disambiguate. The baseline for a no-parameter tool 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?

States a specific verb ('quick counts') and resource ('the inbox') plus the two values returned: total messages and unread messages. An agent can tell this is a summary/count tool distinct from siblings like list_messages or sender_summary, though it does not explicitly name those alternatives.

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 word 'quick' implies this is a lightweight overview rather than a message-listing tool, but there is no explicit statement of when to use it versus list_messages or sender_summary, and no exclusions are given.

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

list_foldersA

List all mail folders (Inbox, Archive, Deleted Items, custom folders, etc.) with their ids and display names.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden of behavioral disclosure. It communicates scope by saying "all mail folders" and lists returned fields, but it does not explicitly state that the operation is read-only, whether folders are ordered or nested, or any permission requirements.

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

Conciseness5/5

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

The description is a single, front-loaded sentence that immediately states the action and return fields. The examples are useful and no sentence is wasted.

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 zero-parameter listing tool with an output schema, the description is nearly complete: it names the resource, scope, and returned fields. Minor gaps remain around folder hierarchy, ordering, or whether all folder types are always included.

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 the baseline score is 4 under the rubric. The description does not need to explain parameter semantics, and the empty schema is consistent with that.

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 states a specific verb and resource: "List all mail folders," and adds concrete examples such as Inbox, Archive, and custom folders. It clearly distinguishes folder listing from message listing, though it does not explicitly contrast with sibling tools like create_folder or list_messages.

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?

Usage is implied: an agent would call this to discover folder ids and display names before operations like move_message or list_messages. However, the description does not explicitly state when to use this tool versus alternatives, nor does it include exclusions or prerequisites.

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

list_messagesA

List messages in a folder, newest first (unless searching).

Returns compact rows keyed by a short ref handle (not the raw Graph id) — pass that ref to get_message / move / delete / the bulk_* tools.

Args: folder: folder id or well-known name (inbox, archive, deleteditems, sentitems, drafts, junkemail). top: max number of messages to return per page (ignored if fetch_all is True). skip: number of messages to skip, for manual paging (ignored if fetch_all is True). filter_query: raw OData $filter, e.g. "receivedDateTime le 2026-01-01T00:00:00Z" or "isRead eq false". search: free-text search (Graph $search); when set, filter_query/order are ignored. fetch_all: if True, follow pagination automatically and return up to max_results messages instead of a single page of top. Use this for bulk operations over a whole folder. max_results: cap on messages returned when fetch_all is True (safety limit, default 500). include_keywords: attach a short salient-keyword list per message (subject+preview) for triage. include_preview: attach the full plaintext preview per message. Prefer include_keywords for triage and get_message for a full read — a preview per message across a big folder is costly.

NameRequiredDescriptionDefault
topNo
skipNo
folderNoinbox
searchNo
fetch_allNo
max_resultsNo
filter_queryNo
include_previewNo
include_keywordsNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

No annotations exist, so the description carries the full burden and does well: it discloses default ordering, the `ref` handle indirection, automatic pagination under fetch_all, a default safety cap of 500, and an explicit cost warning that per-message previews across a big folder are expensive. It stops short of stating read-only semantics, auth/permission needs, or rate limits.

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

Conciseness4/5

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

Front-loaded with the one-line purpose, ordering, and the critical `ref` handoff before the Args block, and each Args line adds real information rather than restating a name. It runs long, but the length is driven by nine undocumented parameters, so little is wasted.

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?

An output schema exists, so return values need no elaboration beyond the `ref` handoff, which is supplied anyway. For a zero-required-parameter, nine-argument listing tool with no annotations, an agent has everything needed to page, filter, search, or bulk-fetch 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 description coverage is 0%, so the description must compensate entirely and it does — all nine parameters are explained with behavior the schema cannot express: well-known folder names enumerated, top/skip nullified by fetch_all, an OData $filter example, search precedence over filter, and max_results described as a safety limit with its default.

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 ('List messages in a folder') plus the default ordering and the one condition that changes it ('newest first (unless searching)'). It also explains the returned shape ('compact rows keyed by a short `ref` handle (not the raw Graph id)'), which instantly distinguishes it from get_message and the bulk_* 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?

Gives explicit conditions for the tricky flags: fetch_all for whole-folder bulk work, include_keywords for triage vs get_message for a full read, and notes that search causes filter_query/order to be ignored. It does not, however, route the agent between this tool and siblings like inbox_summary, sender_summary, or bulk_by_query, so the alternatives coverage is partial.

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

mark_readB

Mark a message (by ref or raw id) as read or unread.

NameRequiredDescriptionDefault
is_readNo
message_idYes

TDQS

B3.3/5.0
Behavior2/5

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

No annotations exist, so the description carries the full burden. It helpfully discloses that the operation is a toggle (read OR unread), but says nothing about idempotency, permission requirements, behavior for an unknown message_id, or what is returned — significant gaps for a mutation 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?

A single front-loaded sentence with zero waste. The action and the toggle semantics are both delivered immediately.

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

Completeness3/5

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

For a simple two-parameter mutation with no annotations and no output schema, the description covers the core semantics but leaves the agent guessing about idempotency, error behavior, and return value. Adequate minimum, with clear gaps.

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 0%, so the description must compensate. It adds real meaning to message_id by revealing it accepts 'a ref or raw id', and to is_read via 'as read or unread', but it does not explain the ref format, why two input forms exist, or the default of is_read=true — so the compensation is only partial.

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?

States a specific verb and resource ('mark a message ... as read or unread'), and the singular 'a message' implicitly distinguishes it from the bulk_mark_read sibling. However, it never names or contrasts that sibling explicitly, so the differentiation is left to inference.

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?

Usage is only implied: the singular 'a message' suggests single-message operation, and the sibling list contains bulk_mark_read, but the description never states when to use this versus the bulk variant. No prerequisites or exclusions are given.

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

move_messageB

Move a message (by ref or raw id) to a folder (id or well-known name).

NameRequiredDescriptionDefault
message_idYes
destination_folderYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does not say whether the destination folder must already exist, whether moving requires permissions, what happens on invalid IDs, or what the response looks like.

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?

A single tightly-worded sentence that front-loads the action and resource with zero waste. The parenthetical parameter hints are efficient rather than verbose.

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

Completeness2/5

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

With no annotations, no output schema, and 0% schema description coverage, the description needs to do more. It covers the basic action and parameter formats but omits error behavior, folder prerequisites, and return semantics for a simple two-parameter mutation.

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 0%, so the description must compensate and does so partially: it clarifies message_id accepts a ref or raw id and destination_folder accepts an id or well-known name. That adds real meaning beyond the bare schema, but the accepted formats/values are not fully specified.

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 states a specific verb (move) and resource (message) plus the destination concept (folder). It is clear what the tool does, though it does not explicitly name a sibling like bulk_move_messages to distinguish the single-message case.

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?

Usage is only implied by the singular 'a message', which suggests it is for one message rather than bulk operations. It never states when to use this instead of bulk_move_messages or archive_message, leaving the agent to infer the single-vs-bulk distinction.

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

protected_sendersA

Read or edit the keep-list of senders that bulk operations won't touch.

Patterns are matched case-insensitively against the sending address: one containing * or ? is a glob over the whole address ("*@edfenergy.com"), one without is a substring test ("dwp"). Use this for the mail that would be expensive to lose — benefits, legal, medical, bills, anything with a case number — so a broad sweep can't reach it.

bulk_by_query excludes protected senders by default and says how many it held back; bulk_delete_messages refuses outright. Both can be overridden per call once you've looked.

Call with no arguments to just read the list.

NameRequiredDescriptionDefault
addNo
removeNo

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses case-insensitive matching, glob vs substring semantics, default exclusion behavior in bulk_by_query, outright refusal in bulk_delete_messages, and per-call override behavior.

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, then adds only relevant pattern and bulk-operation details. Every sentence contributes useful information.

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

Completeness4/5

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

For a low-complexity tool with optional parameters and no output schema, the description is nearly complete. Minor gaps remain around return shape for reads and edge cases such as duplicates or invalid patterns.

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 0%, so the description needs to compensate. It explains the pattern syntax well and clarifies no-argument reads, but does not explicitly describe the add and remove array parameters beyond what their names imply.

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 pair: reading or editing a keep-list of protected senders. It also distinguishes the tool from bulk siblings by explaining that bulk operations will not touch these senders.

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 explicitly says when to use the tool, gives examples of valuable mail to protect, explains that no arguments means read-only access, and describes how bulk_by_query and bulk_delete_messages behave with this list.

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

sender_summaryA

Group a whole folder by sending address and report, per sender, how many messages there are and how many were actually opened.

This is the tool to reach for before proposing anything for deletion. A sender's read rate is measured evidence of whether the mailbox owner wants their mail; guessing from the brand name is not, and gets it wrong.

Returns rows {sender, brand, domain, count, read, unread, read_pct, newest, oldest, sample_ref}, biggest sender first. brand is a heuristic display label — never group or delete by it. brand_shared: true marks a row whose brand label also belongs to another address in the result (e.g. a billing subdomain and a marketing subdomain of one company): those are different senders and must stay separate.

Args: folder: folder id or well-known name. min_count: drop senders with fewer than this many messages. top: return at most this many sender rows (after sorting by count). max_results: cap on messages scanned. unread_only: summarise only unread mail.

NameRequiredDescriptionDefault
topNo
folderNoinbox
min_countNo
max_resultsNo
unread_onlyNo

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the burden well: it discloses return fields, sorting order, the max_results scan cap, and important caveats about heuristic brand labels and shared brands. It does not cover error behavior or permissions, but for a read-only summary tool this is substantially transparent.

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 purpose is front-loaded, then usage rationale, return shape, and caveats follow in a logical order. The length is justified by the grouping semantics and the brand-label warning.

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?

No output schema or annotations exist, yet the description explains the returned row fields, ordering, and the key grouping caveat around brand and brand_shared. That is enough for an agent to invoke and interpret the summary 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 description coverage is 0%, but the Args block explains all five parameters, including folder identification, min_count filtering, top row limits, max_results message scanning, and unread_only. This adds clear meaning beyond the bare schema titles and defaults.

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: group a folder by sending address and report per-sender message/read counts. The scope is precise enough to distinguish it from generic message-listing or folder-summary 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?

Explicitly says to use it before proposing deletion and explains why read-rate evidence matters. It does not name sibling alternatives such as find_newsletters or protective-sender tools, so it stops short of full when/when-not routing.

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

unsubscribeA

Unsubscribe from the bulk sender of a message (ref or raw id).

Reads the message's List-Unsubscribe headers and:

  • method "one-click": with execute=True, performs the RFC 8058 one-click POST and returns the HTTP status — no browser needed.

  • method "mailto": with execute=True, creates a DRAFT unsubscribe email to the sender's unsubscribe address for you to send (our mail scope can create but not send mail).

  • method "weblink": returns the URL for you to open in a browser; not auto-fetched, since blindly GETting links embedded in email is unsafe.

With execute=False (default) it only reports the available method/target so you can decide. Caveat: unsubscribing confirms your address is live, so do it for legitimate senders — for actual spam, prefer delete/block instead.

NameRequiredDescriptionDefault
executeNo
message_idYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses the three method branches, that one-click returns HTTP status, that mailto only creates a DRAFT (scope cannot send), that weblinks are deliberately not auto-fetched for safety, and the caveat that unsubscribing confirms the address is live. These are exactly the side effects and risks an agent needs before mutating state.

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?

Front-loaded with the core action, then a scannable bullet list per method, ending with the important caveat. Dense and mostly waste-free, though the repeated 'with execute=True' phrasing in each bullet is slightly redundant against the standalone default sentence.

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?

No output schema and no annotations, yet the description explains what each branch returns (HTTP status, draft, URL, or a method/target report). It doesn't say what happens when a message has no List-Unsubscribe header, the one gap an agent might hit in practice.

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 0%, so the description must compensate, and it does: 'message_id' is described as a ref or raw id, and 'execute' is fully explained as the gate between report-only and performing the action, far beyond the bare boolean/default 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 and resource ('Unsubscribe from the bulk sender of a message') and clarifies the identifier accepts a ref or raw id. It is easily separable from siblings like delete_message, unsubscribe_many, and find_newsletters because it names the exact mechanism (List-Unsubscribe headers).

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 documents that execute=False is a dry-run report and execute=True performs the action, with behavior varying by method. It also gives a real exclusion rule: 'for actual spam, prefer delete/block instead,' routing the agent to sibling tools for the wrong case.

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

unsubscribe_manyA

Unsubscribe from many bulk senders in one call.

Deduplicates on the unsubscribe target, never on the sender: LinkedIn job alerts all arrive from one address but carry a different savedSearchId each, so skipping by sender leaves most streams subscribed while reporting success. Two messages for the same stream still carry different per-message tokens and so both get posted — a wasted request is cheaper than a missed unsubscribe.

Same per-message semantics as unsubscribe(), but the header fetch is batched and the whole sweep is one tool call instead of one per sender.

Returns {attempted, unsubscribed, needs_browser, drafted, failed, results: [...]}. needs_browser collects the senders whose only working route is a URL a human must open — including one-click endpoints that rejected the POST — so nothing fails silently.

NameRequiredDescriptionDefault
executeNo
message_idsYes

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does well: it discloses dedup keying on target rather than sender, the deliberate tradeoff of duplicate requests over missed unsubscribes, batching of the header fetch, and the needs_browser bucket so 'nothing fails silently'. It omits any mention of the execute flag's default-false/dry-run behavior and required permissions, which are the most consequential behaviors for a mutation tool.

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?

Purpose and the sibling comparison are front-loaded, and the dedup rationale, while long, explains behavior an agent may need to reason about. Some of the savedSearchId narrative is more justification than instruction and could be tightened.

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

Completeness3/5

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

The return shape is spelled out well, which is valuable with no output schema, and the batching/dedup model is covered. But for a two-param mutation tool with no annotations, leaving the execute dry-run flag completely unexplained is a material completeness gap.

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

Parameters2/5

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

Schema coverage is 0% and neither parameter is described. message_ids is only indirectly implied by talk of per-message tokens and savedSearchId, and the execute boolean (default false) is never mentioned at all — the agent cannot tell from the definition whether the call actually unsubscribes or only previews.

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 scale ('Unsubscribe from many bulk senders in one call'), and explicitly contrasts itself with the sibling unsubscribe() as the batched variant. An agent can distinguish it from unsubscribe and from bulk_* tools immediately.

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?

Names the alternative ('Same per-message semantics as unsubscribe(), but ... one tool call instead of one per sender'), which tells the agent to prefer this for multi-sender sweeps. It never states the inverse condition (when to use the single-message tool, or that a single ID should go to unsubscribe()), so the guidance is clear but not fully two-sided.

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. 21 tool updatesv0.1.0
    • First observedarchive_message
    • First observedbulk_archive_messages
    • First observedbulk_by_query
    • First observedbulk_delete_messages
    • First observedbulk_mark_read
    • First observedbulk_move_messages
    • First observedcreate_draft
    • First observedcreate_folder
    • First observedcreate_reply_draft
    • First observeddelete_message
    • First observedfind_newsletters
    • First observedget_message
    • First observedinbox_summary
    • First observedlist_folders
    • First observedlist_messages
    • First observedmark_read
    • First observedmove_message
    • First observedprotected_senders
    • First observedsender_summary
    • First observedunsubscribe
    • First observedunsubscribe_many

TDQS

A3.5/5.0

Scored across 21 tools

Disambiguation3/5

The core distinction between single-message and bulk tools is mostly clear, but bulk_by_query overlaps heavily with the dedicated bulk_* tools and with archive_message/move_message/delete_message/mark_read. archive_message also largely duplicates move_message to Archive, and find_newsletters overlaps with bulk_by_query(only_newsletters=True), so an agent has several plausible routes for the same operation.

Naming Consistency3/5

Most tools use snake_case and are readable, but the naming convention is mixed: many are verb_noun (list_messages, move_message, create_draft), while others are noun-centric or phrase-based (inbox_summary, sender_summary, bulk_by_query, protected_senders). It is not chaotic, but the pattern is not predictable enough for a high score.

Tool Count3/5

At 21 tools, the server is in the heavy borderline range. The domain is complex enough to justify many operations, but there is noticeable duplication between general bulk actions, dedicated bulk tools, and single-message action tools, which inflates the surface.

Completeness4/5

The tool set covers the main mail triage lifecycle well: folders, listing/reading messages, summaries, drafts and reply drafts, single and bulk move/delete/archive/mark operations, newsletter discovery/unsubscribe, and protected senders. Minor gaps remain, such as sending mail, attachment handling, folder rename/delete, and draft editing, but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    A lightweight MCP server for personal Microsoft Outlook/Hotmail accounts, enabling email search, reading, attachment management, and folder operations via Microsoft Graph API with OAuth device-code flow.
    6
    1
    -
  • A
    license
    A
    quality
    D
    maintenance
    Local MCP server for multi-account IMAP/SMTP email (iCloud + Gmail via app-specific passwords). Never marks mail read. Cross-folder search, idempotent sends, TLS verified.
    8
    23 PyPI
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A local MCP server that connects Claude Desktop to a personal Hotmail/Outlook.com mailbox via Microsoft Graph API, enabling email management, rule handling, and composing messages.
    25
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server providing full control over Outlook.com, Hotmail, Live, or Microsoft 365 email via Microsoft Graph API, enabling reading, searching, sending, and managing messages and folders securely.
    1
    MIT