Skip to main content
Glama

ms365-mcp

A Microsoft 365 MCP server sized for small local models.

Most MCP servers are built for frontier models with large context windows, so they expose everything the vendor API offers and let the model sort it out. The reference Microsoft 365 server exposes 326 tools generated from Microsoft's Graph OpenAPI spec.

That does not work for an 8B model at 8k context, where the entire tool list sits in the system prompt and the model starts choosing at random somewhere past twenty-five tools. This server takes the opposite approach:

  • Fourteen hand-written tools, with a hard ceiling of twenty. The tool list is a budget, not a feature list.

  • Descriptions written for a small model, not salvaged from API metadata.

  • Draft-first. Exactly one tool can transmit to another person, it takes a draft id rather than a recipient, and it is annotated destructive.

  • Every tool declares its own effect through MCP readOnlyHint and destructiveHint annotations, so a host can classify it without guessing from the tool's name.

Built for the Edge Harness, and useful to any MCP client.

Status

Feature complete, not yet run against a real account. All fourteen tools are implemented and 171 tests pass, none of which touch the network. What has not happened is the part only a real tenant can prove: a live sign-in and a Graph call that gets answered. See docs/PLAN.md for the ten commits and the reasoning behind each decision.

Scaffold, licence, CI

done

MCP protocol over stdio

done

The fourteen-tool surface

done, all fourteen implemented

Sign-in

done, untested against a live tenant

Microsoft Graph

done, tested against recorded shapes only

Retries and circuit breaker

done

Related MCP server: google-nice-mcp

Seeing the tool surface

--list-tools starts nothing and needs no account, so it answers "what would a host be offered?" before any of it is wired up:

.venv/bin/python -m ms365_mcp --list-tools

Add --json for a machine-readable version.

   read  whoami          Return the display name, email address and timezone…
   read  resolve_person  Look up a person by name or partial name and return…
   read  list_messages   List messages in a mail folder, newest first, as se…
  write  create_draft    Create a draft message. This does NOT send anything…
! write  send_draft      Send a draft that already exists, by its id. This r…
   ...
14 tools, 6 that change something, 4 marked destructive (!)

Handlers are stubs today: a call returns a sentence saying the tool is declared but not implemented. The surface is deliberately fixed before any of it is built, because the tool names, descriptions and effect classes are what a host classifies and a model is prompted against, and those are expensive to change later.

Signing in

Sign-in is the Microsoft device code flow, so there is no redirect URL to host and no secret to store. You need one thing first: the application id of an Azure app registration that has the delegated Graph permissions this server's tools declare.

export MS365_MCP_CLIENT_ID=<your app registration's application id>
export MS365_MCP_TENANT_ID=organizations   # 'consumers' for outlook.com
.venv/bin/python -m ms365_mcp --login

Then check it, before wiring anything into a host:

.venv/bin/python -m ms365_mcp --verify-login

--verify-login prints the client id, tenant, authority, scopes and cache location, and if an account is cached it calls Graph once. That last part is the point. A cached token can look completely healthy and still be refused, because a work or school tenant can withhold consent for a scope the surface needs, and that only ever shows up as a 403 on a real request. --logout forgets the account and removes the cache.

The token cache lives in the operating system's config directory, never in this repository. It is created with mode 0600 rather than written and then made private, since the gap between those two is a window where a refresh token is readable by every account on the machine. It is replaced by an atomic rename, so an interrupted write costs nothing.

Using it from the Edge Harness

The harness launches this server as a subprocess over stdio, so it runs under its own interpreter and shares no dependencies with the host. That is not incidental: the harness has a local package called mcp/ and the official SDK on PyPI is also called mcp, so installing this server into the harness's virtualenv shadows the harness's own package.

Its registry entry there is ms365-own, and pressing Check in the Agent Lab run options lists every tool with its effect class. All fourteen classify as declared, meaning the harness took them from this server's annotations rather than guessing from tool names, and the entry needs no overrides.

In the harness's default draft mode, send_draft is withheld and the other thirteen are available, so a run cannot reach a person.

Errors are raised as the SDK's ToolError rather than allowed to propagate. That is worth knowing if you are writing a handler here: the SDK treats any other exception as a crash and replaces its message with a generic one, so a sentence like "No signed-in account, run --login" is discarded before it ever reaches the model. ToolError is the deliberate-failure channel and its text survives, while the result is still flagged as an error.

