Skip to main content
Glama
hgn

Notmuch

by hgn

mcp-server-notmuch

An MCP server that exposes a local notmuch email database to an LLM client such as Claude. It is read-first: searching, reading, and understanding mail is always available; writing anything (drafts, tags, exported files) requires an explicit opt-in flag and is confined to clearly bounded locations.

It never sends mail. There is no send capability anywhere in this codebase, in any mode, with any flag. Drafts are written to a local maildir for you to review and send yourself in a real mail client.

What it does

  • Searches and reads your mail (threads, single messages, attachments, calendar invites, office documents, images) via the real notmuch CLI.

  • Understands scopes: a named, pre-configured notmuch query (e.g. "personal mail" vs. "mailing lists") that every search is confined to unless you ask otherwise.

  • Answers "what's still unanswered" and "who owes me a reply" (mail_pending), "has this come up before" (mail_related_threads), and gives a token-cheap overview of a long thread before you read all of it (mail_thread_overview).

  • Optionally composes and revises plain-text drafts (--allow-drafts), tags messages (--allow-tags), or exports attachments and a Gource visualization of your mailbox history to a directory you name (--allow-export DIR).

Related MCP server: notmuchproxy

What it does not do

  • It does not send mail. Ever.

  • It does not modify your mail in any way unless you pass --allow-tags (tagging) or --allow-drafts (writing a new file into a drafts maildir). Neither flag lets it touch existing messages' content.

  • It does not read or write outside the notmuch database, the configured drafts maildir, and (only with --allow-export) the configured export directory.

  • It does not require or use the notmuch2 Python bindings, so no compiler is needed to install it.

Install

From PyPI (once published)

$ uvx --prerelease=allow mcp-server-notmuch --help

From source

$ git clone https://github.com/hgn/mcp-server-notmuch
$ cd mcp-server-notmuch
$ uv pip install --prerelease=allow -e .
$ mcp-server-notmuch --help

The --prerelease=allow is required because this project pins a pre-release of the mcp SDK (see SDK version below); it is not optional.

System requirements

  • notmuch (the CLI, not just the library) on PATH or pointed to via notmuch.binary in the config.

  • poppler-utils (pdftotext) to read PDF attachments. Without it, mail_read_attachment on a PDF names the missing package.

  • pandoc or libreoffice to read office documents (doc/docx/odt/rtf). Without either, the error names both options.

  • Optionally, Pillow (pip install 'mcp-server-notmuch[image]') to let oversized image attachments be downscaled instead of refused.

  • Optionally, Gource to actually play back the log mail_export_gource writes.

MCP client configuration

Claude Code

Read-only (the default: search and read tools only):

$ claude mcp add notmuch -- uvx --prerelease=allow mcp-server-notmuch

With drafts enabled (also allows revising/tagging as needed):

$ claude mcp add notmuch -- uvx --prerelease=allow mcp-server-notmuch --allow-drafts

Or by hand in .mcp.json:

{
  "mcpServers": {
    "notmuch": {
      "command": "uvx",
      "args": ["--prerelease=allow", "mcp-server-notmuch", "--allow-drafts"]
    }
  }
}

Claude Desktop

Add to claude_desktop_config.json (read-only default):

{
  "mcpServers": {
    "notmuch": {
      "command": "uvx",
      "args": ["--prerelease=allow", "mcp-server-notmuch"]
    }
  }
}

With drafts enabled:

{
  "mcpServers": {
    "notmuch": {
      "command": "uvx",
      "args": ["--prerelease=allow", "mcp-server-notmuch", "--allow-drafts"]
    }
  }
}

Configuration

The server reads $XDG_CONFIG_HOME/mcp-server-notmuch/config.toml (~/.config/mcp-server-notmuch/config.toml if XDG_CONFIG_HOME is unset), or a path given with --config. A missing file is not an error: the server falls back to the system notmuch binary and a single built-in scope all with an empty query. Once a file exists, [scopes] is authoritative and all is no longer implied.

See config.example.toml for a fully commented reference file. Summary of every key:

Section

Key

Default

Meaning

[notmuch]

binary

"notmuch"

Path or bare name of the notmuch binary.

config

notmuch's own default

Path passed as NOTMUCH_CONFIG.

[limits]

max_body_chars

unset (unlimited)

Message body truncation point; unset means full body every time.

max_attachment_chars

unset (unlimited)

Attachment/office/calendar text truncation point; unset means full text every time.

max_image_bytes

5242880

Image size ceiling; downscaled with Pillow if larger, else refused.

[scopes]

default

(required once [scopes] exists)

Scope used when a tool call omits scope.

[scopes.<name>]

query

A notmuch query ANDed with every search using this scope.

description

""

Shown by mail_list_scopes.

[drafts]

maildir

unset

Root of a maildir (cur/, new/, tmp/) for mail_create_draft.

from

unset

From: header on every draft.

signature

unset

Plain-text signature file, appended on request.

wrap_columns

72

Hard-wrap width for drafted plain text.

max_total_attachment_bytes

26214400 (25 MiB)

Ceiling on draft attachments' combined size.

[identity]

addresses

notmuch's user.primary_email/user.other_email

