iobox includes an MCP (Model Context Protocol) server that exposes Gmail operations as tools for Claude Desktop, Cursor, VS Code, and other MCP-compatible AI hosts.
Installation¶
pip install "iobox[mcp]"
Available Tools¶
Search & Read¶
| Tool | Description |
|---|---|
search_gmail |
Search Gmail for emails matching a query |
get_email |
Retrieve full email content by message ID |
Save¶
| Tool | Description |
|---|---|
save_email |
Save a single Gmail message as a Markdown file |
save_thread |
Save an entire thread as a single Markdown file |
save_emails_by_query |
Batch save emails matching a query, with optional sync |
Send & Forward¶
| Tool | Description |
|---|---|
send_email |
Send an email (plain text or HTML, with optional attachments) |
forward_gmail |
Forward a Gmail message to a recipient |
batch_forward_gmail |
Forward multiple messages matching a query to a recipient |
Drafts¶
| Tool | Description |
|---|---|
create_gmail_draft |
Create an email draft |
list_gmail_drafts |
List drafts |
send_gmail_draft |
Send an existing draft |
delete_gmail_draft |
Permanently delete a draft |
Labels¶
| Tool | Description |
|---|---|
modify_labels |
Add/remove labels on a single message (read, star, archive, custom) |
batch_modify_gmail_labels |
Modify labels on multiple messages matching a query |
Trash¶
| Tool | Description |
|---|---|
trash_gmail |
Move a message to trash |
untrash_gmail |
Restore a message from trash |
batch_trash_gmail |
Move multiple messages matching a query to trash |
Auth¶
| Tool | Description |
|---|---|
check_auth |
Check authentication status and Gmail profile info |
Tool Details¶
search_gmail
search_gmail(
query: str, # Gmail search syntax
max_results: int = 10,
days: int = 7,
start_date: str = None, # YYYY/MM/DD
end_date: str = None, # YYYY/MM/DD
include_spam_trash: bool = False,
) -> list[dict]
get_email
get_email(
message_id: str,
prefer_html: bool = True,
) -> dict
save_email
save_email(
message_id: str,
output_dir: str = ".",
prefer_html: bool = True,
download_attachments: bool = False,
attachment_types: str = None, # comma-separated, e.g. "pdf,docx"
include_spam_trash: bool = False,
) -> str # Returns path to saved file
save_thread
save_thread(
thread_id: str,
output_dir: str = ".",
prefer_html: bool = True,
include_spam_trash: bool = False,
) -> str # Returns path to saved file
save_emails_by_query
save_emails_by_query(
query: str,
output_dir: str = ".",
max_results: int = 10,
days: int = 7,
start_date: str = None,
end_date: str = None,
prefer_html: bool = True,
download_attachments: bool = False,
attachment_types: str = None,
include_spam_trash: bool = False,
sync: bool = False, # Incremental sync via Gmail history API
) -> dict # {saved_count, skipped_count, attachment_count}
send_email
send_email(
to: str,
subject: str,
body: str,
cc: str = None,
bcc: str = None,
html: bool = False,
attachments: list[str] = None, # File paths
) -> dict
forward_gmail
forward_gmail(
message_id: str,
to: str,
note: str = None,
) -> dict
batch_forward_gmail
batch_forward_gmail(
query: str,
to: str,
max_results: int = 10,
days: int = 7,
start_date: str = None,
end_date: str = None,
note: str = None,
) -> dict # {forwarded_count}
create_gmail_draft
create_gmail_draft(
to: str,
subject: str,
body: str,
cc: str = None,
bcc: str = None,
html: bool = False,
attachments: list[str] = None,
) -> dict
list_gmail_drafts
list_gmail_drafts(max_results: int = 10) -> list[dict]
send_gmail_draft
send_gmail_draft(draft_id: str) -> dict
delete_gmail_draft
delete_gmail_draft(draft_id: str) -> dict
modify_labels
modify_labels(
message_id: str,
mark_read: bool = False,
mark_unread: bool = False,
star: bool = False,
unstar: bool = False,
archive: bool = False,
add_label: str = None,
remove_label: str = None,
) -> dict
batch_modify_gmail_labels
batch_modify_gmail_labels(
query: str,
max_results: int = 10,
days: int = 7,
mark_read: bool = False,
mark_unread: bool = False,
star: bool = False,
unstar: bool = False,
archive: bool = False,
add_label: str = None,
remove_label: str = None,
) -> dict # {modified_count}
trash_gmail
trash_gmail(message_id: str) -> dict
untrash_gmail
untrash_gmail(message_id: str) -> dict
batch_trash_gmail
batch_trash_gmail(
query: str,
max_results: int = 10,
days: int = 7,
) -> dict # {trashed_count}
check_auth
check_auth() -> dict # Includes email, messages_total, threads_total
Claude Desktop Configuration¶
Add the following to your Claude Desktop configuration file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"iobox": {
"command": "python",
"args": ["-m", "iobox.mcp_server"],
"env": {
"CREDENTIALS_DIR": "/path/to/your/credentials"
}
}
}
}
Replace /path/to/your/credentials with the directory containing your credentials.json and token.json files.
Usage Examples¶
Once connected to Claude Desktop, you can ask Claude to:
- "Search my Gmail for emails from newsletters in the last week"
- "Save the email with ID 18e4a2b3c1d5f6a7 to my notes folder"
- "Save all emails from my boss this month as markdown"
- "Forward the last email from my boss to my personal address"
- "Create a draft reply to the last email from HR"
- "Star all unread emails from the marketing team"
- "Trash all emails from promotions older than 30 days"
- "Check if my Gmail authentication is working"
Authentication¶
The MCP server uses the same OAuth 2.0 credentials as the CLI. Ensure you have completed the authentication setup before using the MCP server — run iobox auth-status from the command line first.
See Authentication for full setup instructions.