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.sgl

The 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/store

Credentials

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>&1

To extract just the tool response text:

... | grep -o '"text":"[^"]*"'

Fastmail-Specific Notes

  • JMAP session URL: Use https://api.fastmail.com/jmap/session directly. The .well-known/jmap URL returns a redirect that sigil-http doesn't follow.
  • CalDAV namespace: Must use urn:ietf:params:xml:ns:caldav (the short form urn:ietf:params:caldav causes 403 on REPORT requests).
  • CalDAV discovery: Fastmail doesn't support calendar-home-set on the principal URL. The client falls back to replacing /principals/ with /calendars/ in the principal path.
  • JMAP onSuccessUpdateEmail: Fastmail rejects #draft back-reference keys in onSuccessUpdateEmail. The send flow uses a separate Email/set call 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

Email

  • bureau/mailboxes — List mailboxes with counts
  • bureau/email-search — Search emails with filters
  • bureau/email-read — Read full email by ID
  • bureau/email-send — Send email (use identity param for sender address)
  • bureau/email-reply — Reply with threading
  • bureau/email-move — Move to mailbox
  • bureau/email-archive — Archive email
  • bureau/email-trash — Trash single email
  • bureau/email-trash-batch — Trash multiple emails (comma-separated IDs)
  • bureau/email-flag — Flag/unflag
  • bureau/email-mark-read — Mark read/unread

Calendar

  • bureau/calendars — List calendars
  • bureau/events — Query events in date range
  • bureau/event-details — Full event details
  • bureau/event-create — Create event
  • bureau/event-update — Update event
  • bureau/event-delete — Delete event
  • bureau/free-slots — Find free time slots

Utility

  • bureau/identities — Sending identities
  • bureau/status — Connection health check