Security

This repository is public and holds no credential of any kind.

Authentication uses the Microsoft device-code flow. The resulting token cache is written to the operating system's config directory with owner-only permissions, never into this repository or its working tree. .gitignore covers token and cache filenames anyway, and a pre-commit hook scans staged changes for credential-shaped strings, so committing one takes deliberate effort rather than a slip.

A line ending in # pragma: allowlist secret is skipped by the hook. That exists so this repository's own tests can contain fake credentials, and it leaves a marker a reviewer can see in the diff, which --no-verify does not. Use it only for data that is provably fake.

Development

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -q

Enable the secret-scan hook once per clone:

git config core.hooksPath .githooks

Licence

MIT. See LICENSE.

Available Tools

14 tools
cancel_eventCancel an eventA
Destructive

Cancel an event and notify every attendee. This CANNOT be undone. Read the event with get_event first and be sure it is the right one.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageNooptional note to attendees
event_idYesid from list_events

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already include destructiveHint=true, but the description adds specific behavioral consequences: every attendee is notified and the action cannot be undone. This tells the agent exactly what destructive means in this context and encourages a verification step. 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 short sentences, each carrying distinct information: purpose and effect, irreversibility, and a safety precondition. No wasted words and the most critical information 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?

The tool has only one required parameter, no output schema, and annotations covering safety. The description covers the action, side effects, irreversibility, and a verification step, which is sufficient for an agent to call it correctly. Without an output schema, return-value detail 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% — both event_id and message have descriptions. The description does not add parameter-level detail beyond the schema, though it reinforces that event_id should be verified via get_event. This meets the baseline 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 action ('Cancel an event') and its immediate effect ('notify every attendee'). This clearly distinguishes it from siblings like update_event, get_event, and create_event, and there is no delete_event competing tool. The title reinforces but does not carry the description.

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 a concrete precondition: read the event with get_event first and verify it is the right one. This tells the agent when to use the tool and the necessary safety step. It does not explicitly contrast with update_event or state when not to use, but the instruction is clear enough for correct invocation.

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

create_draftDraft a messageA

Create a draft message. This does NOT send anything: it leaves a draft a person can read and change. Get every recipient address from resolve_person first. Returns a draft id, which send_draft takes if the message is later approved.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesrecipient addresses from resolve_person
bodyYesplain text
subjectYes

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that the operation only leaves a draft, does not transmit anything, can be read and changed later, and returns a draft id. These are non-obvious behaviors that materially affect how an agent plans its work.

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 purpose and non-sending behavior, then give the prerequisite and return-value handoff. No filler or repetition.

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 key context: what is created, what is not done, the prerequisite address resolution, and the returned draft id. It does not cover every possible edge case, but it is sufficient for correct selection and 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?

The schema already documents 'to' as 'recipient addresses from resolve_person' and body as 'plain text'. The description does not add much beyond that, and the subject parameter has no useful schema description and no additional explanation in the description. Parameter semantics are adequate but not expanded.

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 ('Create a draft message') and immediately clarifies what it is not: it does NOT send anything, so it cannot be confused with send_draft or reply_draft. This clearly differentiates the tool from its 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?

It gives an explicit precondition ('Get every recipient address from resolve_person first') and explains the downstream handoff ('send_draft takes if the message is later approved'). This tells an agent exactly when and in what sequence to use the tool.

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

create_eventCreate an eventA
Destructive

Create a calendar event. If it has attendees, they are invited, which reaches real people, so get their addresses from resolve_person and check the slot with find_free_time first.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesYYYY-MM-DDTHH:MM
startYesYYYY-MM-DDTHH:MM
subjectYes
locationNo
attendeesNoaddresses from resolve_person

TDQS

A4.2/5.0
Behavior4/5

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