Your own address(es); used to exclude yourself from reply-all and to detect mail_pending direction="waiting".

mail_create_draft/mail_update_draft refuse to run unless both drafts.maildir and drafts.from are set. mail_pending direction="waiting" needs [identity] addresses (or a readable notmuch user.primary_email) to know which address is "you".

Nothing is truncated by default. This is a local, fast mailbox, not a rate-limited API: mail_search, mail_pending, mail_related_threads, mail_list_addresses, mail_find_attachments and mail_export_gource all return every matching row unless a tool call passes an explicit limit, and message bodies/attachment text come back in full unless limits.max_body_chars/limits.max_attachment_chars are set. Whenever an explicit limit or char cap does cut something, the output says so: "Showing N of TOTAL ..." plus a hint to omit limit to see everything. There is no silent, invisible ceiling anywhere in this server.

Scope resolution: a tool's scope argument names a configured scope; its query is ANDed with the caller's query, both sides parenthesized ((scope_query) and (user_query)), so an or on either side cannot leak past the other. An unknown scope name is an error listing the configured scopes; scope="all" is never silently unfiltered unless you define a scope literally named all.

Tiers and tools

Four tiers. The read tier is always registered. The other three are registered only when their flag is passed — there is no "registered but refused" state, an unauthorized tool is simply absent from the tool list a client sees.

Flag

Registers

(none)

Read tier: search, read, list, prepare — nothing is written.

--allow-drafts

Draft tier: compose and revise local plain-text drafts.

--allow-tags

Tag tier: add/remove tags on existing messages.

--allow-export DIR

Export tier: write attachments/a Gource log into DIR.

Read tier (always on)

Tool

Purpose

mail_search

Search threads or messages, paged; returns everything unless limit caps it.

mail_read_thread

Every message in a thread, oldest first.

mail_thread_overview

One line per message (date/size/from), tree or flat layout, before reading a long thread in full.

mail_related_threads

Heuristic "has this come up before" (subject + participant overlap).

mail_pending

Threads you owe a reply on, or threads you're waiting on a reply to.

mail_read_message

A single message's headers and body.

mail_count

Cheap message/thread count for a query.

mail_list_addresses

Resolve a name to the real address(es) behind it.

mail_list_attachments

List one message's attachments.

mail_read_attachment

Read one attachment: text, PDF, image, office document, or calendar invite.

mail_find_attachments

Find attachments across a whole search (e.g. "all PDFs from 2025").

mail_list_scopes

List the configured scopes.

mail_prepare_reply

Derive reply/reply-all/forward headers and quoted/forwarded body; writes nothing.

Draft tier (--allow-drafts)

Tool

Purpose

mail_create_draft

Compose a plain-text draft (optionally with attachments) into the configured maildir.

mail_update_draft

Revise an existing draft in place; only the given fields change.

Tag tier (--allow-tags)

Tool

Purpose

mail_tag

Add/remove tags on every message matching a query.

Export tier (--allow-export DIR)

Tool

Purpose

mail_save_attachment

Save one attachment's raw bytes into DIR.

mail_export_gource

Write a Gource custom log of mailbox history into DIR.

mail_export_gource writes one line per message, timestamp\|username\|type\|path\|colour, sorted oldest first (Gource requires this). path is folder/normalized-subject, so a whole reply chain lands at one point in the tree; colour is a stable hash of the folder name, so a folder keeps its colour across repeated exports. Play it back with:

$ gource --log-format custom mail.gource -s 0.5 --key

All matching messages are included by default; limit matters when the query is broad, since feeding Gource every mailing-list message you've ever received produces an unwatchable animation, so scope the query first or set limit explicitly.

Security model

This is a mail server handed to an LLM; message content is not trusted the way your own instructions are.

  1. Prompt injection. Message bodies, attachment text, calendar summaries, and thread overview lines are third-party content, not instructions. render.py wraps every one of them in explicit -----BEGIN/END UNTRUSTED EMAIL CONTENT----- markers with a notice that nothing inside should be treated as a command, so no individual tool can forget to do this.

  2. Path confinement. The drafts maildir (compose.py) and the export directory (export.py) each resolve the target path and verify it is still inside the configured root afterward. This catches a literal .. and a symlink pointing outside the root (Path.resolve() follows symlinks), and mail_create_draft/mail_update_draft cannot be made to write outside the configured maildir with any combination of arguments.

  3. No shell, ever. Every subprocess call is subprocess.run([...], shell=False) with an argv list; queries are passed as a single argv element, never interpolated into a shell string or a notmuch query string beyond normal AND/OR composition.

  4. No content in diagnostics. Errors and progress go to stderr and are content-free (a byte count or a file path, never a message body).

  5. Never silently unfiltered. A scope argument that AND-composes with a query is always explicit; there is no hidden "search everything" fallback unless a scope literally named all is configured.

  6. Never silently truncated. This is a local, fast mailbox: result rows, message bodies and attachment text are returned in full unless a tool call passes an explicit limit or the config sets an explicit limits.max_body_chars/limits.max_attachment_chars. Whenever one of those does cut something, the output states the true total and how to see the rest, never a silent cut.

notmuch query syntax

