bichon-mcp
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., "@bichon-mcp search my inbox for receipts from last month"
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.
bichon-mcp
MCP server that wraps the Bichon email archiver REST API, letting an AI agent (Claude Code, Claude Desktop) search and read locally-archived emails — without ever touching Gmail or IMAP credentials directly.
Architecture
Gmail / IMAP
└─► Bichon (Docker, localhost:15630)
local Tantivy FTS + compressed EML store
└─► bichon-mcp (this repo, stdio MCP server)
└─► Claude Code / Claude DesktopAfter the initial IMAP sync, the AI only ever calls localhost:15630. No external auth is granted to the AI.
Related MCP server: gmail-research-mcp
Requirements
Python 3.11+
uv (recommended) or pip
Bichon running locally — see Bichon quickstart
Installation
1. Clone and install
git clone https://github.com/pras-labs/bichon-mcp
cd bichon-mcp
uv venv
uv pip install -e .2. Get a Bichon access token
Start Bichon (Docker):
docker run -d --name bichon -p 15630:15630 rustmailer/bichon:latestThen get a token:
curl -s -X POST http://localhost:15630/api/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin@bichon"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])"For a long-lived token, create one in the Bichon WebUI under Settings → Access Tokens.
3. Configure your client
Claude Code
Copy .mcp.json.example to .mcp.json and fill in the token:
cp .mcp.json.example .mcp.json{
"mcpServers": {
"bichon-email": {
"command": ".venv/bin/python",
"args": ["-m", "bichon_mcp"],
"env": {
"BICHON_BASE_URL": "http://localhost:15630",
"BICHON_ACCESS_TOKEN": "<your-token>"
}
}
}
}
.mcp.jsonis gitignored — your token will not be committed.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"bichon-email": {
"command": "/path/to/bichon-mcp/.venv/bin/python",
"args": ["-m", "bichon_mcp"],
"env": {
"BICHON_BASE_URL": "http://localhost:15630",
"BICHON_ACCESS_TOKEN": "<your-token>"
}
}
}
}Configuration
All configuration is via environment variables:
Variable | Default | Description |
|
| Bichon instance URL |
| (required) | Bearer token for Bichon API |
|
| Mailbox stats cache TTL in seconds. |
|
| HTTP request timeout in seconds |
MCP Tools
list_accounts()
List all email accounts configured in Bichon.
Returns: [{id, email}]Example prompt: "What email accounts are set up?"
list_mailboxes(account_id)
List mailbox folders for an account (INBOX, Sent, Drafts, etc.).
account_id* integer From list_accounts
Returns: [{id, name, total, unseen}]Example prompt: "Show me all mailboxes for my account."
get_mailbox_stats(account_id, mailbox_id)
Per-mailbox statistics: total email count, top senders, top subjects by frequency. Results are cached (default 5 min, configurable via BICHON_STATS_CACHE_TTL).
account_id* integer From list_accounts
mailbox_id* integer From list_mailboxes
Returns:
total_emails integer Exact count from Bichon
sampled integer Emails analysed (up to 200 most recent)
top_senders [{sender, count}]
top_subjects [{subject, count}]
oldest_in_sample / newest_in_sample integer (unix ms)
cached booleanExample prompt: "Give me stats for my INBOX — who emails me most?"
search_emails(query, ...)
Full-text search across archived emails. Returns summaries only — no body text.
query* string Full-text search term (max 500 chars)
date_from string ISO date YYYY-MM-DD (inclusive)
date_to string ISO date YYYY-MM-DD (inclusive)
sender string Filter by sender address (max 254 chars)
account_id integer Scope to one account
mailbox_id integer Scope to one mailbox folder
limit integer Max results, default 20, max 50
Returns: [{id, account_id, subject, from, to, date, preview, thread_id, has_attachments}]Example prompts:
"Search for emails about invoices from last month."
"Find emails from notifications@github.com in my INBOX."
get_email(account_id, envelope_id)
Fetch the full plain-text content of one email. HTML is stripped. Body is truncated at ~4000 tokens.
account_id* integer From search_emails result
envelope_id* string UUID from search_emails result
Returns: {account_id, envelope_id, body, attachment_count}Example prompt: "Show me the full content of that invoice email."
list_threads(subject_contains?, sender?, limit?)
Group search results by thread_id to show conversation threads.
subject_contains string Filter by subject text (max 500 chars)
sender string Filter by sender (max 254 chars)
limit integer Max threads to return, default 10
Returns: [{thread_id, account_id, subject, latest_from, latest_date, count}]Example prompt: "Show me all threads from GitHub notifications."
get_sender_summary(email_address)
Aggregate stats for a sender: total email count, date range, top subjects.
email_address* string Valid email address (max 254 chars)
Returns: {email, count, first_seen, last_seen, top_subjects}Example prompt: "How many emails have I received from packt@mail.packtpub.com and what are they about?"
Typical workflow
User: "Summarise my email activity for the past month."
Claude:
1. list_accounts() → finds account IDs
2. list_mailboxes(account_id) → finds INBOX mailbox_id
3. get_mailbox_stats(...) → top senders, subjects, total count
4. search_emails(query="", date_from="2026-04-20", ...) → recent emails
5. get_email(...) × N → reads relevant messages
→ synthesises a summarySecurity notes
The access token is read from
BICHON_ACCESS_TOKENat startup — never hardcode it in source files..mcp.jsonis gitignored to prevent accidental token commits.envelope_idvalues are validated as UUIDs before use in API paths.All string inputs have length limits; integer IDs must be positive.
API error responses are not forwarded to the AI (only the HTTP status code is).
Email bodies are passed directly to Claude. Malicious emails may contain text designed to manipulate AI behaviour — a known limitation of any email-reading AI tool.
Development
# Install in editable mode
uv pip install -e .
# Verify MCP tools are registered (no Bichon needed)
python3 -c "
import subprocess, json, os, threading, queue, time
proc = subprocess.Popen(['.venv/bin/python', '-m', 'bichon_mcp'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
env={**os.environ, 'BICHON_BASE_URL':'http://localhost:15630','BICHON_ACCESS_TOKEN':'test'},
text=True, bufsize=1)
q = queue.Queue()
threading.Thread(target=lambda: [q.put(l.strip()) for l in proc.stdout], daemon=True).start()
for msg in [
{'jsonrpc':'2.0','id':1,'method':'initialize','params':{'protocolVersion':'2024-11-05','capabilities':{},'clientInfo':{'name':'t','version':'0'}}},
{'jsonrpc':'2.0','method':'notifications/initialized','params':{}},
{'jsonrpc':'2.0','id':2,'method':'tools/list','params':{}},
]:
proc.stdin.write(json.dumps(msg)+'\n')
proc.stdin.flush()
deadline = time.time()+10
while time.time()<deadline:
try:
line = q.get(timeout=1)
obj = json.loads(line)
if obj.get('id')==2:
print([t['name'] for t in obj['result']['tools']])
break
except: pass
proc.terminate()
"
# Expected: ['list_accounts', 'list_mailboxes', 'get_mailbox_stats', 'search_emails', 'get_email', 'list_threads', 'get_sender_summary']License
AGPL-3.0. If you distribute this software, the source must remain open.
Available Tools
7 toolsget_emailA
Get full plain-text content of an email. account_id and envelope_id come from search_emails results. HTML is stripped. Body is truncated at ~4000 tokens.
Inputs: account_id (required), envelope_id (required).
get_mailbox_statsA
Stats for a specific mailbox folder: total count, top senders, top subjects by frequency. Use list_mailboxes to find mailbox_id. Samples up to 200 most recent emails. Results cached for BICHON_STATS_CACHE_TTL seconds (default 300). Set to 0 to disable.
Inputs: account_id (required), mailbox_id (required).
get_sender_summaryB
Aggregate stats for a sender: total count, date range, top subjects.
Inputs: email_address (required).
list_accountsA
List all email accounts configured in Bichon. Returns account id and email address.
Inputs: no named parameters. Returns: result
list_mailboxesA
List mailbox folders for an account (INBOX, Sent, etc.). Use list_accounts to find account_id. Returns id, name, total message count, unseen count.
Inputs: account_id (required). Returns: result
list_threadsA
List email threads by grouping search results on thread_id. Returns one entry per thread with message count and latest date.
Inputs: subject_contains, sender, limit. Returns: result
search_emailsA
Search emails by full-text query, date range, sender, and/or mailbox folder. Returns summaries only (no body). Use get_email for full content. date_from/date_to accept ISO dates (YYYY-MM-DD). Max limit is 50. Use list_accounts + list_mailboxes to find account_id and mailbox_id.
Inputs: query (required), date_from, date_to, sender, +3 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool targets a distinct purpose: listing accounts, mailboxes, threads; searching emails; retrieving full email content; and obtaining statistics on a mailbox or sender. No overlapping functionality.
All tools follow a consistent verb_noun pattern using snake_case: 'list_' for enumerations, 'get_' for retrievals, and 'search_' for searching. No mixing of conventions.
With 7 tools, the set is well-scoped for a read-only email retrieval and statistics server. Each tool covers a necessary operation without redundancy or deficiency.
The tool surface covers the full lifecycle for read-only email access: listing accounts and mailboxes, searching, retrieving full content, and aggregating stats. No obvious gaps for the stated purpose.
Maintenance
Related MCP Connectors
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Your IMAP mailbox as an MCP server: read, search and (if you allow it) organize mail. Open source.
Email safety MCP server. Detects phishing, prompt injection, CEO fraud for AI agents.
Related MCP Servers
- AlicenseAqualityAmaintenanceAn MCP server that gives AI agents permission-gated, audit-logged access to private email providers (Proton Mail via Bridge and plain IMAP), running locally with OAuth-based authentication and human-controlled escalation for destructive operations.6660 npm17MIT
- FlicenseNot gradedqualityBmaintenanceA read-only Gmail MCP server that searches email, fetches complete threads, and stores them as local Markdown and JSON for offline analysis by other agents.1-
- AlicenseAqualityDmaintenanceMCP server that gives AI agents the ability to send, read, and search email via Gmail.432 npmMIT
- FlicenseNot gradedqualityCmaintenanceA private, single-user MCP server that unifies Gmail, Microsoft 365/Outlook, and IMAP mailboxes for LLMs to search and read emails live, without storing or caching mailbox contents.-