The description discloses that attendees are actually invited and that this reaches real people, which is valuable behavioral context beyond the annotations. It does not contradict the openWorldHint or destructiveHint annotations, and it makes the real-world side effect concrete.

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 tight sentences with no wasted words. The most important caveat—inviting real people—is front-loaded, and the required setup steps are placed right after the core purpose.

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 tool with no output schema, it covers the critical safety and precondition context well. It does not describe the return value or what happens after creation, but the essential usage guidance is present and sufficient for correct 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 coverage is 60%, and the description mainly reinforces the attendees parameter with 'addresses from resolve_person', which is already in the schema. It does add indirect context about start/end by advising a free-time check, but it adds little beyond the schema for subject and location.

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 'Create a calendar event' with a specific verb and resource, clearly distinguishing it from sibling tools like update_event and cancel_event. The additional note about inviting attendees makes the scope even clearer.

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 preconditions: get attendee addresses from resolve_person and check availability with find_free_time before creating the event. It lacks an explicit 'when not to use' or alternative routing, but the usage context is clear and actionable.

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

find_free_timeFind a free slotA
Read-only

Find open slots of a given length on a date, respecting existing events and working hours. Use this instead of reading the calendar and working out the gaps yourself, which is where arithmetic mistakes turn into double bookings.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYesYYYY-MM-DD
minutesNohow long a slot, default 30

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds behavioral context beyond the schema by noting that the search respects existing events and working hours, which helps the agent understand what influences the returned slots.

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 short, purposeful sentences. The first states the function and constraints; the second explains why to use the tool over manual calculation. No filler or redundant repetition of schema fields.

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 read-only tool, the description provides sufficient context to call it correctly: what it finds, what it respects, and why it should be preferred over manual gap calculation. It does not describe the return format, but the absence of an output schema is partly mitigated by the clear 'open slots' result implied in the description.

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 both parameters are already documented plainly: date expects YYYY-MM-DD and minutes has a default of 30. The description's phrase 'given length' only echoes the minutes parameter without adding new semantic detail, so the schema carries the load.

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 the action ('find'), the resource ('open slots of a given length on a date'), and the constraints ('respecting existing events and working hours'). It also distinguishes itself from the manual approach of reading the calendar, making its purpose easy to separate from sibling calendar 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 recommends using this tool instead of reading the calendar and computing gaps manually, which gives clear when-to-use guidance and a rationale. It does not name sibling alternatives directly, but the contrast with 'reading the calendar' is enough to orient an agent among the calendar-related siblings.

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

get_eventRead an eventA
Read-only

Read one calendar event in full, including its body and the response status of each attendee, by the id list_events returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesid from list_events

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful detail about the response contents (body and attendee response status), but does not go further into error or edge cases. This is acceptable given the simple 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?

A single, front-loaded sentence that communicates the action, resource, result contents, and ID provenance with no wasted words.

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 tool with safety annotations, the description is complete: it names the source of the identifier and the key contents returned. No critical information for invoking 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 coverage is 100%, with event_id already documented as 'id from list_events'. The description repeats this same guidance, so it adds no new semantic value 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?

States a specific verb ('Read'), a specific resource ('one calendar event'), and the distinguishing scope ('in full, including its body and the response status of each attendee'). It clearly differentiates from sibling tools like list_events and get_message.

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

Usage Guidelines4/5

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

The description indicates the correct input source ('by the id list_events returned'), which implies the prerequisite workflow of listing events first. It does not explicitly exclude alternatives, but the context is clear for a single-event read.

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

get_messageRead a messageA
Read-only

Read one message in full, including its body, by the id that list_messages returned. Read the message before replying to it or summarising it; a reply written from the subject line alone invents its own content.

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYesid from list_messages

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 destructiveHint=false, so the safety profile is covered. The description adds that the full message including its body is returned, which is useful behavioral context. It also explains why reading the full message matters before replying or summarising. No contradiction with annotations 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?

The description is two compact sentences with no filler. The core action is front-loaded in the first sentence, and the second sentence provides essential usage guidance and rationale. Every clause 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 single-parameter read-only tool with readOnlyHint and destructiveHint annotations, the description covers what is returned ('in full, including its body'), where the id comes from, and when to call it. With no output schema, the description sufficiently sets expectations for the response without needing a field-by-field breakdown.

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 documents message_id with the description 'id from list_messages', giving 100% parameter coverage. The description repeats this provenance but does not add format, type nuance, or additional meaning beyond the schema. Baseline 3 is appropriate given high 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 and resource: 'Read one message in full, including its body.' It also distinguishes itself from list_messages by clarifying that this tool retrieves the full body by an id returned from list_messages, and from get_event by focusing on messages. This makes the tool's 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 the tool: 'Read the message before replying to it or summarising it.' It also establishes the expected workflow by tying message_id to 'list_messages' and warns about the consequence of skipping this step: 'a reply written from the subject line alone invents its own content.' This gives clear context and rationale for use.

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

