Skip to main content
Glama
SuperAngryMonkey

iris

iris

A Microsoft 365 mail server for AI agents that does not send email — until you decide it should.

By default iris requests the delegated Graph scope Mail.ReadWrite and never Mail.Send. The access token it holds has no capability to transmit a message, so no prompt, no jailbreak and no bug in this code can make one go out. It writes drafts into a folder in your mailbox; you open Outlook and press Send.

Sending is an explicit opt-in (IRIS_ENABLE_SEND=1) that requires granting the Mail.Send scope and re-consenting — and even then every send is human-confirmed and allowlist-checked. Leave it off (the default) and the no-send property is structural, as above. See Enabling send.

That is the whole design. Everything else is detail.


Why this shape

The usual worry about giving an agent your mailbox is that it will send something you did not sanction — to the wrong person, with the wrong tone, or because someone talked it into doing so. The common answer is a confirmation prompt, which is a guardrail: code that asks permission, and code can be bypassed.

iris removes the capability instead. Microsoft Graph will reject a send attempt made with this token, because the consent screen you approved never included that permission. The security boundary is Microsoft's, not this program's, and it holds even if this program is wrong.

The trade is real: a human is in the loop on every message, by construction. If you want autonomous sending, iris is the wrong tool.

Related MCP server: mcp-outlook-mail

Install

uvx iris-mcp        # run without installing
pip install iris-mcp

Python 3.10 or newer. macOS ships Python 3.9, which is too old — mcp requires 3.10+. Use uv (it comes with uvx and manages its own Python), or install a current Python with Homebrew (brew install python@3.12). The system python3 on macOS will not work.

Setup

You must register your own Entra application. There is no shared app registration and no hosted service — iris talks directly from your machine to your tenant. This is deliberate: a shared app would mean trusting someone else's client ID with access to your mail.

  1. Entra admin centre → App registrationsNew registration. Single tenant is fine. No redirect URI needed.

  2. Authentication → Settings → enable Allow public client flows. Device code sign-in needs this. No client secret is used anywhere.

  3. API permissions → Microsoft Graph → Delegated → add Mail.ReadWrite. For draft-only use (the default), add nothing else and leave Mail.Send off — that omission is what makes the no-send property structural. Add Mail.Send only if you intend to enable sending (see Enabling send).

  4. Copy the Application (client) ID and Directory (tenant) ID. Neither is a secret.

Then add iris to your MCP client:

{
  "mcpServers": {
    "iris": {
      "command": "uvx",
      "args": ["iris-mcp"],
      "env": {
        "IRIS_CLIENT_ID": "<application (client) id>",
        "IRIS_TENANT_ID": "<directory (tenant) id>"
      }
    }
  }
}

Sign in once: call iris_login, open the URL, enter the code, then call iris_login_finish. The token cache is written next to the server, mode 600.

Deploying to a whole team? See the Administrator Deployment Guide — authorizing iris across a Microsoft 365 tenant: admin consent, per-user assignment, and why it stays the delegated model rather than application permissions.

Clients

iris is a local stdio MCP server: your MCP client launches it as a child process on the same machine. It works with any client that supports local stdio servers — Claude Desktop, Cursor, and the Grok CLI (grok mcp add iris -- uvx iris-mcp) among them.

It does not work with clients that only accept remote MCP connectors over HTTP. The Grok app / Grok Bot is in that category — it takes hosted HTTP servers, not local stdio ones — so iris cannot attach to it as-is. Bridging iris to an HTTP transport is possible, but out of scope for this project.

Tools

Tool

What it does

iris_login

Starts device-code sign-in, returns a URL and a code

iris_login_finish

Completes sign-in; safe to call repeatedly while you type the code

iris_auth_status

Who is signed in, which scopes, and whether Graph is reachable

iris_list_folders

Lists your top-level mail folders, so you can pick one for a draft

iris_create_draft

Writes a draft (to/cc/bcc, subject, body or HTML, optional reply-to, optional folder)

iris_list_drafts

Lists what is waiting in a draft folder (optional folder)

iris_update_draft

Revises a draft in place

iris_delete_draft

Deletes a draft; requires confirm=true

iris_send_draft

Only present when IRIS_ENABLE_SEND=1. Sends an existing draft; requires confirm=true, re-checks the allowlist

Where drafts go

