pikuri-thunderbird

Search and read your local Thunderbird mail and calendars from a pikuri agent — reading Thunderbird's own on-disk profile, never touching the network. Part of the pikuri family.

The default surface is read-only and egress-free: four inbound tools (thunderbird_mail_search / thunderbird_mail_read / thunderbird_calendar_search / thunderbird_calendar_read). An agent wired with only these has your private mailbox and untrusted message content but no way to send anything out — the lethal trifecta is broken by construction.

pikuri never sends mail on its own. If you turn on the opt-in thunderbird_mail_compose tool, the most it can do is open a pre-filled Thunderbird compose window — you read it, and you click Send. It draws the draft in plain text (no hidden HTML, no tracking images), refuses a body laced with invisible characters, drops look-alike recipient addresses for you to retype, and warns you when you're about to mail a domain you've never corresponded with. See DESIGN.md.

Requirements

  • Linux, with Thunderbird installed (snap or apt).
  • For mail search: Thunderbird's global search index (Gloda) enabled — the default. For calendar: events must be cached to disk (a local calendar, or a network calendar with "Offline Support" turned on).

Try it

./bin/pikuri-thunderbird "what did Alice say about the invoice last month?"

It auto-discovers your active Thunderbird profile. Point it elsewhere with --profile-dir /path/to/profile. This demo wires the full surface, including the compose hand-off — ask it to reply to a message and it opens a pre-filled Thunderbird window for you to send (it never sends by itself). The demo talks to a local llama.cpp server by default; put your LLM connection in ~/.pikuri-examples-config.yaml (llm_server, llm_model, llm_api_key).

Wire it into your own agent

require 'pikuri-thunderbird'

agent = Pikuri::Agent.new(transport:, system_prompt:) do |c|
  c.add_extension Pikuri::Thunderbird::Extension.new
end

Mail tools register only when the Gloda index is present; calendar tools register whenever a profile is found (and guide you to enable Offline Support if nothing is cached yet). To add an outbound hand-off, pass Extension.new(allow_compose_mail: true) (draft a message) or allow_create_calendar_event: true (draft a calendar event) — each stays off unless you ask for it, and your system_prompt should then tell the model it may draft for you to send/import (an inbound-only prompt that forbids sending will keep the tools unused).

How it works

pikuri copies a consistent snapshot of Thunderbird's SQLite databases (so it never fights Thunderbird for the lock), builds its own fast full-text index over the already-decoded mail, and serves ranked search + full reads with no MIME parsing. Design and threat model: DESIGN.md. In-flight design notes: ideas/thunderbird.md in the repo.