MCP server for an office assistant β E-Mail/Calendar integration, GTD tasks & resource planning
Warning
This project is under active development. Things will break, APIs will change, and features may be incomplete until v1.0. Use at your own risk β and feel free to contribute!
Eule is the German word for owl β a symbol of wisdom, sharp vision, and the ability to see clearly in the dark. Like an owl surveying its territory, Eule gives your AI assistant a clear view across your entire office landscape: emails, calendars, tasks, and contacts β all through a single, unified interface.
Eule is a Model Context Protocol (MCP) server that turns any MCP-compatible AI assistant into a full office agent. Instead of switching between Outlook, task managers, and calendars, your AI assistant connects to all of them through Eule.
βββββββββββββββββββββββββββββββββββββββββββββββ
β AI Assistant (Kiro, Claude, Cursor, ...) β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β MCP Protocol
ββββββββββββββββββββΌβββββββββββββββββββββββββββ
β Eule MCP Server β
β β
β βββββββββββ ββββββββββββ βββββββββββββββ β
β β Mail β β Calendar β β GTD Tasks β β
β ββββββ¬βββββ ββββββ¬ββββββ ββββββββ¬βββββββ β
β ββββββ΄βββ ββββββββ΄βββ ββββββββββ΄ββββββββ β
β β Chat β β Files β β Contacts β β
β βββββ¬ββββ ββββββ¬βββββ βββββββββ¬βββββββββ β
β β β β β
β βββββΌβββββββββββΌβββββββββββββββΌββββββββββ β
β β Provider Layer β β
β β M365 (Graph/EWS) Β· IMAP Β· CalDAV Β· β β
β β CardDAV Β· iCal Β· Signal Β· Google β β
β βββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββ
Key design decisions:
- Multi-provider architecture β M365, Google Workspace, CalDAV, CardDAV, IMAP, iCal, Signal
- Tiered API access β Graph API β EWS β IMAP/SMTP, auto-detected per tenant
- Headless re-authentication β optional TOTP auto-auth via Playwright when tokens expire
- Role-based context β map accounts and connectors to professional roles
- LLM-optimized output β HTML emails rendered as clean Markdown with thread splitting
| Tool | Description |
|---|---|
auth_status |
Show authentication status and configuration |
auth_login |
Authenticate an account (M365 or Google) via browser OAuth |
auth_probe |
Test which API tier works for an account |
| Tool | Description |
|---|---|
role_list |
List all configured roles with connectors and weekly hours |
| Tool | Description |
|---|---|
mail_list |
List emails from any folder (inbox, sentitems, archive, ...) |
mail_read |
Read email as Markdown with attachment metadata |
mail_search |
Search emails, optionally scoped to a folder |
mail_send |
Send, reply, or forward an email |
mail_update |
Mark read/unread, move to folder (archive, spam, ...), or delete |
mail_attachment_get |
Download attachment to disk |
| Tool | Description |
|---|---|
chat_list |
List recent conversations (Signal, Teams) |
chat_read |
Read messages from a conversation |
chat_send |
Send a message to a conversation |
| Tool | Description |
|---|---|
file_search |
Search files in OneDrive/SharePoint/Google Drive |
file_read |
Read file content (text extraction) |
file_list |
List recently modified files |
file_upload |
Upload a file to OneDrive or Google Drive |
| Tool | Description |
|---|---|
calendar_calendars |
List available calendars across all sources |
calendar_list |
List upcoming events from all sources (M365, Google, CalDAV, iCal) |
calendar_today |
Today's schedule with attendees and locations |
calendar_create |
Create event with optional calendar selection |
calendar_update |
Update an existing event |
calendar_delete |
Delete an event |
| Tool | Description |
|---|---|
task_add |
Capture a new task (supports email source linking) |
task_list |
List tasks by status/project/context/role |
task_update |
Update task properties |
task_complete |
Mark task as done |
task_search |
Full-text search across tasks |
| Tool | Description |
|---|---|
contact_add |
Add contact to remote address book (Graph, EWS, Google) or locally |
contact_list |
List contacts from all sources |
contact_search |
Search contacts across all sources |
| Tool | Description |
|---|---|
doc_search |
Full-text search across documents (Paperless-NGX) |
doc_list |
List recent documents with metadata |
doc_read |
Read document metadata and content (OCR text or Markdown via pymupdf4llm) |
doc_download |
Download a document file |
doc_upload |
Upload a document (with title, tags, correspondent, type) |
doc_tag |
Update document metadata (title, tags, correspondent, type) |
doc_bulk |
Bulk operations (add/remove tag, set type, delete, merge, reprocess) |
| Calendar | Contacts | Chat | Files | Documents | ||
|---|---|---|---|---|---|---|
| M365 Graph | β rw | β rw | β rw | β Teams | β rw | β |
| M365 EWS | β rw | β rw | β rw | β | β | β |
| β rw | β rw | β rw | β | β rw | β | |
| IMAP/SMTP | β rw | β | β | β | β | β |
| CalDAV | β | β rw | β | β | β | β |
| CardDAV | β | β | β rw | β | β | β |
| iCal Feed | β | ro | β | β | β | β |
| Signal | β | β | β | β rw | β | β |
| Paperless-NGX | β | β | β | β | β | β rw |
- Node.js 22+
- An M365 or Google Workspace account
git clone https://github.com/metaneutrons/eule-mcp.git
cd eule-mcp
pnpm install
pnpm run build# Interactive setup β authenticates your M365 account
node dist/cli/index.js setupThis opens a browser window for Microsoft OAuth login. After authentication, configure your roles in ~/.eule/config.yaml:
language: de
roles:
- id: work
name: "My Work Role"
weeklyHours: 40
connectors:
mail:
- id: work-mail
type: m365
account: "you@example.com"
calendar:
- id: work-cal
type: m365
account: "you@example.com"
messenger:
- id: teams
type: m365
account: "you@example.com"
files:
- id: sharepoint
type: m365
account: "you@example.com"Generic IMAP (iCloud, Gmail, Fastmail, any mail server):
google:
clientId: "123456.apps.googleusercontent.com"
clientSecret: "GOCSPX-..."
roles:
- id: personal
name: "Personal"
weeklyHours: 0
connectors:
mail:
- id: gmail
type: google
account: "you@gmail.com"
- id: icloud
type: imap
account: "you@icloud.com"
host: "imap.mail.me.com"
smtpHost: "smtp.mail.me.com"
auth: password
password: "xxxx-xxxx-xxxx-xxxx"
calendar:
- id: gcal
type: google
account: "you@gmail.com"
files:
- id: gdrive
type: google
account: "you@gmail.com"
messenger:
- id: signal
type: signal
account: "+491234567890"
signalCliUrl: "http://localhost:8080"
documents:
- id: paperless
type: paperless
account: "paperless.local"
url: "http://paperless:8000"
token: "your-api-token"Kiro CLI:
kiro-cli mcp add --name eule --command node --args "/path/to/eule-mcp/dist/server/index.js"Claude Desktop / Cursor β add to your MCP config:
{
"mcpServers": {
"eule": {
"command": "node",
"args": ["/path/to/eule-mcp/dist/server/index.js"]
}
}
}For unattended re-authentication when tokens expire (e.g., on a server):
# Playwright is already an npm dependency, but the Chromium browser
# binary (~150MB) needs to be downloaded separately:
npx playwright install chromiumAdd to ~/.eule/config.yaml:
autoAuth:
- account: "you@example.com"
password: "your-password"
totpSecret: "YOUR_BASE32_TOTP_SECRET"- OAuth with PKCE + headless TOTP auto-auth
- Multi-tier M365 support (Graph / EWS / IMAP)
- Mail tools (list, read, search, send, reply, attachments)
- HTML β Markdown rendering with thread splitting
- Provider-based architecture
- Calendar read/write (Graph + EWS + CalDAV)
- GTD task engine with SQLite + Markdown export
- Role & context CRUD
- Contacts (local + remote write via Graph/EWS)
- Graph API connectors (Mail + Calendar + Contacts)
- Generic IMAP/SMTP provider (any mail server, password or OAuth)
- CalDAV/CardDAV provider (iCloud, Nextcloud, any CalDAV/CardDAV server)
- iCal feed subscriptions (read-only calendar feeds)
- Resource planning & capacity tracking
- Paperless-ngx connector
- Apple Notes (macOS-only, AppleScript/SQLite)
- Messengers β iMessage (macOS), WhatsApp (Business API), Telegram, Discord, Slack, Matrix
- Google Workspace (Gmail API, Google Calendar API)
- Auto-auth i18n resilience
- IETF OAuth for Open Public Clients (
draft-ietf-mailmaint-oauth-public) β provider-agnostic auth with dynamic client registration - Exchange on-premise support (Basic/NTLM auth, configurable EWS URL)
- sqlite-vec for local semantic search
Contributions are welcome! This project is in early development, so there's plenty to do.
- Fork the repo
- Create a feature branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
Please follow Conventional Commits for commit messages.
GPL-3.0-or-later β free as in freedom.
Made with β€οΈ and AI in Hannover, Germany