Into a dedicated top-level mail folder, AI Drafts by default (IRIS_DRAFT_FOLDER), created on first use. Set the variable to an empty string to use the normal Drafts folder instead.

You can also choose the folder per draft: pass folder to iris_create_draft (and iris_list_drafts) to target any folder by name, created on first use if it does not exist. Pass "" or "Drafts" for the normal Outlook Drafts folder, or call iris_list_folders first to pick from what already exists. Omitting folder uses the IRIS_DRAFT_FOLDER default, so nothing changes for existing setups.

These are real drafts and Outlook sends them normally — but because they live in their own folder, they do not appear in the Drafts view. That is the point: agent-written mail sits somewhere you have to go and look, rather than mixed in with your own half-finished messages.

One wrinkle worth knowing: Graph's createReply always lands a reply in Drafts first, so iris moves it afterwards, and a move assigns a new message id.

Enabling send

Sending is off by default and, by design, takes three deliberate steps — miss any one and iris still cannot send:

  1. In your Entra app registration, add Mail.Send (Delegated) alongside Mail.ReadWrite.

  2. Set IRIS_ENABLE_SEND=1 in the server's environment. Only then is Mail.Send requested and the iris_send_draft tool registered at all.

  3. Run iris_login again to re-consent — the cached token predates the new scope and will not carry it until you do.

Then iris_send_draft(draft_id, confirm=true) sends an existing draft. It refuses without confirm, re-verifies the message is still an unsent draft, and re-runs the recipient allowlist before sending. The flow stays compose → review → send; iris never composes and sends in one shot.

Understand the trade. With send off, "cannot send" is enforced by Microsoft against your consent and holds even if this code is wrong. With send on, the last line of defence is a per-call confirmation — a guardrail in this code, which is exactly the kind of check a bug or a cleverly-worded prompt can talk past. Enable it only where that weaker guarantee is acceptable.

Other controls

  • Recipient allowlistrecipients.allow, one address or domain per line. Absent or empty means all recipients are permitted. Point IRIS_ALLOWLIST elsewhere if you prefer.

  • Kill switch — create a DISABLED file beside the server, or set IRIS_DISABLED=1, and every tool refuses.

  • Audit log — every call is appended to audit.log (IRIS_AUDIT_LOG).

Limits

No attachments. No shared or delegated mailboxes — /me only. No folder nesting via parentFolderId. Sign-in is delegated device-code as a public client, so the blast radius is exactly one mailbox: yours.

Security

The no-send guarantee, how to verify it yourself, and — just as important — what iris can reach with Mail.ReadWrite: see SECURITY.md.

License

MIT — see LICENSE.

Available Tools

8 tools
iris_auth_statusA

Report whether iris is signed in, as whom, and with what scopes.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations present, the description carries the full burden, and it does reasonably by communicating that this is a read-only reporting operation returning identity and scopes. It does not mention side effects or whether an existing session is required, but the reporting verb strongly implies non-destructive introspection.

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 sentence containing no filler. It front-loads the action and delimits exactly what the report will contain.

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 status checker with an output schema present, the description is fully sufficient: it tells the agent what the tool reports and implies no required setup. No important missing context is identifiable.

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

Parameters4/5

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

The tool has zero parameters and the schema coverage is 100%, so no parameter documentation is needed. The description contributes to semantics by listing the output dimensions (signed-in state, identity, scopes), which compensates for the lack of any exposed data.

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

Purpose5/5

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

The description names a specific verb ('Report'), a clear resource ('iris signed-in state'), and the exact information returned (whether signed in, which user, what scopes). It is clearly distinct from siblings like iris_login and iris_create_draft, which perform different operations.

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

Usage Guidelines3/5

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

The description implies when to use the tool — to inspect the current auth status — but does not state any exclusions nor explicitly contrast it with the login/draft siblings. An agent can infer the right use case, but the guidance is not made explicit.

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

iris_create_draftA

Compose a message into a mail folder as an unsent draft. It is NOT sent — a human opens Outlook and presses Send.