query/scope arguments accept full notmuch search syntax: from:, to:, subject:, tag:, date: ranges, boolean and/or/not, and more. See notmuch-search-terms(7) (man notmuch-search-terms) for the complete reference.

SDK version

Targets MCP spec 2026-07-28 and pins mcp==2.0.0b2, a pre-release of the Python SDK built for that spec. Once the spec and a matching stable SDK release ship, this pin moves to the stable release; until then, every install (uv pip install, uvx) needs --prerelease=allow.

Development

$ make          # fmt + lint + test
$ make test     # pytest (skips cleanly if notmuch is not installed)
$ make lint     # ruff format --check + ruff check
$ make help     # list all targets

Tests build a small crafted maildir and run real notmuch commands against it; nothing touches your real mail. CI runs on Python 3.11, 3.12 and 3.13 with notmuch installed via apt.

License

MIT, see LICENSE.

Available Tools

13 tools
mail_countCount mailA
Read-only

Count messages or threads matching a query, without fetching any of them.

Cheap way to check whether a correspondent, subject or thread exists at all before running a full mail_search, e.g. "how many mails did I get from X" (count="messages", the right default) versus "how many separate conversations" (count="threads"). Not a substitute for mail_search when you need to see the matches themselves.

Args: query: A notmuch query, e.g. 'from:alice'. See notmuch-search-terms(7) for the full syntax, including relative date ranges such as 'date:this_year..', 'date:last_month..', 'date:1Y..' and 'date:2026-01-01..2026-06-30'. scope: Name of a configured scope to AND with query (see mail_list_scopes). Defaults to the configured default scope. count: 'messages' or 'threads'.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNomessages
queryYes
scopeNo

TDQS

A4.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, but the description adds valuable behavior: 'without fetching any of them' clarifies that no message content is retrieved, and 'cheap way' signals performance characteristics. This goes beyond the annotation's basic safety profile, though it doesn't cover all possible edge cases.

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

Conciseness5/5

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

The description is front-loaded with the core statement, followed by usage context and an Args section. Every sentence adds value—examples for query syntax, scope behavior, and count semantics are all relevant. 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 count tool with no output schema, the description sufficiently implies the return value (a count) while covering query syntax, scope, and count modes. The mention of default scope and examples of date ranges makes it complete for the tool's complexity.

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

Parameters5/5

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

Even though schema property descriptions are absent (0% coverage), the description thoroughly explains each parameter: the query syntax with notmuch examples and date ranges, the scope default behavior, and the count options ('messages' or 'threads'). This fully compensates for the schema's lack of descriptions.

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

Purpose5/5

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

The description opens with 'Count messages or threads matching a query'—a specific verb and resource that clearly states the tool's function. It distinguishes itself from siblings by explicitly stating it doesn't fetch matches and is not a substitute for mail_search.

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

Usage Guidelines5/5

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

Provides explicit usage context: it's a 'cheap way to check whether a correspondent, subject or thread exists' before running a full mail_search, and explicitly says 'Not a substitute for mail_search when you need to see the matches themselves.' This gives clear when-to-use and when-not-to-use guidance relative to alternatives.

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

mail_find_attachmentsFind mail attachmentsA
Read-only

Find attachments across a whole search, not just within one message.

Use this for questions like "all invoices from 2025" or "which PDFs did I get from the accountant", where the attachment itself, not the message, is what you are looking for. For a single message's attachments, use mail_list_attachments instead. Note that notmuch's own query syntax already supports 'attachment:*.pdf' and 'tag:attachment' inside query if you want to filter at the notmuch level too.

Args: query: A notmuch query selecting the messages to scan for attachments. scope: Name of a configured scope to AND with query (see mail_list_scopes). Defaults to the configured default scope. type: Filter by 'pdf', 'image', 'doc' (office documents), or a raw filename extension such as 'png' or 'xlsx'. Omit for no filter. limit: Maximum number of attachment rows to return. Omit for all results (the default); set it only to cap the number returned, and when it truncates the total is still reported.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
limitNo
queryYes
scopeNo

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already mark the tool as readOnlyHint=true and openWorldHint=false, which covers the safety profile. The description adds behavioral context beyond annotations: it explains the search scope (across a whole search), the `limit` parameter's truncation behavior ('when it truncates the total is still reported'), and scope defaulting. It does not discuss auth or return format, but for a read-only search tool this is adequate.

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 well-structured: a one-sentence purpose, then usage guidance with examples, a note about query-level filtering, and an Args section. Every sentence adds value—no filler or repetition. The front-loaded purpose makes it easy to scan, and the Args section is formatted for quick reference.

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 4 parameters, no output schema, and no enums, this description covers the core usage well: what the tool does, when to use it, parameter semantics, and limit behavior. It does not describe the structure of returned attachment rows (e.g., fields like filename, size, message ID), which could be helpful given there is no output schema. Still, the lack of such detail does not prevent correct invocation for the described purposes.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must fully compensate. It does: each parameter (query, scope, type, limit) has a clear explanation with examples and default behavior. For instance, `type` is defined with categories and raw extensions, and `limit` clarifies that omission means all results while truncation still reports the total.

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 'Find attachments across a whole search, not just within one message', which is a specific verb+resource+scope statement. It clearly distinguishes itself from the sibling mail_list_attachments by explaining the different scope ('a whole search' vs 'a single message').

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