list_eventsList calendar eventsA
Read-only

List calendar events between two dates, with subject, start, end, location, attendees and id. Dates are YYYY-MM-DD in the account's own timezone. Check the calendar before booking anything, so a new event does not land on top of an existing one.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateYesYYYY-MM-DD, inclusive
start_dateYesYYYY-MM-DD

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral detail: the date range filtering, the account timezone handling, and the exact fields that will be returned. 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 three sentences, front-loaded with the primary behavior, then date format, then usage guidance. Every sentence earns its place and there is no unnecessary verbosity.

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 listing the returned fields. It also covers date format, timezone, and the key usage scenario. It does not mention ordering, pagination, or how to handle a single event, but for a list operation with simple parameters this is reasonably 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%, so baseline is 3. The description adds meaningful context beyond the schema by noting that dates are YYYY-MM-DD in the account's own timezone, which is not in the schema's parameter descriptions. It also clarifies the inclusive nature of the range through the end_date schema description and the returned fields.

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 lists calendar events between two dates, identifies the specific resource (calendar events), and enumerates the returned fields (subject, start, end, location, attendees, id). This distinguishes it from related tools like get_event, which targets a single event, and find_free_time, which searches availability.

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 contextual usage: 'Check the calendar before booking anything, so a new event does not land on top of an existing one.' This implies the tool should be used to avoid conflicts before creating events. It does not explicitly state when not to use it or name alternatives, so it falls short of a 5.

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

list_foldersList mail foldersA
Read-only

List the mail folders on this account with their names and message counts. Use it when a task names a folder you have not seen, rather than guessing that it exists.

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?

Annotations already mark it read-only and non-destructive. The description adds useful behavioral context by stating the scope ('on this account') and the return contents (names and message counts). 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?

Two sentences, no wasted words: the first states exactly what the tool returns and the second gives a practical usage rule. It is front-loaded and easy 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?

For a zero-parameter read-only listing tool, this description is complete: it names the output fields, the account scope, and the condition under which an agent should invoke it. No output schema exists, but the described return content is sufficient.

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 takes zero parameters, so the empty schema fully covers parameter semantics. The description adds the only relevant contextual scope, 'on this account,' which warrants the baseline-4 score.

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 object: 'List the mail folders on this account with their names and message counts.' This clearly identifies the resource and output, and distinguishes it from sibling tools like list_messages or list_events.

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 a clear trigger: use it when a task names a folder you have not seen, rather than assuming it exists. It does not name specific sibling alternatives or explicit when-not-to-use cases, but the context is unambiguous.

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

list_messagesList mailA
Read-only

List messages in a mail folder, newest first, as sender, subject, date and id. Bodies are not included; use get_message with an id to read one. Defaults to the inbox and to 10 messages.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNohow many, 1 to 50, default 10
folderNoinbox, drafts, sentitems or deleteditems, or an id from list_folders. A folder's display name will not work. Defaults to inbox.
searchNooptional words to match

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 and destructiveHint=false, and the description adds meaningful behavioral context: newest-first ordering, body exclusion, and defaults for folder and count. This is useful value 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?

Two compact sentences front-load the action, resource, and return shape, then give the important body caveat and defaults. There is no filler or unnecessary repetition.

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 supplies the returned fields and the no-body caveat, while the schema covers folder values, search, and top limits. An agent has enough context to call the tool and interpret its results 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 three parameters are already documented with defaults and allowed values. The description mostly restates the inbox and 10-message defaults rather than adding new parameter-level 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 states a specific verb and resource ('List messages in a mail folder'), names the returned fields, and distinguishes itself from get_message by explicitly saying bodies are not included. This is enough for an agent to tell it apart from related mail 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 gives clear guidance for the main alternative: 'Bodies are not included; use get_message with an id to read one.' It also explains the default folder and result count. It does not explicitly contrast with list_folders, but the essential routing decision is covered.

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

reply_draftDraft a replyA

Create a draft reply to an existing message, keeping its thread and recipients. Does NOT send. Read the message with get_message first, so the reply answers what was actually asked.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesplain text
reply_allNodefault false
message_idYesthe message to reply to