folder selects the destination folder by display name, created on first use if absent. Omit it to use the configured default (IRIS_DRAFT_FOLDER, currently "AI Drafts"); pass "" or "Drafts" for the normal Outlook Drafts folder. Set reply_to_message_id to draft a threaded reply.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYes
bccNo
bodyYes
htmlNo
folderNo
subjectYes
reply_to_message_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/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. It discloses that the draft is not sent, that a human must send it, that folders are created on first use, and that passing '' or 'Drafts' targets the normal Drafts folder. It does not cover authentication or rate limits, but for a draft-creation tool these are less critical. The key side-effect (not sending) is prominently disclosed.

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 concise paragraphs. The first sentence states the core purpose and the not-sent caveat. The second paragraph focuses on the two parameters that need explanation (folder and reply_to_message_id). No fluff, every sentence earns its place, and the most important information (not sent) is front-loaded.

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 an 8-parameter tool with no annotations and an output schema present, the description covers the essential aspects: purpose, non-sending, folder behavior, and reply threading. It does not explain the html parameter's meaning (HTML vs plain text), which could be relevant, but the output schema may cover return values. Overall it is sufficient for an agent to use correctly.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate. It explains folder (selection by display name, creation on first use, default, special values) and reply_to_message_id (threaded reply) in detail. It does not elaborate on cc, bcc, or html, but these are conventional email fields; to, subject, body are self-explanatory. Given the low coverage, the description adds meaningful semantics for the non-obvious parameters.

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

Purpose5/5

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

The description clearly states the action (compose a message into a mail folder as an unsent draft) and explicitly distinguishes it from sending by noting it is NOT sent. It also differentiates from sibling tools by focusing on creation rather than update/delete. The verb+resource combination is specific and unambiguous.

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

Usage Guidelines4/5

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

The description provides clear usage context for the folder parameter (including default behavior and special values) and for reply_to_message_id (threaded replies). It also implies when not to use this tool (if the intent is to send). However, it does not explicitly name alternative tools like iris_update_draft or iris_send (if it existed), so the guidance is good but not exhaustive.

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

iris_delete_draftA

Delete a draft. Destructive, so confirm=true is required — set it only after the human has explicitly approved deleting this specific draft.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNo
draft_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly labels the operation as 'Destructive' and explains the confirmation requirement and human-approval condition. While it implies irreversibility through the word 'destructive', it does not explicitly state that the deletion is permanent or mention any side effects. However, it covers the critical safety behavior well.

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, concise sentence that front-loads the purpose ('Delete a draft') and immediately provides a critical warning about the confirmation flag. Every word earns its place with no redundancy or fluff.

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

Completeness4/5

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

For a simple delete operation, the description adequately covers the essential behavioral aspects: destructive nature, confirmation requirement, and human-approval condition. The presence of an output schema (not shown) likely covers return values and errors. While it could explicitly state that deletion is irreversible, 'destructive' effectively communicates this. Overall, it is complete enough for an agent to call the tool correctly.

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

Parameters4/5

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

The schema provides no descriptions (0% coverage), so the description must compensate. It adds crucial meaning to the confirm parameter by stating it is required and only to be set after human approval, which the schema does not convey. The other parameter, draft_id, is self-explanatory given the tool's purpose, so the description's contribution is sufficient.

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 operation as 'Delete a draft' with a specific verb and resource. It is distinct from sibling tools like iris_create_draft, iris_update_draft, and iris_list_drafts, which involve different actions. No ambiguity exists about what the tool does.

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 provides usage guidance: confirm=true is required and should only be set after human approval. This tells the agent when it is appropriate to invoke the tool and under what conditions, effectively differentiating it from non-destructive alternatives.

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

iris_list_draftsA

List recent messages sitting in a draft folder. folder selects which one by display name; omit it for the configured default (IRIS_DRAFT_FOLDER), or pass "" / "Drafts" for the normal Outlook Drafts folder.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
folderNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It implies a read-only operation through 'list' but does not explicitly state that it is non-destructive, nor does it mention any side effects, authentication requirements, or pagination behavior. It also leaves 'recent' undefined, which could affect expectations about ordering or limits.

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

Conciseness5/5

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

The description is two sentences with no wasted words. The primary purpose is front-loaded, and the folder parameter details are presented compactly. It is an efficient, well-structured definition.

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 list tool, the description covers the main use case and the folder parameter thoroughly. It does not explain the limit parameter or the meaning of 'recent', but the output schema likely documents the return format, and the limit has a clear default in the input schema. Given the low complexity and presence of an output schema, this is adequate, though not exhaustive.

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 description adds meaningful detail for the folder parameter, explaining how to select it by display name and the default behavior. However, it entirely omits the limit parameter, which has no schema description (coverage 0%). Since the description must compensate for both parameters, it only partially fulfills this duty.

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