Usage Guidelines5/5

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

The description provides explicit when-to-use guidance with concrete examples ('all invoices from 2025', 'which PDFs did I get from the accountant') and an explicit alternative for single-message cases: 'use mail_list_attachments instead'. It even notes the notmuch query-level filtering alternative (attachment:*.pdf, tag:attachment).

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

mail_list_addressesList mail addressesA
Read-only

Resolve a name or query into the concrete email addresses behind it.

Searching from: directly is unreliable: it also matches mail that merely mentions the name in a display name (e.g. a share notification like "Kathrin Pietsch (via Google Keep) <keep-shares@ google.com>"), and a name can belong to more than one real address or person. Call this tool first whenever you only have a name, then search or count using the address(es) it returns.

Args: query: A notmuch query, typically a name fragment, e.g. 'kathrin'. scope: Name of a configured scope to AND with query (see mail_list_scopes). Defaults to the configured default scope. output: 'sender' (addresses this query's messages were From), 'recipients' (addresses in To/Cc/Bcc), or 'count' (sender addresses ranked by occurrence count, the way to find someone's most-used address among several). limit: Maximum number of addresses to return. Omit for all results (the default); set it only to cap the number returned, and when it truncates the total is still reported.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
scopeNo
outputNosender

TDQS

A5/5.0
Behavior5/5

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

While annotations provide readOnlyHint=true, the description adds critical behavioral details: it explains that query is a notmuch query, describes the three output modes and their semantics, and discloses limit truncation behavior ('when it truncates the total is still reported'). It also surfaces a subtle pitfall about display-name matching, which goes well beyond annotation data.

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

Conciseness5/5

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

The description is compact and front-loaded with the core purpose, then usage rationale, then detailed parameters. Every sentence earns its place—there is no fluff or repetition. The Args block follows a consistent, scannable format, making the information 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?

With four parameters and no output schema, the description covers all essential aspects: purpose, usage context, parameter semantics, and even edge-case behavior (unreliable direct matching, truncation reporting). It provides enough information for an agent to select and invoke the tool correctly without external docs.

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

Parameters5/5

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

The input schema provides no descriptions (0% coverage), so the description carries the full burden. Each parameter receives thorough explanation: query with an example, scope with a reference to mail_list_scopes, output with explicit modes and meanings, and limit with default and truncation semantics. This fully compensates for the schema's silence.

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 clear, specific verb-resource pairing: 'Resolve a name or query into the concrete email addresses behind it.' It distinguishes itself from sibling tools by focusing on address resolution rather than message search, read, or count operations. The purpose is immediately understandable and not a tautology.

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

Usage Guidelines5/5

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

The description explicitly tells the agent when to use this tool: 'Call this tool first whenever you only have a name, then search or count using the address(es) it returns.' It also warns against the unreliable alternative of using from:<name> directly in search, providing concrete when-not-to-use guidance and setting expectations for subsequent steps.

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

mail_list_attachmentsList mail attachmentsA
Read-only

List a message's attachments (part index, filename, content type, size).

Call this before mail_read_attachment to learn valid part_index values; it does not return attachment content itself.

Args: message_id: A Message-ID as seen in mail_search/mail_read_thread output.

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYes

TDQS

A4.7/5.0
Behavior4/5

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

The description adds behavioral context beyond the readOnlyHint annotation by stating that the tool returns metadata (part index, filename, content type, size) and not content. This is useful, though the annotation already covers safety.

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

Conciseness5/5

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

The description is concise and well-structured: it starts with the main purpose, then gives usage guidance, and ends with an Args section. Every sentence earns its place without unnecessary 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 simple one-parameter tool without an output schema, the description is complete: it lists the return fields, states what it does not return, and positions it relative to sibling tools. No critical information is missing.

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

Parameters4/5

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

With 0% schema description coverage, the description compensates by explaining that message_id should be 'as seen in mail_search/mail_read_thread output', providing source context. This adds meaningful value over the schema alone.

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

Purpose5/5

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

The description clearly states the tool's function: 'List a message's attachments (part index, filename, content type, size)'. It uses a specific verb and resource, and explicitly distinguishes itself from sibling tools like mail_read_attachment by noting it does not return content.

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

Usage Guidelines5/5

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

The description gives explicit usage guidance: 'Call this before mail_read_attachment to learn valid part_index values'. It also clarifies what the tool does not do ('does not return attachment content itself'), helping the agent choose the right tool.

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

mail_list_scopesList mail scopesA
Read-only

List the configured scopes with their notmuch query and description.

Call this to discover valid scope values for mail_search/mail_count/ mail_tag instead of guessing scope names.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true. The description adds value by specifying the output includes notmuch query and description, behaviorally enriching beyond the annotation.

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

Conciseness5/5

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

Two sentences: first states purpose, second provides usage guidance. Front-loaded, no wasted words, perfectly concise.

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 with no output schema, the description explains what is returned and why to use it. Could be more explicit about output format, but sufficient given no schema.

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

Parameters4/5

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

Tool has 0 parameters with 100% schema coverage (empty schema), so description does not need to cover parameter meaning. Baseline for 0 params is 4.

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

