Usage

September 20, 2026 · View on GitHub

Prerequisites

  • Go 1.24+
  • A TypeSafe API key
  • A Google Cloud project with Gmail API enabled
  • An OAuth Desktop client JSON (installed), redirect URI http://localhost

One-time setup

cd MailboxBoy
cp .env.example .env
# Put TYPESAFE_API_KEY=... in .env

go run ./cmd/mailboxboy labels init

This writes ~/.config/mailboxboy/taxonomy.yaml from configs/default-taxonomy.yaml.

Download the Desktop client JSON from Google Cloud Console and save it as:

~/.config/mailboxboy/credentials.json

Authorize (browser opens; keep the CLI running until it prints saved token):

go run ./cmd/mailboxboy auth

Create the Gmail labels named in the taxonomy (校园, 金融, 通知/重要, …):

go run ./cmd/mailboxboy labels ensure

First classification

Dry-run (Jev is called; Gmail is not modified):

go run ./cmd/mailboxboy sync --max 20

Write labels:

go run ./cmd/mailboxboy sync --max 20 --apply

Re-scan the latest INBOX page (ignores the history cursor):

go run ./cmd/mailboxboy sync --max 100 --apply --full

Daemon (poll + HTTP). Default applies labels:

go run ./cmd/mailboxboy serve
  • Health: curl http://127.0.0.1:8080/healthz
  • Status: curl http://127.0.0.1:8080/status
  • Kick: curl -X POST http://127.0.0.1:8080/hooks/sync

Taxonomy

Edit ~/.config/mailboxboy/taxonomy.yaml (or ./config/taxonomy.yaml in Docker).

Noul label

- id: pets
  enabled: true
  type: noul
  name: 宠物
  gmail: 宠物
  threshold: 0.65
  description: >
    Mail about the owner's animals.

CLI equivalent:

go run ./cmd/mailboxboy labels add --id pets --name 宠物 --desc "Mail about the owner's animals." --gmail 宠物
go run ./cmd/mailboxboy labels ensure

id must match ^[a-z][a-z0-9_]*$. At most 40 enabled user labels.

Score label

Levels are ordered. Only the selected level’s gmail is written. Omit gmail for a rung that should not appear in Gmail (例行通知).

Safety switches

go run ./cmd/mailboxboy safety spam off
go run ./cmd/mailboxboy safety fraud on
go run ./cmd/mailboxboy labels list

Owner hints

In YAML owner::

  • note — always sent (language, how to read the mailbox)
  • known_senders — full From addresses that veto auto-spam
  • campus_domains — domains that veto auto-spam

Changing descriptions changes the pack version; already-classified messages are classified again on the next sync.

CLI reference

CommandPurpose
authDesktop OAuth; writes token.json
labels init [--force]Seed taxonomy YAML
labels listPrint pack hash and labels
labels add/set/disableEdit taxonomy
labels ensureCreate missing Gmail labels
labels strip NAME [--if OTHER]Remove a Gmail label from messages
classify --eml FILEClassify a local .eml
classify --id GMAIL_ID --applyClassify one Gmail id
sync / runHistory or --full batch
serveDaemon
reviewList 待复核; `--id … --accept
evalGolden .eml report

--dump-request on classify prints the JSON posted to Jev (no network if you only dump).

Environment

VariableMeaning
TYPESAFE_API_KEYRequired for Jev
MAILBOXBOY_CONFIG_DIRTaxonomy + Gmail JSON
MAILBOXBOY_DATA_DIRSQLite
MAILBOXBOY_LISTENserve bind (default :8080)
MAILBOXBOY_POLLHistory poll (default 5s; 0 = hooks only)
MAILBOXBOY_WEBHOOK_TOKENBearer / ?token= / X-MailboxBoy-Token
GMAIL_PUBSUB_TOPICprojects/…/topics/… for users.watch

Review queue

Gray-zone safety, vetoed spam, or “no life label fired” set 待复核. List:

go run ./cmd/mailboxboy review --limit 50

Mark locally and optionally write Gmail:

go run ./cmd/mailboxboy review --id MESSAGE_ID --accept --apply
go run ./cmd/mailboxboy review --id MESSAGE_ID --spam --apply

Tests

go test ./...
go run ./cmd/mailboxboy eval

Fixtures live in testdata/eml and testdata/golden.jsonl.