Purpose5/5

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

The description clearly states the action (list) and resource (recent messages in a draft folder), and the folder parameter's behavior distinguishes it from siblings like iris_list_folders (which lists folders, not messages) and iris_create_draft. The purpose is unambiguous and specific.

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

Usage Guidelines4/5

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

It provides clear context on when to use the tool (when you want to list drafts) and explains the folder parameter's usage with default and explicit values. However, it does not explicitly mention alternatives or exclusions, such as suggesting iris_list_folders to discover folder names, so it stops 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.

iris_list_foldersA

List the mailbox's top-level mail folders (name, id, unread/total counts) so you can pick one to pass as the folder argument to iris_create_draft or iris_list_drafts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It discloses the read-only nature implicitly by describing a listing action and specifies the output scope (top-level folders) and fields. It doesn't mention authentication requirements or pagination, but for a parameterless list operation this is a minor gap, not a contradiction.

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: the first states the action and output, the second explains its purpose. No filler, no repetition, and the key information is front-loaded.

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

Completeness4/5

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

Given the tool's simplicity, the description covers the what, why, and how it feeds into other tools. The output schema already documents the return shape, so the description needn't repeat it. It could mention authentication prerequisites, but the presence of iris_auth_status in the sibling set makes that an implied step for the agent.

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 baseline is 4. The description adds no parameter-specific meaning because none exists; the schema is empty and the description correctly focuses on the operation and output.

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 (List), a precise resource (the mailbox's top-level mail folders), and enumerates the returned fields (name, id, unread/total counts). It also names the downstream consumers (iris_create_draft, iris_list_drafts), which clearly distinguishes it from the draft and auth siblings without needing to open their schemas.

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 use case: pick a folder to pass as the `folder` argument to two named sibling tools. This makes the intended context explicit. It doesn't state exclusions (e.g., when not to use), but since there is no competing folder-listing tool, the guidance is sufficient.

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

iris_loginA

Start a device-code sign-in for the mailbox. Returns a URL and a code for the human to enter in a browser; then call iris_login_finish() to complete. Only needed once, or after the refresh token lapses.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior3/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It does explain the interactive flow (returns URL/code for human entry, requires a follow-up call) and the condition for reuse, which is valuable. However, it does not disclose potential side effects (e.g., invalidating existing tokens), whether the call is blocking, or error behavior if invoked multiple times. A 3 reflects this moderate level of 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?

The description is two sentences with no filler. It front-loads the primary action, then immediately gives the return values and next step, and ends with the usage condition. Every sentence earns its place and there is no redundancy with the schema.

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

Completeness5/5

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

Despite having an output schema, the description explains the meaningful output (URL and code) in plain terms, which the schema may not convey. It also covers the workflow (call finish after) and the lifecycle condition. For a login-initiation tool with no parameters, nothing an agent needs to call it correctly is missing.

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

Parameters4/5

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

The tool has zero parameters, so the description has no parameter semantics to add. The baseline for 0 parameters is 4; the description appropriately mentions 'the mailbox' but that refers to the overall context, not a specific parameter. There is no gap to compensate for.

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

Purpose5/5

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

The description clearly states the action ('Start a device-code sign-in'), the resource ('the mailbox'), and the specific protocol (device-code), distinguishing it from siblings like iris_login_finish (which completes the sign-in) and iris_auth_status (which presumably checks status). It also mentions the return values (URL and code), leaving no ambiguity about what the tool does.

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: 'Only needed once, or after the refresh token lapses.' It also names the next step, iris_login_finish(), and implies that if you already have a valid token you don't need to call this. This is clear guidance on when to use vs. alternatives.

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

iris_login_finishA

Complete a device-code sign-in started with iris_login(). Call after entering the code in the browser. Waits up to ~60s; if the code has not been entered yet, it says so and can simply be called again.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON 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 are provided, so the description carries the burden of behavioral disclosure. It transparently reveals that the tool waits up to ~60 seconds and how it behaves when the code hasn't been entered (returns a notice and can be retried). It does not explicitly describe success behavior or side effects, but the existence of an output schema may cover the return format. The disclosure of timing and retry is valuable and beyond what the empty schema provides.

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

Conciseness5/5

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

The description is two sentences with no redundant words. The first sentence states the action and prerequisite; the second explains the wait and retry behavior. Information is front-loaded, with the primary purpose stated before the behavioral details. Every sentence earns its place, and there is no fluff.

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

Completeness5/5

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

For a tool with no parameters, an output schema, and a simple role in the login flow, the description covers the essential usage context. It explains the prerequisite (iris_login was called), the triggering condition (code entered), the wait behavior, and the retry logic. Nothing critical is missing that would prevent an agent from calling it correctly.

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

Parameters4/5

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

The tool has zero parameters, so the baseline is 4. The schema has no properties to describe, and the description does not need to add parameter-level meaning. Any context about the sign-in flow is already covered by the purpose and usage guidelines, so the parameter semantics are trivially satisfied.

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 completes a device-code sign-in initiated by iris_login(), using a specific verb (complete) and resource (sign-in). It immediately distinguishes itself from iris_login, which starts the flow, and from other sibling tools like iris_auth_status and draft management functions, leaving no ambiguity about its role.

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

Usage Guidelines4/5

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

The description explicitly states when to call it ('after entering the code in the browser') and provides retry guidance ('can simply be called again' if the code isn't entered). While it implies the prerequisite of having called iris_login(), it does not explicitly name alternative tools for excluding use cases, such as iris_auth_status for checking status. However, the flow is so clearly delineated that an agent would not confuse it with other tools.

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

iris_update_draftA

Revise an existing draft in place. Only the fields you pass are changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toNo
bccNo
bodyNo
htmlNo
subjectNo
draft_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It explicitly states the partial-update behavior, which is a valuable disclosure beyond the schema. However, it omits error handling, idempotency, or what happens if the draft does not exist, leaving behavioral gaps.

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, focused sentences with no wasted words. The core action is front-loaded, and the second sentence clarifies the update semantics effectively.

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

Completeness3/5

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

Given the tool's simplicity and presence of an output schema, the description is mostly adequate. However, missing context on error behavior or authentication (given no annotations) leaves room for improvement, making it minimally viable.

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. The phrase 'Only the fields you pass are changed' adds key partial-update semantics beyond the raw schema. Yet no per-parameter details are given, though parameter names are self-explanatory.

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 the specific verb 'Revise' with 'existing draft' and 'in place,' clearly identifying the target resource and distinguishing it from creation or other operations. This directly differentiates the tool from siblings like iris_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 Guidelines3/5

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

The usage context (update an existing draft) is implied but no explicit when/when-not guidance or alternatives are given. It doesn't mention that creating a new draft should use the sibling tool, leaving usage to be inferred.

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. Dates show when Glama detected each change.

  1. 3 tool updatesv0.2.1
    • Changediris_create_draft1 field changed
      • addedInput schema / properties / folder
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Folder"
        +}
    • Changediris_list_drafts1 field changed
      • addedInput schema / properties / folder
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Folder"
        +}
    • Addediris_list_folders
  2. 7 tool updatesv0.1.0
    • First observediris_auth_status
    • First observediris_create_draft
    • First observediris_delete_draft
    • First observediris_list_drafts
    • First observediris_login
    • First observediris_login_finish
    • First observediris_update_draft

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: login steps, auth status, and CRUD operations on drafts. There is no ambiguity between them; even the two login tools are sequentially distinct with clear descriptions.

Naming Consistency5/5

All tools follow a consistent iris_ prefix followed by verb_noun naming (e.g., iris_create_draft, iris_list_folders). The pattern is uniform and predictable.

Tool Count5/5

8 tools is well-scoped for the domain of draft management and authentication. Each tool serves a necessary function without redundancy or bloat.

Completeness5/5

The tool set covers the full draft lifecycle (create, list, update, delete) plus necessary folder listing and authentication flow. There are no obvious missing operations for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to interact with Microsoft 365 Outlook Mail, allowing email operations via natural language.
    29
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to read and manage Microsoft 365/Outlook email and calendar, with destructive actions (send email, create event) requiring human approval.
    8
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI coding agents to search, read, and manage drafts across Gmail and Outlook mailboxes via MCP.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SuperAngryMonkey/iris'

If you have feedback or need assistance with the MCP directory API, please join our Discord server