OAKENMAIL
Beta

Set up Oaken from scratch

This walks through a first setup on one machine: install, the config file, the local model, one mail account, the daemon, a first sync, and, if you want it, the MCP server. Each step says how to check that it worked.

Oaken is in beta. Everything below stays on your machine.

1

1. Install

You need Python 3.11 or newer and uv.

python3 -m pip install oaken-core   # into a virtual environment you keep for it
oaken --help

To work on Oaken itself, use a checkout instead: git clone https://github.com/dfoulks1/oaken-mail, uv sync, then run commands as oaken ... (or activate .venv to type oaken alone). The commands below are written as oaken .... To check the install:

oaken --version
oaken help sync
2

2. Write config.toml

The file lives outside the repository, in your per-user config directory (~/.config/oaken/ on Linux). Start from the documented template:

mkdir -p ~/.config/oaken
cp config.example.toml ~/.config/oaken/config.toml

Every section has defaults, so you only keep what you change. Never put a password or token in this file; step 5 stores them in your keyring. See Store credentials in your keyring if you have not used one before.

You do not have to copy anything: the first time core starts it writes a config.toml with every setting shown at its default, commented out. Edit it in the console at /config (it tests a change before saving and keeps a .bak), or with oaken config show, oaken config test FILE and oaken config save FILE, then apply it with oaken config reload.

Where Oaken keeps its files

Set OAKEN_HOME=/some/dir to put everything (config, data, the runtime file) under one directory, and put the line in your shell profile so every shell agrees. If it is unset, core warns, then uses the last home it ran under, or the platform folders if there is none, and tells you the line to add. Core cannot export a variable into your shell; it remembers the home in a small pointer file outside the home instead.

Plugins that are not set up

A plugin that is installed but has no [plugins.<kind>.<name>] table (Gmail, IMAP, SMTP) is listed as "not configured", not as an error. To turn one off for good, set enabled = false in its table. Without restarting core: oaken plugins disable gmail, oaken plugins enable gmail, and oaken plugins reload gmail to pick up a change to its table. oaken plugins config gmail shows its settings and oaken plugins set gmail page_size=200 changes one (your comments in config.toml are kept; reload to apply). Each plugin kind has a page or tab (Triage, Embed, Enrich, or a General tab) with an enable switch and a Reload button.

3

3. Get the local models

Oaken runs a local Ollama by default. It never pulls models itself, so pull the ones named in [ai] (these are the defaults):

ollama pull nomic-embed-text     # the embedder
ollama pull qwen2.5:3b           # the language model

To use a model you already have, set llm_model (and embed_model) under [ai] in config.toml.

4

4. Add an account

Pick the provider that matches the account:

Then register the account. On a terminal this asks for the provider, an id, a display name and the provider's non-secret settings:

oaken admin account add
oaken admin account list

The account id (letters, digits, - and _) names the provider instance, gmail@<id>, and its keyring entry.

5

5. Store the credential

oaken gmail auth --account-id <id>     # opens Google's consent page and waits
oaken imap auth --account-id <id>      # or: asks for the password, no echo

Each provider owns its own sign-in, so the command starts with the provider's name (oaken smtp auth works the same way). The credential goes to the OS keyring and is never printed. Add --check to test one that is already stored.

6

6. Start the daemon and check it

oaken start                   # in the background; --fg keeps it attached to this terminal
oaken status                  # prints the pid and the loopback port
oaken plugins                 # your account's provider row should say healthy
oaken admin account show <id> # a "problem:" line says why one is not

If oaken start fails (for example "core exited while starting"), run oaken start --fg. It stays attached and prints the real error, such as a port already in use.

Core serves a small API on loopback only. Its token is the file api_token in the config directory. The daemon and the local API explains the rest.

7

7. Sync and look

oaken sync --wait                    # every account on every provider; or add --account <id>
oaken search "invoice"

The first sync of a large mailbox takes a while by design. Mail is stored under your user data directory (~/.local/share/oaken/ on Linux). A schedule then keeps the account current; see Sync schedule.

8

8. Optional: connect an AI client

The MCP server is off until you turn it on. Add this to config.toml and restart core:

[api]
mcp = true

Then follow Connect an AI client to point Claude Desktop or another client at oaken mcp. Changes made through it always ask for confirmation first.

9

If something fails

Message Likely cause
no OS keyring is available The keyring is locked or not running. See the keyring page.
client_secret_file is missing or is not a Google OAuth client JSON The file does not exist, or is a web client. It must be a Desktop-app client with an installed block.
core is already running A daemon is up. oaken status shows where; oaken stop ends it.
core_not_running from a tool call Start it with oaken start.