AtlatestRenderedmarkdown
Readme
Bureau
Bureau is an MCP server for Fastmail email and calendar, built with Sigil.
Project Structure
bureau/ ├── package.sgl # Package definition ├── dev-redirects.sgl # Points deps at local sigil checkout ├── .env # Credentials (gitignored) ├── src/bureau/ │ ├── main.sgl # Entry point: MCP server setup and run │ ├── config.sgl # Env var credential reading │ ├── connection.sgl # Lazy JMAP/CalDAV client caching │ ├── email.sgl # Email tool handlers │ ├── calendar.sgl # Calendar tool handlers │ └── format.sgl # Output formatting + ISO 8601 parsing └── test/test-bureau.sgl # Unit tests
Dependencies
Bureau depends on these Sigil packages:
- sigil-mcp — MCP server framework
- sigil-jmap — JMAP email client (Fastmail, etc.)
- sigil-caldav — CalDAV calendar client
- sigil-run, sigil-stdlib, sigil-tls, sigil-http — transitive deps declared explicitly
Building
Always build with --redirects to use the local Sigil checkout:
/path/to/sigil/build/dev/bin/sigil build --redirects dev-redirects.sglThe dev config produces a bundled binary at build/dev/bin/bureau.
If you get stale cache errors (empty .a files, corrupt .sgb), clear the cache:
rm -rf ~/.cache/sigil/storeCredentials
Bureau needs a .env file (gitignored) with three variables:
[email protected] BUREAU_FASTMAIL_API_TOKEN=fmu1-... BUREAU_FASTMAIL_APP_PASSWORD=fmu1-...
- BUREAUFASTMAILUSERNAME — Fastmail email address (used as CalDAV username)
- BUREAUFASTMAILAPI_TOKEN — Fastmail API token for JMAP email access (
Authorization: Bearer <token>) - BUREAUFASTMAILAPP_PASSWORD — Fastmail app password for CalDAV calendar access (HTTP Basic auth)
These must be separate credentials — an API token (Settings → API tokens) for JMAP and an app password (Settings → App passwords) for CalDAV.
Testing MCP Tools
Test tools by piping JSON-RPC messages to the bureau binary:
source .env && echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"bureau/mailboxes","arguments":{}}}' | timeout 30 ./build/dev/bin/bureau serve 2>&1To extract just the tool response text:
... | grep -o '"text":"[^"]*"'Fastmail-Specific Notes
- JMAP session URL: Use
https://api.fastmail.com/jmap/sessiondirectly. The.well-known/jmapURL returns a redirect that sigil-http doesn't follow. - CalDAV namespace: Must use
urn:ietf:params:xml:ns:caldav(the short formurn:ietf:params:caldavcauses 403 on REPORT requests). - CalDAV discovery: Fastmail doesn't support
calendar-home-seton the principal URL. The client falls back to replacing/principals/with/calendars/in the principal path. - JMAP onSuccessUpdateEmail: Fastmail rejects
#draftback-reference keys inonSuccessUpdateEmail. The send flow uses a separateEmail/setcall to move to Sent after submission. - JSON null values: JSON null is truthy in Sigil. Always guard with
(string? x)before calling string operations on values that might be null.
MCP Tools
bureau/mailboxes— List mailboxes with countsbureau/email-search— Search emails with filtersbureau/email-read— Read full email by IDbureau/email-send— Send email (useidentityparam for sender address)bureau/email-reply— Reply with threadingbureau/email-move— Move to mailboxbureau/email-archive— Archive emailbureau/email-trash— Trash single emailbureau/email-trash-batch— Trash multiple emails (comma-separated IDs)bureau/email-flag— Flag/unflagbureau/email-mark-read— Mark read/unread
Calendar
bureau/calendars— List calendarsbureau/events— Query events in date rangebureau/event-details— Full event detailsbureau/event-create— Create eventbureau/event-update— Update eventbureau/event-delete— Delete eventbureau/free-slots— Find free time slots
Utility
bureau/identities— Sending identitiesbureau/status— Connection health check