TDQS

A4.2/5.0
Behavior4/5

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

Annotations mark readOnlyHint=false and destructiveHint=false, so creating a draft is already implied as a mutating but non-destructive operation. The description adds genuinely useful behavior beyond the annotations: it preserves 'thread and recipients,' explicitly states it does not send, and recommends reading the original message first for correctness. This provides valuable behavioral context 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?

The description is only two sentences, front-loads the primary action, then states the critical caveat ('Does NOT send') and a useful workflow recommendation. Every sentence earns its place with no fluff or repetition.

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 3 simple parameters, no output schema, and no nested objects, the description covers the essential points: what it does, what it does not do, and the recommended prerequisite. It is complete enough for correct invocation. A minor gap is not explicitly distinguishing reply_draft from the sibling create_draft, but the 'existing message' framing largely handles this.

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 parameters are already documented: message_id is 'the message to reply to,' body is 'plain text,' and reply_all has a default of false. The tool description adds no extra per-parameter detail beyond the schema, so the baseline of 3 is appropriate. The 'keeping its thread and recipients' phrase hints at reply behavior but doesn't add parameter-level 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 states a specific verb and resource: 'Create a draft reply to an existing message, keeping its thread and recipients.' It also adds the key exclusion 'Does NOT send,' which distinguishes it from send_draft and clarifies its scope relative to generic create_draft.

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 this when replying to an existing message, and it explicitly warns 'Does NOT send' so agents know not to expect sending to occur. It also gives a concrete pre-step: 'Read the message with get_message first.' However, it does not explicitly name alternative tools like create_draft or send_draft for comparison, so it falls just short of full guidance.

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

resolve_personFind someone's addressA
Read-only

Look up a person by name or partial name and return their real email address. ALWAYS use this before addressing a message or inviting someone. Never type an email address you were not given. If this returns more than one person, ask which one rather than picking.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesa name, or part of one

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already provide readOnlyHint/openWorldHint/destructiveHint, and the description adds useful behavioral context: results may contain multiple people, the returned email is a 'real' address, and the agent must not guess addresses. This goes beyond the structured 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?

Three sentences, each earning its place: the first defines the core operation, the second gives an imperative usage rule, and the third resolves ambiguity. The description is front-loaded and concise with no 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 simple one-parameter read-only lookup with no output schema, the description covers invocation, the return value (email address), and the multi-result scenario. It does not detail the full response structure, but that is not necessary for the tool's stated purpose.

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 only parameter 'name' is described as 'a name, or part of one.' The description reiterates this by saying 'by name or partial name,' but it adds no additional semantic detail such as matching rules, case sensitivity, or input constraints. 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 ('Look up a person by name or partial name') and the expected outcome ('return their real email address'). It clearly distinguishes this tool from its siblings, none of which perform person resolution.

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 the tool: 'ALWAYS use this before addressing a message or inviting someone.' It also provides a behavioral rule for ambiguous results ('ask which one rather than picking') and a strong safety directive ('Never type an email address you were not given').

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

send_draftSend a draftA
Destructive

Send a draft that already exists, by its id. This reaches a real person and CANNOT be undone. There is deliberately no way to write and send in one step: create the draft, check it is right, then send it.

ParametersJSON Schema
NameRequiredDescriptionDefault
draft_idYesid from create_draft

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, readOnlyHint=false), the description explains the real consequence: it reaches a real person and cannot be undone. It also warns that there is deliberately no combined write-and-send path, which helps the agent plan the multi-step workflow.

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 direct sentences front-load the core action and consequence, then add a brief workflow note. Every sentence earns its place with no padding or repetition.

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, irreversible send operation, the description provides complete context: what is sent, by what identifier, what the consequence is, and the expected workflow. No return value is required because the behavior itself is clearly a fire-and-forget 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?

The input schema already fully describes the single parameter draft_id as 'id from create_draft', so schema coverage is 100%. The description adds only that the draft must already exist and be sent by id, which is useful but not a significant addition 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 states a specific verb and resource: send an existing draft identified by its id. It also distinguishes itself from message-creation tools by emphasizing that this is the final send step for an already-created draft.

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 tells the agent when to use the tool: after creating and checking a draft, use this to send it. It does not explicitly name alternatives like create_draft or reply_draft, but the workflow description effectively routes the agent away from using this tool for writing or replying.

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

