Skip to main content
Glama
weirdapps

sch-mail

by weirdapps

sch-mail

MCP server for the Greek School Network (sch.gr) mailbox: IMAP read + SMTP send, exposed as ten typed tools over the Model Context Protocol.

CI License: MIT Python 3.12+

What it is

A single-file Python MCP server that talks to the sch.gr mail servers over IMAP4 (SSL, port 993) and SMTP (SSL, port 465), using the MCPServer class from the mcp[cli] package (MCP Python SDK 2.x). From inside an MCP client like Claude Code it lets you list folders, read and search mail, download attachments, send new messages, forward existing ones, move messages between folders, and create folders.

Built for the specific quirks of the Greek School Network mailbox: Greek Unicode in subject and sender lines falls back to client-side filtering (IMAP SEARCH on mail.sch.gr does not handle non-ASCII reliably), and Drafts / Sent folder discovery walks a candidate list to cope with IMAP namespace variations.

send_mail and forward_mail default to draft-first: the message is IMAP-APPENDed into the Drafts folder with the \Draft flag rather than dispatched. Pass send_now=True to actually put it on the wire.

Deployment policy stays local. If a particular mailbox should be used more narrowly than the tools allow, write that guidance in ~/.sch-mail/instructions.md rather than in the code. The server appends the file's text to its MCP instructions at startup (see Local instructions), so every client sees it. The SMTP path works whenever a tool is called with send_now=True; keep that in mind before wiring it into any automation.

Related MCP server: thunderbird-mcp-server

Features

Ten MCP tools (six read, four write), all defined in server.py and registered via the @mcp.tool() decorator on an MCPServer("sch-mail") instance. Every tool accepts an optional account: str matching a key in the multi-account credentials file (default: the default key).

Read tools

Tool

Purpose

sch_list_folders

List all mailbox folders on the account.

sch_list_mail