Purpose5/5

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

The description clearly states it lists configured scopes with their notmuch query and description, and explicitly mentions its purpose for discovering valid scope values for other mail tools. This distinguishes it from all sibling 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 instructs to call this tool to discover valid scope values for mail_search/mail_count/mail_tag instead of guessing, providing clear context and a specific alternative.

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

mail_pendingPending mailA
Read-only

Threads that need attention: mail owed by you, or mail you are waiting on.

direction='owed': threads matching scope that no message has ever been tagged 'replied' on, i.e. mail you have not answered. Use this for "what do I still need to reply to".

direction='waiting': threads where your own address sent the most recent message and nobody has responded since. Use this for "who owes ME a reply". Needs at least one address configured under [identity] addresses in the config (normally defaulted automatically from notmuch's own user.primary_email/user.other_email); without that, this direction raises an actionable error rather than guessing.

Both directions sort oldest (most overdue) first, since age is the point. This is not a substitute for mail_search when you want to see the messages themselves, only for triaging what is outstanding.

Args: direction: 'owed' (you have not replied) or 'waiting' (you are waiting on a reply). older_than: Only include threads whose relevant date is at least this old, e.g. '14d', '2w', '3m', '1y'. Omit for no age floor. scope: Name of a configured scope to restrict the search (see mail_list_scopes). Defaults to the configured default scope. limit: Maximum number of threads to return. Omit for all results (the default); set it only to cap the number returned, and when it truncates the total is still reported.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
scopeNo
directionNoowed
older_thanNo

TDQS

A4.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safe-read nature is covered. The description adds valuable behavioral context: both directions sort oldest first because 'age is the point', the 'waiting' direction requires identity addresses and raises an actionable error if missing, and the limit parameter still reports the total when truncating. This is strong supplementary transparency beyond the annotations.

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

Conciseness5/5

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

The description is organized into clear paragraphs and an Args section. Every sentence earns its place: both directions are explained with use cases, sorting is justified, the config dependency for 'waiting' is disclosed, and the relationship to mail_search is stated. It is thorough but not bloated, with no redundant phrasing.

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

Completeness5/5

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

Given the tool's complexity (two directions, config dependency, sorting, and four parameters with nuances), the description is fully complete. It covers return-ordering behavior, error conditions, parameter semantics, and when to use alternatives. Although there is no output schema, the description notes that the total is reported even when truncating, which addresses response expectations.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must carry the full burden, and it does. Every parameter is explained with concrete examples: direction lists values and meaning, older_than gives formats like '14d', scope references mail_list_scopes for configuration, and limit explains its default and truncation behavior. This fully compensates for the schema's lack of descriptions.

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

Purpose5/5

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

The description opens with 'Threads that need attention: mail owed by you, or mail you are waiting on,' which specifies the exact verb (list threads needing attention) and resource (mail threads). It differentiates from the sibling mail_search by explicitly stating 'This is not a substitute for mail_search when you want to see the messages themselves,' making its purpose unmistakable.

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

Usage Guidelines5/5

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

The description provides explicit usage scenarios: direction='owed' is for 'what do I still need to reply to' and direction='waiting' for 'who owes ME a reply'. It also names the sibling alternative (mail_search) and explains when not to use this tool, saying it is only for triaging outstanding mail, not for viewing messages.

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

mail_prepare_replyPrepare mail replyA
Read-only

Derive reply/forward headers and the quoted or forwarded body.

This is read-only: it computes what a reply or forward should look like but writes nothing. Pass the result's To/Cc/Subject/In-Reply-To to mail_create_draft (draft tier) if you want it actually saved as a draft.

Args: message_id: A Message-ID as seen in mail_search/mail_read_thread output. quote: Whether to include the original body (quoted with '> ' for reply/reply-all, or as a labelled forwarded block for forward). mode: 'reply' (sender only, honouring Reply-To), 'reply-all' (all original recipients minus your own configured addresses, honouring Mail-Followup-To, which is what mailing lists set and what makes the difference between a correct reply and an embarrassing one), or 'forward' (no In-Reply-To/References, subject gets exactly one 'Fwd:' prefix, body is a labelled forwarded block with the original headers, not an interleaved quote).

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoreply
quoteNo
message_idYes

TDQS

A5/5.0
Behavior5/5

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

The description reinforces the readOnlyHint annotation by stating it 'computes' and 'writes nothing.' It adds behavioral details such as quoting behavior ('> ' for replies, labelled forwarded blocks for forwards), subject prefix rules ('Fwd:' exactly once), and header handling (In-Reply-To/References). This goes well beyond the annotation alone.

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

Conciseness5/5

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

The description is front-loaded with a one-sentence summary, followed by a read-only note and a direct pointer to mail_create_draft. The Args section is cleanly formatted and every sentence adds value – no fluff or repetition of schema metadata.

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

Completeness5/5

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

Given the tool has no output schema and only three parameters, the description covers the tool's purpose, output (headers and body), mode variations, and the follow-up action. It also clarifies the read-only nature, making it complete for an agent to select and invoke correctly.

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

Parameters5/5

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

Schema coverage is 0%, so the description compensates by defining message_id as a Message-ID from mail_search/mail_read_thread output, quote as including the original body with specific formatting, and mode with three detailed options including Mail-Followup-To semantics. Each parameter is fully explained beyond the schema's type/default 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 opens with a specific verb ('Derive') plus the resource ('reply/forward headers and the quoted or forwarded body'), clearly distinguishing it from read-only tools like mail_read_message and mail_read_thread. It also names the output artifacts (To/Cc/Subject/In-Reply-To) and the body format, making the tool's function unmistakable.

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

Usage Guidelines5/5

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

It explicitly instructs the agent to pass the result to mail_create_draft for persistence, and it specifies that this tool itself writes nothing, establishing when to use it versus the draft-saving alternative. The mode parameter is explained with concrete semantics (reply/reply-all/forward) and pitfalls (honoring Mail-Followup-To), giving clear usage context.

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

mail_read_attachmentRead mail attachmentA
Read-only

Read one attachment: text, PDF, image, office document or calendar invite.

Dispatches by content type: text/* and PDF (via pdftotext) come back as text; image/* comes back as an actual image the model can look at (downscaled if oversized and Pillow is installed, otherwise refused with its size); office documents (doc/docx/odt/rtf) are converted to text via pandoc or libreoffice; calendar invitations (text/calendar, .ics) are rendered as a readable summary (method, time, location, organizer, attendees with their response status). Call mail_list_attachments first to get a valid part_index. Archives and other binary formats are not supported and raise an explanatory error.

Args: message_id: A Message-ID as seen in mail_search/mail_read_thread output. part_index: The 1-based part index from mail_list_attachments.

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYes
part_indexYes

TDQS

A5/5.0
Behavior5/5

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

Annotations only indicate readOnlyHint, but the description goes far beyond by detailing content-type dispatch (pdftotext, Pandoc/LibreOffice, etc.), image handling with downscaling/refusal, error behavior for unsupported formats, and calendar invite summary rendering. This is rich behavioral context with no 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?

The description is concise yet complete, starting with a clear summary, followed by necessary technical details, and ending with parameter definitions. No sentence is wasteful; the structure is logical and 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?

With no output schema, the description covers expected return formats (text, image, summary) and error cases. It also notes prerequisites and limitations, making the tool's behavior fully comprehensible for an agent.

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

Parameters5/5

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

Although schema coverage is 0%, the description includes an 'Args' section that explains both parameters. message_id is tied to specific sources ('as seen in mail_search/mail_read_thread output') and part_index is defined as '1-based part index from mail_list_attachments', adding meaning the schema lacks.

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 clear, specific statement: 'Read one attachment: text, PDF, image, office document or calendar invite.' This identifies the verb, resource, and scope, and distinguishes it from sibling tools like mail_list_attachments and mail_read_message by focusing on attachment content.

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?

Explicit guidance is provided: 'Call mail_list_attachments first to get a valid part_index.' It also clarifies unsupported types ('Archives and other binary formats are not supported') and explains the prerequisite, making the when-to-use and when-not-to-use clear.

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

mail_read_messageRead mail messageA
Read-only

Return a single message's headers and body.

Use this for one specific message. For an entire conversation in order, use mail_read_thread instead.

Args: message_id: A Message-ID as seen in mail_search/mail_read_thread output, with or without angle brackets or the 'id:' prefix. response_format: 'concise' (From/Date/Subject, short body) or 'detailed' (full headers, full body up to the configured limit).

ParametersJSON Schema
NameRequiredDescriptionDefault
message_idYes
response_formatNodetailed

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true, and the description adds meaningful behavioral context beyond that: it describes the response_format behaviors ('concise' vs 'detailed') and discloses that the detailed body is truncated by a configured limit. This goes beyond the annotations, though it could have mentioned error handling or idempotency.

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

Conciseness4/5

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

The description is moderately sized and well-structured, starting with a one-line summary, then a usage note, then an Args list. Every sentence contributes value with no fluff, though it is slightly longer than the minimal needed.

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

Completeness5/5

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

Given only two parameters and no output schema, the description adequately covers what the tool returns (headers and body), the output format choices, and how it relates to sibling tools. It provides enough information for an agent to invoke the tool correctly.

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

Parameters5/5

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

The input schema has zero property descriptions (0% coverage), but the description's Args section fully compensates. It explains message_id format (with/without angle brackets or 'id:' prefix) and the two response_format options with their effects. This adds substantial meaning beyond the schema.

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

Purpose5/5

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

The description clearly states the tool returns a single message's headers and body, using a specific verb and resource. It also distinguishes itself from the sibling mail_read_thread by explicitly noting the difference between a single message and an entire conversation.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool ('for one specific message') and names the alternative for conversations (mail_read_thread). It also includes parameter-specific usage details, such as how to format message_id and the two response_format options.

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

mail_read_threadRead mail threadA
Read-only

Return every message in a thread, oldest first, with '--- [N/M] ---' separators.

Use this once mail_search has identified a thread_id and you need the conversation in order. For a single message, use mail_read_message instead. For a long thread, consider calling mail_thread_overview first: it shows one line per message (date, size, from, subject changes) so you can pick the one or two messages worth reading in full here, instead of pulling the whole thread.

Args: thread_id: A thread identifier as returned by mail_search (with or without the 'thread:' prefix). response_format: 'concise' (From/Date/Subject, short body) or 'detailed' (full headers, full body up to the configured limit).

ParametersJSON Schema
NameRequiredDescriptionDefault
thread_idYes
response_formatNodetailed

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false. The description adds substantial behavioral context beyond this: ordering, message separators, response_format differences ('concise' vs 'detailed'), handling of the 'thread:' prefix, and the caveat about long threads and configured limits. 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?

Every sentence is functional: output format, usage context, alternatives, and parameter details. The structure is clear, front-loaded with the primary purpose, and no redundant wording despite being more detailed than typical.

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 is a read-only operation with two parameters and no output schema. The description covers output ordering, format, parameter semantics, and usage guidance. It is complete for the tool's complexity and leaves no critical gaps.

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

Parameters5/5

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

Schema description coverage is 0%, so the description fully carries parameter documentation. It explains thread_id as 'A thread identifier as returned by mail_search (with or without the 'thread:' prefix)' and response_format with concrete examples of what each option returns. This exceeds baseline for zero-coverage 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 opens with a specific verb+resource: 'Return every message in a thread, oldest first, with '--- [N/M] ---' separators.' It clearly distinguishes from siblings by explicitly naming mail_read_message for single messages and mail_thread_overview for long threads.

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

Usage Guidelines5/5

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

Provides explicit when-to-use ('Use this once mail_search has identified a thread_id'), when-not-to-use ('For a single message, use mail_read_message instead'), and an alternative strategy for long threads ('consider calling mail_thread_overview first'). This fully covers the decision space.

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

mail_thread_overviewThread overviewA
Read-only

One line per message: index, date, size, from, and a marker when the subject changes from the thread's root subject.

Use this before mail_read_thread on any thread you have not looked at yet, especially a long one: it costs a fraction of the tokens and lets you decide which one or two messages to actually read in full, instead of pulling all eighty. Do not use it in place of mail_read_thread when you already know you need the full content.

Args: thread_id: A thread identifier as returned by mail_search (with or without the 'thread:' prefix). layout: 'tree' (the actual reply nesting, from notmuch's own thread structure; for a patch series with parallel discussion strands this is materially different from linear order) or 'flat' (linear oldest-first order, matching mail_read_thread's [N/M] numbering).

ParametersJSON Schema
NameRequiredDescriptionDefault
layoutNotree
thread_idYes

TDQS

A4.7/5.0
Behavior4/5

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

The annotations already declare readOnlyHint=true, and the description adds valuable behavior: output structure, layout semantics ('tree' vs 'flat'), and token efficiency compared to mail_read_thread. It does not contradict annotations, and adds meaningful context beyond the safety hints.

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

Conciseness5/5

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

The description is appropriately sized and well-structured: it starts with the output format, then gives usage guidance, then details arguments. Every sentence earns its place with no redundant or vague 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?

The description is highly complete for a read-only overview tool: it specifies output fields, layout options, usage context, and parameter origins. Minor gaps like pagination or max message limits are not addressed, but the description is sufficient for the tool's purpose.

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

Parameters5/5

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

With 0% schema description coverage, the description fully compensates. thread_id is explained as a value from mail_search with/without 'thread:' prefix, and layout is thoroughly described with tree/flat semantics and its relation to mail_read_thread's numbering. This adds substantial meaning beyond the schema's bare types.

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

Purpose5/5

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

The description clearly states the tool's output format ('One line per message: index, date, size, from, and a marker when the subject changes') and identifies the resource as a mail thread overview. It distinguishes itself from sibling mail_read_thread by emphasizing its lightweight, token-efficient nature.

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?

Explicit guidance is provided: 'Use this before mail_read_thread on any thread you have not looked at yet' and 'Do not use it in place of mail_read_thread when you already know you need the full content.' This clearly states when to use and when not to use, and names the 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. Dates show when Glama detected each change.

  1. 12 tool updatesv3.0.0
    • Changedmail_count5 fields changed
      • changedInput schema / properties / count / title
        Before
        "count"
        After
        "Count"
      • changedInput schema / properties / query / title
        Before
        "query"
        After
        "Query"
      • addedInput schema / properties / scope / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / scope / title
        Before
        "scope"
        After
        "Scope"
      • removedInput schema / properties / scope / type
        "string"
    • Changedmail_find_attachments11 fields changed
      • addedInput schema / properties / limit / anyOf
        [
          {
            "type": "integer"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / limit / default
        Before
        50
        After
        null
      • changedInput schema / properties / limit / title
        Before
        "limit"
        After
        "Limit"
      • removedInput schema / properties / limit / type
        "string"
      • changedInput schema / properties / query / title
        Before
        "query"
        After
        "Query"
      • addedInput schema / properties / scope / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / scope / title
        Before
        "scope"
        After
        "Scope"
      • removedInput schema / properties / scope / type
        "string"
      • addedInput schema / properties / type / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / type / title
        Before
        "type"
        After
        "Type"
      • removedInput schema / properties / type / type
        "string"
    • Changedmail_list_addresses8 fields changed
      • addedInput schema / properties / limit / anyOf
        [
          {
            "type": "integer"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / limit / title
        Before
        "limit"
        After
        "Limit"
      • removedInput schema / properties / limit / type
        "string"
      • changedInput schema / properties / output / title
        Before
        "output"
        After
        "Output"
      • changedInput schema / properties / query / title
        Before
        "query"
        After
        "Query"
      • addedInput schema / properties / scope / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / scope / title
        Before
        "scope"
        After
        "Scope"
      • removedInput schema / properties / scope / type
        "string"
    • Changedmail_list_attachments1 field changed
      • changedInput schema / properties / message_id / title
        Before
        "message_id"
        After
        "Message Id"
    • Changedmail_pending11 fields changed
      • changedInput schema / properties / direction / title
        Before
        "direction"
        After
        "Direction"
      • addedInput schema / properties / limit / anyOf
        [
          {
            "type": "integer"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / limit / default
        Before
        50
        After
        null
      • changedInput schema / properties / limit / title
        Before
        "limit"
        After
        "Limit"
      • removedInput schema / properties / limit / type
        "string"
      • addedInput schema / properties / older_than / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / older_than / title
        Before
        "older_than"
        After
        "Older Than"
      • removedInput schema / properties / older_than / type
        "string"
      • addedInput schema / properties / scope / anyOf
        [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / scope / title
        Before
        "scope"
        After
        "Scope"
      • removedInput schema / properties / scope / type
        "string"
    • Changedmail_prepare_reply4 fields changed
      • changedInput schema / properties / message_id / title
        Before
        "message_id"
        After
        "Message Id"
      • changedInput schema / properties / mode / title
        Before
        "mode"
        After
        "Mode"
      • changedInput schema / properties / quote / title
        Before
        "quote"
        After
        "Quote"
      • changedInput schema / properties / quote / type
        Before
        "string"
        After
        "boolean"
    • Changedmail_read_attachment3 fields changed
      • changedInput schema / properties / message_id / title
        Before
        "message_id"
        After
        "Message Id"
      • changedInput schema / properties / part_index / title
        Before
        "part_index"
        After
        "Part Index"
      • changedInput schema / properties / part_index / type
        Before
        "string"
        After
        "integer"
    • Addedmail_read_message
    • Addedmail_read_thread
    • Changedmail_related_threads5 fields changed
      • addedInput schema / properties / limit / anyOf
        [
          {
            "type": "integer"
          },
          {
            "type": "null"
          }
        ]
      • changedInput schema / properties / limit / default
        Before
        10
        After
        null
      • changedInput schema / properties / limit / title
        Before
        "limit"
        After
        "Limit"
      • removedInput schema / properties / limit / type
        "string"
      • changedInput schema / properties / thread_id / title
        Before
        "thread_id"
        After
        "Thread Id"
    • Addedmail_search
    • Changedmail_thread_overview2 fields changed
      • changedInput schema / properties / layout / title
        Before
        "layout"
        After
        "Layout"
      • changedInput schema / properties / thread_id / title
        Before
        "thread_id"
        After
        "Thread Id"
  2. 10 tool updatesv1.0.0
    • First observedmail_count
    • First observedmail_find_attachments
    • First observedmail_list_addresses
    • First observedmail_list_attachments
    • First observedmail_list_scopes
    • First observedmail_pending
    • First observedmail_prepare_reply
    • First observedmail_read_attachment
    • First observedmail_related_threads
    • First observedmail_thread_overview

TDQS

A4.5/5.0
Disambiguation5/5

Each tool targets a distinct operation: search, read single message, read thread, thread overview, related threads, pending, count, address resolution, attachment listing, attachment reading, attachment finding, scope listing, and reply preparation. Overlapping tools like mail_search and mail_count are clearly differentiated by output type.

Naming Consistency4/5

All tools follow the mail_ prefix with snake_case, and most use a verb_noun structure (read_message, list_addresses, find_attachments). A few deviate slightly (mail_search, mail_pending, mail_related_threads) but the pattern is predictable and consistent in style.

Tool Count5/5

13 tools is well-scoped for a mail search and retrieval server. Each tool serves a clear purpose, and the count neither feels excessive nor sparse. The set covers reading, searching, attachments, addresses, and reply preparation without unnecessary duplication.

Completeness3/5

The read-side coverage is strong, but there are gaps: mail_list_scopes references a mail_tag tool that is not present, and there is no way to modify tags, send mail, or create drafts within this server. The prepare_reply tool is a read-only dead end without a draft/send tool. These omissions will cause agent failures when trying to complete write operations.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive

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
    A
    quality
    D
    maintenance
    Local MCP server for multi-account IMAP/SMTP email (iCloud + Gmail via app-specific passwords). Never marks mail read. Cross-folder search, idempotent sends, TLS verified.
    8
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to search and read email from a notmuch archive, providing tools for searching threads, retrieving messages, and listing tags through an MCP endpoint.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Local IMAP/SMTP MCP server that lets Claude read, search, draft, send, flag, and move mail across multiple IMAP mailboxes. Credentials stay on your machine.
    -

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/hgn/mcp-server-notmuch'

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