update_eventChange an eventA
Destructive

Change the time, subject or location of an existing event. Attendees are notified. Only the fields you pass are changed. Read the event with get_event first, so you are not overwriting something you have not seen.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoYYYY-MM-DDTHH:MM
startNoYYYY-MM-DDTHH:MM
subjectNo
event_idYesid from list_events
locationNo

TDQS

A4.2/5.0
Behavior4/5

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

Annotations mark this as destructive and non-read-only; the description adds valuable context by stating that attendees are notified, only passed fields are changed, and reading first avoids overwriting unseen data. This expands on the annotation without contradicting it.

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 action, the side effect, and the critical precondition are each stated in one tight sentence. 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?

For a destructive mutation tool with no output schema and moderate complexity, the description covers the essential behaviors: partial updates, attendee notification, and the get_event precondition. It does not describe return values or null-clearing semantics, but those are not strictly required for safe invocation given the other guidance.

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 documents start/end formats and event_id source, but subject and location descriptions are empty. The description clarifies partial-update semantics by saying only passed fields are changed, which adds real value. However, it does not clarify how passing null interacts with 'only the fields you pass are changed'—whether null clears a field or is ignored—leaving ambiguity.

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 ('Change') with a concrete resource ('existing event') and enumerates the mutable fields (time, subject, location). This clearly separates it from create_event and cancel_event in the sibling tool 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 explicitly instructs the agent to read the event with get_event first, preventing blind overwrites. It implies the tool is for modifying existing events rather than creating or canceling, though it does not explicitly name alternative tools or exclusion conditions.

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

whoamiWho am IA
Read-only

Return the display name, email address and timezone of the signed-in account. Call this when the task says 'me', 'my' or 'I' and you need the actual address, rather than guessing it.

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?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds context by specifying the signed-in account scope and the return fields, which goes beyond what the annotations alone disclose.

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 first sentence defines the action and output, and the second provides the practical trigger condition. 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 parameterless tool with no output schema, the description fully covers what the agent needs: what will be returned, who it applies to, and when to call it. No important context 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 takes zero parameters, so there are no parameter semantics to document. The description correctly focuses on the return value and usage trigger, which is sufficient for a parameterless 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 states a specific action ('Return...') and names the exact resource ('the signed-in account' and its display name, email address, timezone). This clearly distinguishes it from sibling tools like resolve_person 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 Guidelines4/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: when the task says 'me', 'my', or 'I' and the actual address is needed. It also warns against guessing, giving clear practical guidance, though it does not explicitly name an alternative tool.

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. 14 tool updatesv0.1.0
    • First observedcancel_event
    • First observedcreate_draft
    • First observedcreate_event
    • First observedfind_free_time
    • First observedget_event
    • First observedget_message
    • First observedlist_events
    • First observedlist_folders
    • First observedlist_messages
    • First observedreply_draft
    • First observedresolve_person
    • First observedsend_draft
    • First observedupdate_event
    • First observedwhoami

TDQS

A4.4/5.0

Scored across 14 tools

Disambiguation5/5

Each tool targets a distinct resource and action: identity, people lookup, mail read/draft/send, and calendar read/find/write. The only close pair, create_draft and reply_draft, is clearly separated by new-vs-reply intent.

Naming Consistency4/5

Almost all tools follow a consistent verb_noun pattern (list_messages, create_draft, cancel_event). The lone exception is whoami, which is a conventional single-word command but breaks the otherwise uniform pattern.

Tool Count5/5

14 tools is a well-scoped size for a mail-plus-calendar server. Each tool covers a necessary step in reading, creating, and sending mail or managing calendar events, with no redundant utilities.

Completeness4/5

Calendar coverage is complete with list/get/find/create/update/cancel, and mail covers read, draft, reply-draft, and send. Minor gaps such as updating/deleting drafts or searching messages exist, but agents can work around them with the provided tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A production-ready MCP server that provides secure, delegated access to Microsoft 365 services including Email, SharePoint, OneDrive, and Calendar. It enables AI models to search messages, browse files, manage calendar events, and parse document contents using OAuth 2.1 authentication.
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Lightweight MCP server that enables AI agents to manage Microsoft Outlook email, calendar, and files using PKCE authentication with only a Client ID.
    46
    MIT