List recent messages in a folder with id (the message's IMAP UID, which every msg_id parameter takes), date, from, to, subject, read flag, and attachment indicator. Looks back 30 days unless since (YYYY-MM-DD) is given; top is capped at 100.

sch_get_mail

Fetch a specific message by id and return headers, attachment metadata, and the body as plain text or HTML (with max_body_chars truncation).

sch_search_mail

Search a folder by keyword across subject, from, body, or all fields; auto-fallback to client-side filtering for non-ASCII queries, over a 180-day window unless since is given.

sch_download_attachments

Save attachments from a message to disk (default ~/Downloads; any out_dir must sit inside the allowed folders), with optional case-insensitive filename filter and collision-safe renaming.

sch_mail_stats

Quick counts for a folder: total, unread, received today, received in the last 7 days.

Write tools

Tool

Purpose

sch_send_mail

Compose and either save as draft (default) or send via SMTP with send_now=True. Supports plain / HTML bodies, CC, BCC, and file-path attachments, read only from the allowed folders. Sent messages are archived to the Sent folder via IMAP APPEND.

sch_forward_mail

Forward an existing message to new recipients, preserving all original attachments verbatim. Same draft-first default as sch_send_mail.

sch_move_mail

Move one message, by UID, between folders: UID MOVE where the server supports it, else UID COPY + \Deleted flag + UID EXPUNGE, and a bare EXPUNGE only on a server with neither MOVE nor UIDPLUS.

sch_create_folder

Create a new mailbox folder and optionally subscribe to it. Idempotent: returns already_exists if the folder is already there.

Architecture

flowchart TD
    Client["MCP client<br/>(Claude Code)"] -- stdio JSON-RPC --> Server["sch-mail<br/>MCPServer<br/>(server.py)"]
    Server -- IMAP4 SSL:993 --> IMAP["mail.sch.gr<br/>IMAP"]
    Server -- SMTP SSL:465 --> SMTP["mail.sch.gr<br/>SMTP"]
    Server -. reads .-> Creds["~/.sch-mail/<br/>credentials.json"]
    IMAP --> Mailbox["sch.gr mailbox"]
    SMTP --> Mailbox

The server opens a fresh IMAP or SMTP connection per tool call and closes it in a finally block. There is no connection pooling and no long-lived session.

Installation

Requires Python 3.12+. The repo ships a uv.lock for reproducible installs via uv, but plain pip works too.

# HTTPS (no SSH key required):
git clone https://github.com/weirdapps/sch-mail.git
# or, with SSH:
git clone git@github.com:weirdapps/sch-mail.git
cd sch-mail

# Option A: uv (recommended, matches the committed lockfile)
uv sync

# Option B: pip
python -m venv .venv
.venv/bin/pip install -e .

The only runtime dependency is mcp[cli] (constraint declared in pyproject.toml, currently >=2.0.0, pinned by uv.lock). The optional dev extra adds ruff and pytest, which is what CI lints and tests with.

Configuration

Credentials live at ~/.sch-mail/credentials.json, outside the repo. credentials.json is also in .gitignore for safety.

Single-account format:

{
  "email": "user@sch.gr",
  "password": "..."
}

Multi-account format (referenced from every tool via the account argument):

{
  "accounts": {
    "personal": { "email": "user@sch.gr",       "password": "..." },
    "work":     { "email": "other.user@sch.gr", "password": "..." }
  },
  "default": "personal"
}

The key names are yours to choose. A tool called without account uses the account default names, or the first one listed when there is no default.

Connection parameters are hard-coded in server.py:

Constant

Value

IMAP_HOST

mail.sch.gr

IMAP_PORT

993 (SSL)

SMTP_HOST

mail.sch.gr

SMTP_PORT

465 (SSL)

CRED_PATH

~/.sch-mail/credentials.json

INSTRUCTIONS_PATH

~/.sch-mail/instructions.md (optional)

DEFAULT_DOWNLOAD_DIR

~/Downloads

Local instructions (optional)

When ~/.sch-mail/instructions.md exists, the server reads it once at startup and appends its text, after a single space, to the built-in MCP instructions that every client receives. Use it for anything specific to one deployment, such as house rules for how a mailbox may be used, so that none of it has to live in this repo. A missing or blank file leaves the built-in text alone; a file that cannot be read or decoded as UTF-8 stops the server from starting rather than letting it run without the guidance.

Allowed folders

sch_send_mail reads attachments, and sch_download_attachments saves files, only inside an allowlist of folders. Every tool argument is chosen by a model that is also reading mail anyone can send, so without the limit a hostile message could get a private key or document attached to a draft, or a file saved somewhere that runs it. Paths are resolved with symlinks followed before the check, so neither .. nor a link inside an allowed folder can point out of it. Hidden files and folders below an allowed folder are refused too, because other programs load files from them without asking (a .venv's site-packages, .git/hooks, editor and agent settings); to use a hidden folder anyway, name that folder itself in SCH_MAIL_ALLOWED_DIRS. The defaults are deliberately narrow:

  • ~/Downloads

  • the system temp dir, and /tmp

~/Documents, ~/Desktop and cloud-synced folders are not among them. To attach a file kept elsewhere, copy it into ~/Downloads first, or name its folder in SCH_MAIL_ALLOWED_DIRS.

SCH_MAIL_ALLOWED_DIRS replaces the defaults outright: absolute paths separated by os.pathsep (: on macOS and Linux). ~ is expanded and relative entries are ignored. It is the only setting the server takes from the environment. A refused path is reported as an error that names the variable. An attachment that is refused, missing or not a regular file fails the whole call, so a message never goes out quietly missing a file. Saved file names are cleaned too: path separators, control characters and bidirectional-override characters become _, and a leading dot gets a _ prefix so nothing lands hidden.

Usage

Run the server

bash run_mcp.sh

run_mcp.sh resolves its own directory and execs .venv/bin/python -m server, so it works from any working directory.

Register with Claude Code

Add an entry to your Claude Code MCP config pointing at the launcher script:

{
  "mcpServers": {
    "sch-mail": {
      "command": "/absolute/path/to/sch-mail/run_mcp.sh"
    }
  }
}

Claude Code starts the server on demand over stdio; you do not run it manually.

Example tool calls

Once the server is registered, tools are available as sch_list_mail, sch_send_mail, and so on. Concrete examples:

  • Triage the inbox: sch_list_mail(folder="INBOX", top=20) returns the 20 most recent messages with read / attachment flags.

  • Read a message: sch_get_mail(msg_id="12345", body="text", max_body_chars=5000).

  • Search for a topic in Greek: sch_search_mail(query="Επιμόρφωση", field="subject", top=10) (auto-uses client-side filtering because of non-ASCII).

  • Save a draft (default behaviour): sch_send_mail(to="foo@sch.gr", subject="test", body="hello") returns {"status": "draft_saved", "folder": "Drafts", ...}. Review it in sch.gr webmail and hit send, or rerun with send_now=True.

  • Dispatch immediately: same call with send_now=True sends via SMTP and archives to the Sent folder via IMAP APPEND. There is no undo.

  • Forward preserving attachments: sch_forward_mail(msg_id="12345", to="bar@sch.gr", additional_text="FYI").

  • Move a message: sch_move_mail(msg_id="12345", dest_folder="INBOX/Archive2026"). The destination must exist; use sch_create_folder("INBOX/Archive2026") first if it does not.

Development

The project follows the house Python conventions used across weirdapps repos.

# Install the dev extra first: a plain `uv sync` does not pull ruff in,
# because ruff lives in the optional `dev` extra, not the default deps.
uv sync --extra dev --frozen

# Lint + format (config in pyproject.toml)
uv run ruff check .
uv run ruff format --check .

# Import sanity check, then the test suite (offline: tests/conftest.py
# blocks real sockets and the real credentials file)
uv run python -c "import server; print('Import OK')"
uv run pytest -q

.pre-commit-config.yaml wires up ruff, ruff-format, gitleaks secret scanning, and the standard pre-commit-hooks hygiene set. Install once with pip install pre-commit && pre-commit install.

CI (.github/workflows/ci.yml) runs two jobs on push and PR to master: lint (ruff check plus ruff format --check) and test (the import server smoke check, then pytest -q). Both install with uv sync --frozen, so uv.lock has to stay in step with pyproject.toml or CI fails before it runs anything. SonarCloud analysis is wired via sonar-project.properties (project key weirdapps_sch-mail).

Dependabot runs weekly against two ecosystems, uv and github-actions, with minor and patch updates grouped (see .github/dependabot.yml). .github/workflows/dependabot-auto-merge.yml is a thin caller for the shared reusable workflow weirdapps/shared-workflows/.github/workflows/dependabot-auto-merge.yml, pinned to a commit SHA; it merges a Dependabot PR once that PR's own checks are green and leaves majors open for review.

Security

Report vulnerabilities privately through GitHub (the Security tab, then Report a vulnerability); see SECURITY.md. Credentials never enter the repo: credentials.json and *.env are in .gitignore, and gitleaks runs pre-commit.

weirdapps/yahoo-access is a downstream adaptation of this server (a copy rather than a GitHub fork, so there is no upstream PR relationship), retargeted at Yahoo Mail's IMAP / SMTP endpoints and its own multi-account setup.

License

MIT, see LICENSE. Copyright (c) 2026 Dimitrios Plessas.

Available Tools

10 tools
sch_create_folderA

Create a new mailbox folder.

Args: name: Folder name. For nested folders use the server's separator (commonly "/" or ".", e.g. "INBOX/Archive2026" or "Archive.2026"). subscribe: Subscribe to the folder so it appears in mail clients (default: True). account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
accountNo
subscribeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

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

No annotations are supplied, so the description carries the full behavioral burden. It usefully discloses the subscribe default and the account default resolution, but says nothing about idempotency if the folder already exists, permission requirements, or error behavior for a mutation tool.

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

Conciseness4/5

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

The one-line purpose is front-loaded, and the Args block is structured and dense. It is documentation-styled rather than terse, but every line adds information, so little is wasted.

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

Completeness4/5

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

An output schema exists, so return values need not be described, and all three input parameters are covered. The remaining gap is mutation-specific behavior (permissions, duplicate handling), which is a modest omission for a simple create tool.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it does: it explains all three parameters, the nested-folder separator convention with examples, the subscribe default (True), and how 'account' maps to credentials.json. This is meaningful meaning beyond the bare schema types.

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

Purpose4/5

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

States a specific verb and resource ('Create a new mailbox folder'), which is unambiguous and distinct from read-only siblings like sch_list_folders. It does not explicitly differentiate itself from other folder operations, but the purpose is clear without opening the schema.

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

Usage Guidelines3/5

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

Usage is largely implied rather than stated – no when-to-use/when-not or reference to alternatives. The Args block does give practical guidance (separator conventions for nested folders, account default resolution), which nudges it above pure inference.

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

sch_download_attachmentsA

Download attachments from a message to disk.

Args: msg_id: Message UID from sch_list_mail / sch_search_mail folder: Mailbox folder (default: INBOX) out_dir: Directory to save files (default: ~/Downloads). Must lie inside the allowed folders (by default ~/Downloads and the temp dirs; SCH_MAIL_ALLOWED_DIRS replaces them). filename_filter: Only download files matching this substring (case-insensitive) account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNoINBOX
msg_idYes
accountNo
out_dirNo
filename_filterNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/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 behavioral burden. It usefully discloses the allowed-directory restriction, default output directory, case-insensitive filtering, and account default logic, but it omits key mutation behaviors such as whether existing files are overwritten, error handling, or permission requirements.

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

Conciseness5/5

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

The purpose is front-loaded in the first sentence, followed by a well-organized Args block. Every sentence adds value, with no redundancy or filler.

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

Completeness4/5

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

Given five parameters, full schema coverage in the description, and an output schema that handles return values, the definition is largely complete for invocation. It still lacks some behavioral context expected when no annotations are present, such as overwrite semantics or failure modes.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate, and it does thoroughly. Each of the five parameters is explained with its source, default, or constraint (e.g., msg_id UID source, out_dir allowed folders, filename_filter substring behavior, account key file).

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

Purpose5/5

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

The first sentence gives a specific verb (Download) and resource (attachments from a message) and destination (to disk), clearly distinguishing this tool from siblings like sch_get_mail or sch_search_mail. An agent can immediately tell what the tool does without opening the schema.

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

Usage Guidelines4/5

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

It provides clear context by stating that msg_id comes from sch_list_mail / sch_search_mail, and it documents defaults for folder, out_dir, and account. However, it does not explicitly state when to use this tool versus alternatives or any conditions where it should not be used.

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

sch_forward_mailA

Forward an existing message to new recipient(s), preserving attachments.

Args: msg_id: Source message UID (from sch_list_mail / sch_search_mail) to: Recipient(s), comma-separated cc: CC recipient(s) bcc: BCC recipient(s) additional_text: Optional text prepended above the forwarded content (plain text) folder: Source folder (default: INBOX) send_now: True to dispatch immediately. Default False = save to Drafts. account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

Returns status, subject, attachment count, and message id.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYes
bccNo
folderNoINBOX
msg_idYes
accountNo
send_nowNo
additional_textNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

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 full behavioral burden. It discloses the critical draft-vs-dispatch behavior via send_now, attachment preservation, and the account default resolution from credentials.json. It doesn't mention permissions or rate limits, but covers the key state-changing behavior.

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

Conciseness4/5

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

A front-loaded purpose sentence followed by structured Args and Returns sections. Every line adds parameter value rather than padding. Slightly verbose but earns its length given 8 undocumented params.

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 output schema existing, the description still notes what is returned (status, subject, attachment count, message id). Given 8 params at 0% schema coverage and no annotations, the description covers all the info an agent needs to call this mutation correctly.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must fully compensate and it does: each of the 8 params is explained with meaning, format (comma-separated), default (INBOX, Drafts), and the account key example. This is exactly the compensation 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?

States a specific verb and resource ('Forward an existing message to new recipient(s)') plus a distinguishing behavioral trait ('preserving attachments'). This clearly separates it from siblings like sch_send_mail or sch_move_mail.

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

Usage Guidelines4/5

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

The description implies usage by tying msg_id to sch_list_mail/sch_search_mail as sources and explaining the send_now draft-vs-send behavior. It doesn't explicitly state when to use this over sch_send_mail, but the context is clear enough for selection.

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

sch_get_mailA

Read a specific message by UID (the "id" from sch_list_mail or sch_search_mail).

Args: msg_id: Message UID from sch_list_mail / sch_search_mail folder: Mailbox folder (default: INBOX) body: Body format: "text" (plain text, default), "html", or "none" max_body_chars: Truncate body to this many chars (default: 5000) account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNotext
folderNoINBOX
msg_idYes
accountNo
max_body_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose meaningful behavior: default folder INBOX, body format choices, a 5000-char truncation default, and how the account key resolves via credentials.json. The notable omission is whether reading marks the message as read (an IMAP side effect) or what permissions are needed.

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

Conciseness5/5

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

One front-loaded sentence gives the purpose, followed by a compact Args list; no filler and every line carries parameter information the schema does not.

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?

An output schema exists so return values need not be described, and the parameters are fully covered. What remains thin is the safety/side-effect profile for a read over IMAP and any explicit routing away from the attachment and stats siblings.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate fully, and it does: every one of the five parameters (msg_id, folder, body, max_body_chars, account) is documented with type, accepted values, default, and provenance. The 'body' enum-like options and account example add meaning the bare 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?

States a specific verb and resource ('Read a specific message by UID') and immediately ties the UID to its origin tools (sch_list_mail / sch_search_mail), which lets an agent distinguish this from the list/search siblings without opening a schema.

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

Usage Guidelines4/5

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

The description establishes the required context: msg_id must come from sch_list_mail or sch_search_mail, so the agent knows this tool is a follow-up read after enumeration. It stops short of explicit when-not guidance (e.g., use sch_download_attachments for attachment retrieval).

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

sch_list_foldersA

List all mailbox folders.

Returns folder names available in the sch.gr mailbox. Pass account (a key in credentials.json, e.g. "work") to pick a mailbox, or omit it for the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It usefully discloses that folder names are returned and that the account resolves via credentials.json with a "default" key when omitted, but says nothing about read-only safety, authentication failures, or folder hierarchy/pagination behavior.

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

Conciseness4/5

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

Front-loaded with the core purpose in one short sentence, followed by return info and parameter guidance. Slight redundancy between "List all mailbox folders" and "Returns folder names available in the sch.gr mailbox," but nothing is wasted.

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

Completeness4/5

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

For a one-parameter read tool with an output schema present (so return structure needn't be explained), the description covers purpose and the account-selection mechanic. Only multi-mailbox edge cases and error conditions are unaddressed.

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%, yet the description fully explains the single parameter: it is a key in credentials.json (e.g. "work"), and omission resolves to the "default" account. This compensates well for the missing schema documentation, though it doesn't state the error behavior for an unknown key.

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

Purpose4/5

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

States a specific verb and resource ("List all mailbox folders") plus the concrete return (folder names in the sch.gr mailbox). It is clearly distinguishable from write siblings like sch_create_folder or mail siblings like sch_list_mail, though that separation is inferred rather than stated explicitly.

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

Usage Guidelines3/5

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

The description gives no when-to-use framing relative to alternatives (e.g. using this before sch_move_mail or after sch_create_folder); the only guidance is for the account parameter. Usage is implied by the listing nature of the tool, so it lands at minimum viable.

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

sch_list_mailA

List recent messages with subject, sender, date, and attachment indicators.

Each result's "id" is the message's IMAP UID: stable across calls, unlike a sequence number, and the value every msg_id parameter expects.

Args: folder: Mailbox folder (default: INBOX) top: Max messages to return (default: 20, max: 100) since: Only messages after this date (YYYY-MM-DD). Default: last 30 days. account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNo
sinceNo
folderNoINBOX
accountNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does add real behavioral context: the 'id' is an IMAP UID that is stable across calls (unlike a sequence number) and is the value every msg_id parameter expects, plus which credentials file/account governs the call. It omits rate limits, ordering guarantees, or empty-result behavior, but the UID stability note is genuinely useful information not available elsewhere.

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 primary action is front-loaded in sentence one, the important UID caveat follows, and the Args block is a compact per-parameter reference. No sentence is redundant or padded.

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 read-only listing tool with an output schema present, the description need not explain return shape, and it correctly focuses on parameters and the id semantics that link output to other tools. Minor gaps remain (no statement about empty results or what happens if the folder is missing), but nothing essential for a correct call is absent.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate, and it does for all four parameters: folder default INBOX, top default 20 with a 100 maximum, the YYYY-MM-DD format and 30-day default for since, and the account key convention with its default resolution rule. This is exactly the information the bare schema lacks.

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

Purpose4/5

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

The first sentence gives a specific verb and resource ('List recent messages') plus the concrete fields returned (subject, sender, date, attachment indicators), which distinguishes it from sch_get_mail and sch_search_mail implicitly. It never names the alternatives, so an agent must infer the routing, but the purpose itself is unambiguous.

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

Usage Guidelines3/5

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

The default 30-day 'since' window and 'recent messages' framing imply when this listing tool is appropriate versus a search, but there is no explicit when-to-use or when-not-to-use statement and no sibling is named. Guidance is implied rather than stated.

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

sch_mail_statsB

Quick mailbox statistics: total messages, recent/unseen counts, date range.

Args: folder: Mailbox folder (default: INBOX) account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNoINBOX
accountNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses what is returned (counts, date range) and implies a read-only operation, but never states that it is non-mutating, what permissions/auth it needs, or whether it hits the network per call. Partial disclosure only.

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

Conciseness4/5

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

Front-loaded one-line summary followed by a compact args list; every line earns its place given the zero-coverage schema. Slightly verbose but no waste.

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?

An output schema exists, so return format need not be re-explained, and both parameters are documented in the description despite 0% schema coverage. Only the read-only/auth profile is left implicit for a zero-annotation tool.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it does: it documents folder's default (INBOX) and explains account as a credentials.json key with an example ('personal'/'work') and a default-resolution rule. This meaningfully exceeds the bare schema.

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

Purpose4/5

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

States a specific verb+resource ('mailbox statistics') and enumerates the outputs (total messages, recent/unseen counts, date range). This clearly differentiates it from the sibling list/get/search mail tools, though it does not name a sibling explicitly.

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

Usage Guidelines2/5

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

The word 'Quick' hints that this is a lightweight summary, but there is no explicit when-to-use guidance and no mention of when an agent should prefer sch_list_mail or sch_search_mail instead. Usage must be inferred entirely.

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

sch_move_mailA

Move one message, addressed by UID, from source_folder to dest_folder.

Uses UID MOVE when the server supports it, else UID COPY + \Deleted + UID EXPUNGE, and a bare EXPUNGE only on a server with neither MOVE nor UIDPLUS. Destination folder must already exist (use sch_create_folder first if needed).

Args: msg_id: Source message UID from sch_list_mail / sch_search_mail (one UID; ranges and lists are refused) dest_folder: Target folder name source_folder: Source folder (default: INBOX) account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
msg_idYes
accountNo
dest_folderYes
source_folderNoINBOX

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

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 full burden, and it delivers unusually good behavioral detail: it discloses the server-capability fallback chain (UID MOVE vs. UID COPY + \Deleted + UID EXPUNGE vs. bare EXPUNGE). It omits reversibility, permission/authentication requirements, and error behavior when the move fails partway.

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 core action is front-loaded in the first sentence, followed by implementation detail and then an Args block. The IMAP fallback sentence is the only slightly dense part, but it earns its place by explaining non-obvious server-dependent behavior.

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

Completeness5/5

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

With an output schema present, return values need not be described, and the description covers the remaining gaps: prerequisites, addressing constraints, defaults for both optional parameters, and the fallback execution path. 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.

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, and it does: msg_id is specified as a single UID with ranges/lists explicitly refused, dest_folder is the target name, source_folder defaults to INBOX, and account is explained as a credentials.json key with its own default resolution rule.

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

Purpose5/5

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

The first sentence states a specific verb (Move), a precise resource (one message), and both endpoints (source_folder to dest_folder), with the addressing scheme (UID) called out. It is immediately distinguishable from siblings like sch_send_mail or sch_get_mail without opening the schema.

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

Usage Guidelines4/5

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

It explicitly routes the agent to siblings for prerequisites: use sch_create_folder if the destination does not exist, and msg_id comes from sch_list_mail / sch_search_mail. It does not state any when-not-to-use conditions (e.g., that it cannot move multiple messages), so it falls just short of full guidance.

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

sch_search_mailA

Search messages by keyword in subject, sender, or body.

Result ids are IMAP UIDs, the same ids sch_list_mail returns.

Args: query: Search text (case-insensitive) folder: Mailbox folder (default: INBOX) field: Where to search: "subject", "from", "body", or "all" (default: subject) since: Only search after this date (YYYY-MM-DD) top: Max results (default: 20) account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNo
fieldNosubject
queryYes
sinceNo
folderNoINBOX
accountNo

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?

No annotations are provided, so the description carries the full burden. It discloses useful operational detail — result ids are IMAP UIDs, folder defaults to INBOX, and account defaults to the 'default' entry in credentials.json — but never states that this is a read-only operation, nor addresses rate limits, permissions, or result ordering/pagination.

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

Conciseness4/5

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

Front-loaded purpose sentence followed by a compact Args block; each parameter line is a single clause with no waste. The docstring-style layout is slightly verbose relative to a prose summary but remains tight and scannable.

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?

An output schema exists so return values need not be explained, and the description still usefully clarifies that ids are IMAP UIDs. Combined with the full parameter documentation and default-resolution rules, it covers what an agent needs, though it omits read-only/behavioral guarantees.

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 must do all the work, and it does: every one of the six parameters is documented with meaning and defaults, including the enumerated field values ('subject','from','body','all') that the schema lacks entirely, the YYYY-MM-DD date format for 'since', and the credentials.json account-key semantics.

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

Purpose5/5

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

States a specific verb and resource ('Search messages') and the searchable fields (subject, sender, body), and differentiates itself from siblings by noting result ids are IMAP UIDs identical to what sch_list_mail returns. An agent can distinguish this from sch_list_mail and sch_get_mail without opening any schema.

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

Usage Guidelines3/5

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

The tool's purpose implies its use case (keyword lookup vs listing), and the UID note hints at how it relates to sch_list_mail, but there is no explicit when-to-use/when-not statement or named alternative for retrieval-by-id (sch_get_mail). Usage is inferred rather than stated.

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

sch_send_mailA

Send a new email via SMTP, or save as draft (default).

Args: to: Recipient(s), comma-separated (e.g. "a@x.gr,b@y.gr") subject: Subject line body: Email body (plain text by default; set html=True for HTML) cc: CC recipient(s), comma-separated bcc: BCC recipient(s), comma-separated html: True if body is HTML; False (default) for plain text attachments: List of absolute file paths to attach. Each must be an existing file inside the allowed folders (by default ~/Downloads and the temp dirs; SCH_MAIL_ALLOWED_DIRS replaces them). One that is missing or outside them fails the whole call, so nothing is saved or sent without it. send_now: True to dispatch via SMTP immediately. Default False = save to Drafts folder. account: Account key in credentials.json (e.g. "personal" or "work"). Default: the account named by "default" in that file.

Returns dict with status ("draft_saved" or "sent"), folder/recipients, and message id.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYes
bccNo
bodyYes
htmlNo
accountNo
subjectYes
send_nowNo
attachmentsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the atomic attachment-validation rule (missing or out-of-allowed-dir file fails the whole call, nothing saved or sent), the allowed-dirs default and SCH_MAIL_ALLOWED_DIRS override, and account resolution from credentials.json. Auth mechanics and any rate limits are not spelled out, but failure semantics and defaults are unusually well covered.

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

Conciseness4/5

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

Purpose is front-loaded in one sentence, then a clean per-argument list where each line earns its place. The attachments entry is long, but that length buys genuinely load-bearing failure-mode information rather than padding.

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

Completeness5/5

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

For a 9-parameter mutation tool with zero schema coverage and no annotations, nothing critical is missing: modes, defaults, attachment constraints, account selection, and failure behavior are all present. The brief return summary ('draft_saved' or 'sent', folder/recipients, message id) is mildly redundant against the output schema but harmless.

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% across 9 parameters, so the description must compensate – and it does. It defines formats and examples for every parameter: comma-separated recipient lists with an example ('a@x.gr,b@y.gr'), html's effect on body, attachments as absolute paths with validation rules, send_now's default, and account's default key resolution.

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

Purpose5/5

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

States a specific verb and resource ('Send a new email via SMTP') plus the key mode switch ('or save as draft (default)'). The word 'new' implicitly separates it from sch_forward_mail, so an agent can route between the two send-family tools without opening a schema.

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

Usage Guidelines4/5

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

Gives clear operational context: the default is a draft and send_now=True dispatches it, which is the main decision an agent must make. It does not name alternatives or state when-not to use it (e.g. vs sch_forward_mail), so it stops short of full routing guidance.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv0.1.0
    • First observedsch_create_folder
    • First observedsch_download_attachments
    • First observedsch_forward_mail
    • First observedsch_get_mail
    • First observedsch_list_folders
    • First observedsch_list_mail
    • First observedsch_mail_stats
    • First observedsch_move_mail
    • First observedsch_search_mail
    • First observedsch_send_mail

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct action on the mail domain: listing, searching, reading, sending, forwarding, moving, downloading attachments, folder listing/creation, and stats. The closest pair (sch_list_mail vs sch_search_mail) is clearly separated as browse-vs-query, and both share the same UID semantics, so there is no realistic misselection.

Naming Consistency4/5

The set follows a consistent sch_<verb>_<noun> pattern (sch_list_mail, sch_get_mail, sch_send_mail, sch_move_mail, sch_create_folder). The only deviation is sch_mail_stats, which puts the noun before the description rather than using a verb, but it remains readable.

Tool Count5/5

Ten tools is a well-scoped size for an email client surface, covering reading, sending, organizing, and attachments without bloat. Every tool earns its place and none appears redundant.

Completeness3/5

Core lifecycle is covered (list, search, read, send, forward, move, create folder, attachments, stats), but notable operations are missing: no delete_mail or delete/rename folder, and no reply or mark read/unread. These are common email workflows whose absence forces agents to work around dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

  • Your IMAP mailbox as an MCP server: read, search and (if you allow it) organize mail. Open source.

  • Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.

  • Your mailbox for MCP clients: search, read, draft, send, rules and notes. Sending is off by default.

  • Your agent needs a mailbox of its own — to receive, thread, draft and send, with attachments, without borrowing your personal inbox or your company's SMTP. **What you can ask for** • "Create an inbox for this agent and tell me its address." • "Read the new messages in this thread and draft a reply." • "Send this message with the attachment and wait for the response." • "Search this inbox for everything from that domain." • "Show delivery metrics and the events on this inbox." **How to use it** Point any MCP client at https://mcp.aisa.one/mail/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: create and delete inboxes, list and read messages, raw message bodies, attachments, threads, drafts and draft attachments, send and reply, message search, inbox events, metrics, and list entries — reads and writes. **Why this rather than the source** A real inbox an agent owns, rather than an SMTP credential it borrows from a human. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Find the contact elsewhere in the catalogue, then write to them from here — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/sales/mcp finds the person to write to.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Gmail through the MCP protocol, supporting sending, reading, searching, replying, forwarding, managing drafts and labels, and saving attachments.
    12 npm
    3
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server exposing JMAP email and Sieve script operations as tools, enabling mailbox management, email creation, search, flagging, and Sieve script management.
    2
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes any IMAP mailbox and SMTP relay as MCP tools, enabling email management (read, search, send, delete) through MCP-compatible agents.
    1
    MIT