morning-inbox-mcp
Provides tools for interacting with Gmail, including fetching recent messages, reading full message bodies, archiving messages, marking messages read, starring messages, applying labels, and listing labels.
Allows posting messages to Slack channels, channel IDs, or users as DMs, enabling delivery of a morning inbox summary to Slack.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@morning-inbox-mcprun my morning inbox routine"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
clean-gmail-mcp
An MCP server that gives an AI agent the hands it needs for a daily inbox routine:
Gmail: fetch recent mail, read full messages, archive noise, star urgent, label, mark read
Slack: post the summary in four sections — To reply, Important, Top news, Clean up summary — to a channel or DM
The agent (OpenWork + a scheduled Automation) is the brain: it decides what's noise, what's urgent, and how to word the summary. This server only exposes clean, single-purpose mechanisms.
OpenWork Automation (daily, 7:00 + 17:00 Europe/Bucharest)
└─ agent reasons over tool results
├─ gmail_fetch_recent ──► Gmail API
├─ gmail_archive / gmail_star / gmail_apply_label ──► Gmail API
└─ slack_send_message ──► Slack Web APITools
Tool | What it does |
| Recent messages: id, from, subject, date, snippet, labels, attachment flag |
| One message with decoded body text |
| Remove INBOX label (never deletes) |
| Remove UNREAD label |
| Add STARRED label |
| Apply a label by name, creating it if missing |
| List system and custom labels |
| Post to |
Related MCP server: Gmail MCP Server
Prerequisites
Node.js >= 20
A Google Cloud project with the Gmail API enabled
A Slack workspace where you can create an app
Setup
git clone git@github.com:rusuraluca/clean-gmail-mcp.git
cd clean-gmail-mcp
npm install
npm run build
cp .env.example .envGoogle setup (one-time)
Open Google Cloud Console → create a project.
APIs & Services → Library → enable Gmail API.
APIs & Services → OAuth consent screen → External → add scope
https://www.googleapis.com/auth/gmail.modify→ add your own Gmail address as a test user.APIs & Services → Credentials → Create credentials → OAuth client ID → Desktop app → copy the client ID and secret into
.env.Exchange them for a refresh token (opens your browser, saves
.tokens/google-token.json):
npm run auth:googleThe gmail.modify scope reads and modifies mail (labels, archive, star, mark read) but cannot permanently delete anything.
Slack setup (one-time)
api.slack.com/apps → Create New App → From scratch.
OAuth & Permissions → Bot Token Scopes:
chat:write,channels:read,groups:read,im:write.Install to Workspace → copy the Bot User OAuth Token (
xoxb-...) into.env.Invite the bot where it should post:
/invite @your-app-name(private channels too).Optional: set
SLACK_DEFAULT_CHANNEL=#inbox-briefin.env.
Test locally
npm testRuns both smoke tests: the stdio one (MCP handshake, all 8 tools, unconfigured-credentials error paths) and the HTTP one (initialize, session id, tools/list over Streamable HTTP). CI runs them on every PR.
For an interactive session with the official inspector:
npx @modelcontextprotocol/inspector node dist/index.jsWire it into OpenWork
OpenWork reads opencode.json, so add the server to your workspace config:
{
"mcp": {
"clean-gmail-mcp": {
"type": "local",
"command": ["node", "dist/index.js"],
"cwd": "/absolute/path/to/clean-gmail-mcp",
"enabled": true
}
}
}cwd matters: the server loads .env from it. Rebuild (npm run build) after code changes; OpenWork starts the server on demand.
Use with any AI client
Same tools, two transports:
Transport | How it starts | Connect from |
stdio (default) | the client spawns | any client that can run a local command: Claude Desktop, Cursor, VS Code, Codex, OpenCode |
Streamable HTTP |
| any client that connects by URL: MCP Inspector, OpenWork (Settings → Library → Add workspace MCP), web-based agents |
npm run start:http # PORT=3000 by default
PORT=8080 npm run start:http
HOST=0.0.0.0 npm run start:http # listen on all interfaces (see warning below)stdio needs no port or network — that is what "speaks MCP over stdio" means: the client owns the process, messages travel over the pipes. HTTP lets a client that never spawns processes reach the same server by URL.
Warning: the HTTP endpoint has no authentication and binds
127.0.0.1only. Do not expose it to the network without putting auth in front of it (reverse proxy, VPN, or tunnel).
Then create the Automations — daily, morning and at 5pm (e.g. 7:00 and 17:00 in your timezone), same prompt:
Run my inbox routine using the clean-gmail-mcp tools.
gmail_fetch_recentwith hours=24. Read full bodies (gmail_get_message) only when the snippet is ambiguous.Triage: archive newsletters, promotions, marketing and automated notifications; mark the archived batch as read; label receipts as "Receipts"; star anything that needs a reply, has a deadline, or involves money.
Compose a Slack summary in mrkdwn with four sections: To reply (needs your answer), Important (deadlines, money, urgent), Top news (notable but not urgent), Clean up summary (X archived, Y kept). Two sentences max per item, one line per item. Skip anything trivial.
slack_send_messagethe summary. Do not change labels or archive beyond step 2, and never trash messages.
The first runs are the time to tune the prompt — tell the agent what it got wrong and edit the Automation.
Security notes
.envand.tokens/are gitignored — never commit tokens.Refresh token is stored with
0600permissions.Minimal scopes:
gmail.modify(no delete, no send) +userinfo.email.Revoking access anytime: Google Account → Security → Third-party access.
Ideas for next versions
slack_send_digestwith Block Kit cardsWebhook mode so a hosted version can be triggered outside OpenWork
Dry-run mode that returns the triage plan without applying it
Per-thread reply detection (
gmail_fetch_recentalready returns thread ids)
License
MIT
Available Tools
8 toolsgmail_apply_labelApply a Gmail labelA
Apply a label to the given messages. The label is created if it does not exist yet (e.g. 'Newsletters', 'Receipts', 'To Review').
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Message ids to label. | |
| label | Yes | Label name, e.g. 'Receipts'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one genuinely valuable behavior: the label is created if it does not exist. It still omits whether labels are additive or replace existing ones, permission/scope requirements, the 500-message cap behavior, and what the call returns (no output schema exists to cover that).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the core action front-loaded and the side effect (auto-creation) immediately after. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation with no annotations and no output schema, the description covers the action and the auto-create side effect but leaves the agent guessing about mutability semantics (additive vs. replacing), auth scope, and the return value. Adequate but with real gaps given the absence of structured behavioral metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the schema; baseline is 3. The description adds only example label values ('Newsletters', 'Receipts', 'To Review'), which reinforces the label-name format but adds no constraint or semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Apply a label to the given messages') and adds the non-obvious auto-creation behavior. It does not differentiate from the specialized sibling operations (gmail_star, gmail_archive, gmail_mark_read), which are all label-style mutations, so an agent gets no help choosing between the generic and the specialized tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied clearly by the verb and the mention of example labels, so an agent can infer when to reach for it. However, there is no explicit when-to-use statement, no exclusion, and no mention of the specialized siblings that might be preferable for system labels.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gmail_archiveArchive Gmail messagesA
Archive messages by removing the INBOX label. Messages are kept, never deleted. Use for newsletters, promotions, notifications and other noise after triage.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Message ids to archive. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does disclose the two most consequential traits: the operation is non-destructive ("kept, never deleted") and it works by inbox-label removal. It omits permission/auth requirements, batching limits, and whether the change is reversible, which would matter for a bulk mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, no filler, with the core action and the safety guarantee front-loaded before the usage guidance. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool this is nearly complete: action, mechanism, and non-destructiveness are all covered. Minor gaps remain around bulk behavior (up to 500 ids) and authorization context, which the absence of annotations leaves unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `ids` parameter is documented there, including the 1-500 bounds. The description adds no format or constraint detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb (archive) plus the mechanism (removing the INBOX label), which is exactly the operation that separates it from siblings like gmail_apply_label and gmail_mark_read. An agent can tell what this does and how it differs from label/star/read tools 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use for newsletters, promotions, notifications and other noise after triage" gives clear, actionable context for when this tool is appropriate. It does not name an alternative (e.g., delete or apply_label) or state exclusions, 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.
gmail_fetch_recentFetch recent Gmail messagesA
Fetch recent Gmail messages (metadata + snippet, newest first) for triage. Returns id, from, subject, date, snippet, labelIds and attachment flag for each message. Use gmail_get_message when the snippet is not enough to judge a message.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | How far back to look, in hours (default 24). | |
| query | No | Extra Gmail search terms, e.g. 'is:unread' or 'from:alice@example.com'. | |
| maxResults | No | Maximum messages to return, newest first (default 25). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It discloses the safe-read nature implicitly via 'Fetch', the ordering guarantee (newest first), and — most usefully — that the payload is deliberately partial (metadata + snippet, not full bodies), which tells the agent what it will and won't see. It stops short of stating read-only status explicitly, permission/auth requirements, rate limits, or how results behave when more than maxResults match, leaving some gaps for a no-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler, and the highest-value information (what it returns and its scope vs. gmail_get_message) is front-loaded. Each sentence changes how an agent would use the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly compensates by enumerating the returned fields (id, from, subject, date, snippet, labelIds, attachment flag). What's missing is behavior when the result set exceeds maxResults (pagination/truncation) and how hours and query combine, but for a triage-oriented reader the definition is nearly self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — hours, query, and maxResults all carry their own descriptions and bounds — so the schema already does the heavy lifting and 3 is the correct baseline. The description adds only the 'newest first' ordering constraint, which is not attached to any specific parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fetch) and resource (recent Gmail messages) plus the payload shape (metadata + snippet, newest first) and the intent (triage). It also distinguishes itself from the sibling gmail_get_message by naming the escalation condition, so an agent can pick between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly scopes itself to triage and names the alternative ('Use gmail_get_message when the snippet is not enough to judge a message'), giving both the when-to-use and the when-to-escalate condition. This is the exact kind of routing guidance the dimension rewards.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gmail_get_messageRead one Gmail messageA
Fetch a single Gmail message with its decoded body text. Use after gmail_fetch_recent when a snippet is not enough to decide what to do.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Message id from gmail_fetch_recent. | |
| maxChars | No | Truncate the body at this many characters (default 20000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It usefully discloses that the body is returned already decoded, but says nothing about side effects (does reading mark the message as read?), auth requirements, rate limits, or what else is returned besides the body — notable given siblings like gmail_mark_read imply state-changing operations exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, fully front-loaded: the core action first, the routing guidance second. Nothing is redundant with the schema or the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description must carry more than it does. It mentions the decoded body and implies truncation, but never describes the shape of the response (headers, metadata, attachments) or any state side effect, leaving gaps for an agent that needs to know what it will actually receive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (id, maxChars with default and bounds) are already fully documented in the schema. The description adds no syntax or constraint detail beyond what's there, which is the expected baseline when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch a single Gmail message') and adds a meaningful qualifier ('with its decoded body text') that tells the agent no further decoding is needed. The second sentence separates it from the list-style sibling gmail_fetch_recent, so an agent can route between the two 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear selection context: use it after gmail_fetch_recent when a snippet is insufficient to decide what to do, which names the alternative and the trigger condition. It stops short of stating explicit exclusions or prerequisites (e.g. that the id must come from that fetch, or when the full body is unnecessary).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gmail_list_labelsList Gmail labelsA
List all Gmail labels (system and custom) with their ids.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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 both system and custom labels are returned and that ids are included, but says nothing about ordering, pagination, or auth requirements. Low risk for a list operation, hence mid-range rather than low.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the scope qualifier front-loaded and zero filler. Every element earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument, no-output-schema read tool, the description is nearly sufficient: it names the resource, the scope, and the key returned field (ids). Only edge details such as ordering or pagination are absent, which is acceptable given the simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4. There is no argument surface to document and the description correctly adds nothing spurious about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list Gmail labels) plus scope (system and custom) and return content (ids). It is trivially distinguishable from siblings like gmail_apply_label or gmail_get_message, which operate on messages rather than enumerating labels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use, prerequisites, or named alternatives. For a zero-parameter enumeration tool the usage is strongly implied (fetch label ids before labeling), but the description leaves that inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gmail_mark_readMark Gmail messages as readB
Remove the UNREAD label from the given messages.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Message ids to mark as read. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses the underlying mechanism (UNREAD label removal) rather than just restating 'mark read', which is real added value. However it omits relevant behavioral context for a mutation: required Gmail modify scope, idempotency/repeat-safety, and the 500-id batch ceiling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short, front-loaded sentence with zero filler; every word earns its place. It is arguably under-specified rather than padded, which is a completeness issue rather than a conciseness one.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter mutation with no output schema, the description is minimally adequate, but with no annotations and no output schema it should at least note permission requirements or that the operation is idempotent. Nothing an agent needs to call it is strictly missing, but the safety context is thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with a single well-documented 'ids' parameter, so the baseline is 3. The description's 'given messages' adds no format, ordering, or batching detail beyond the schema's own 'Message ids to mark as read.'
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific operation (remove the UNREAD label) applied to a specific resource (given messages), and the Gmail label mechanic distinguishes it from gmail_apply_label or gmail_archive. It does not explicitly name a sibling or state why one would choose this over gmail_apply_label with the UNREAD label id, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus gmail_apply_label (which could achieve the same label removal) or when it is inappropriate. The agent must infer the intended context from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gmail_starStar Gmail messagesB
Add the STARRED label to the given messages. Use for urgent or action-needed mail.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Message ids to star. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. "Add" implies a Gmail state mutation, but there is no mention of idempotency (re-starring an already-starred message), permission/scope requirements, how invalid ids are handled, or that the change is reversible via unstar. That is a real gap for a write operation with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, with the action front-loaded before the usage hint. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a trivial one-parameter tool the essentials (what it does, when to use it) are present. But with no annotations and no output schema, an agent still lacks confirmation of the mutation's safety profile and idempotency, so it is adequate rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 100% and a single well-documented `ids` array (including maxItems 500 and minItems 1), the schema already does the heavy lifting. The description adds only "given messages," which reiterates rather than extends the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (adding the STARRED label to messages) that an agent can act on immediately. However, it never distinguishes itself from the sibling gmail_apply_label, which can plausibly achieve the same effect via the STARRED label, so the boundary between the two is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use for urgent or action-needed mail" gives a usage scenario, which is more than nothing. But it offers no alternatives or exclusions — notably it never says to prefer gmail_apply_label (or vice versa) when a generic label operation would do, leaving the choice to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
slack_send_messageSend a Slack messageA
Post a message to a Slack channel, or to a user id for a DM. Uses Slack mrkdwn formatting (bold, italic, > quote, • bullet). channel defaults to SLACK_DEFAULT_CHANNEL when omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Message text, Slack mrkdwn allowed. | |
| channel | No | Target: '#channel-name', 'C0123456789', or a user id for a DM. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses mrkdwn formatting support and the default-channel fallback behavior, but says nothing about auth requirements, rate limits, whether messages can be edited/deleted after posting, or what happens on delivery failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: purpose and targeting first, formatting second, default behavior last. No filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter write tool with no annotations and no output schema, the description covers purpose, formatting, and targeting adequately, but omits the return shape (e.g., whether a message timestamp/id comes back) and permission expectations, which are the remaining gaps an agent would want closed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3. The description goes slightly beyond the schema by disclosing the omitted-channel fallback to SLACK_DEFAULT_CHANNEL, a behavior the schema does not state, and restates the mrkdwn formatting allowance that also appears in the text parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Post a message to a Slack channel') and extends it to the DM case via user id, which the name alone doesn't convey. It is trivially distinguishable from the sibling set, which is entirely Gmail-based, so an agent can route between them immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and the description confirms the DM-vs-channel targeting, plus the default-channel fallback. However, there is no explicit when-to-use/when-not guidance, no mention of alternatives for richer Slack actions, and no prerequisites such as required scopes.
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.
8 tool updates
v0.1.0- First observed
gmail_apply_label - First observed
gmail_archive - First observed
gmail_fetch_recent - First observed
gmail_get_message - First observed
gmail_list_labels - First observed
gmail_mark_read - First observed
gmail_star - First observed
slack_send_message
TDQS
Scored across 8 tools
Each tool targets a distinct action, and the descriptions explicitly differentiate gmail_fetch_recent (list/snippet) from gmail_get_message (full body). There is mild conceptual overlap since archive, mark_read, star, and apply_label all manipulate labels, but the intent of each is clearly spelled out.
All tools use a consistent service_verb_noun snake_case pattern (gmail_fetch_recent, gmail_mark_read, slack_send_message), with the service prefix cleanly partitioning Gmail vs Slack operations. Minor verb variation (fetch vs get) is still predictable and readable.
Eight tools is well-scoped for a focused inbox-triage assistant. Each tool earns its place, covering the read/triage, label, and notify steps without redundancy.
The triage lifecycle (fetch, inspect, archive, mark read, star, label) plus Slack notification is well covered. Minor gaps remain: no reply/send-email tool, no unread/undo path, and Slack is limited to sending with no channel listing or read capability.
Maintenance
Related MCP Connectors
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
One inbox for all your addresses: your AI agent reads, sorts, drafts and sends with your permission.
Stateful email for AI agents — read inboxes, reply in-thread, draft with approval.
Email inboxes for AI agents: send, receive, search, drafts with owner approval, and webhooks.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Gmail by reading unread emails with automatic classification, creating AI-generated draft replies, and saving drafts directly to Gmail through the Gmail API.96 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Gmail accounts for reading unread emails, creating draft replies with proper threading, and managing messages, with optional professional writing guidelines, templates, and Google Docs/Calendar integration.-
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to interact with Gmail for classifying messages, extracting action items, and performing batch inbox triage. It supports automated labeling, smart replies, and task creation for external platforms like Linear, Jira, and Todoist.-
- AlicenseAqualityBmaintenanceEnables AI assistants to review unread emails and perform email management operations like delete, archive, and label through Gmail integration.7Apache 2.0