Operations
Everything a client can ask Oaken Mail to do, with its permission class and MCP exposure, generated from the registry.
Every operation, defined once. The general API, the CLI and the MCP server are generated from the same registry. How it works.
Permission: read changes nothing, mutate asks for confirmation, send is refused in this version. MCP is the ceiling in code and the default; the user can lower it, and raise it only up to the ceiling. Marks read means it may change read state.
| Operation | Permission | MCP | Marks read | What it does |
|---|---|---|---|---|
approve_action |
mutate | never | no | Say yes to an action that is waiting for approval: it runs now, for this message and route. |
cache_stats |
read | never | no | The enrichment cache: how many answers it holds, how big, from which prompt versions, and how often it saved a model call. |
cancel_job |
mutate | never | no | Cancel a queued job, or ask a running one to stop at its next safe point. |
check_plugin_config |
read | never | no | Test one plugin's settings before saving them: they are checked against the plugin's own schema and capabilities, then a throwaway instance is started on them and asked if it is healthy. Give no change to test the saved settings. The running plugin is not touched and nothing is written. |
check_settings |
read | never | no | Test a change to one section of core's settings without saving it: field-level errors, which keys would change, and whether it needs a reload, a reindex or a restart. |
check_workspace |
read | never | no | Validate workspace settings without saving: field errors, the effective backend, and a warning when trust would drop from secure to insecure. |
clear_cache |
mutate | never | no | Delete cached model answers (all, or one task's). Only derived results go: mail, the index and the usage record are untouched, and anything cleared is recomputed the next time it is asked for, at the cost of the model calls the cache had saved. |
config_get |
read | never | no | Read the current config.toml text (non-secret; tokens are never stored here). |
config_reload |
mutate | never | no | Reload core on the saved config.toml (the Reload button). Core rebuilds in place: the old config is restored automatically if the new one fails to start. Watch /v1/health to see it come back (the port may change). |
config_save |
mutate | never | no | Validate and save config.toml, backing up the previous file (the Save button). Does not reload core; call config_reload to apply. |
config_validate |
read | never | no | Test an edited config.toml against the settings schema without saving it (the Test button). |
create_account |
mutate | never | no | Add an account. Its credential is stored separately by the provider's own auth command (for example gmail.auth). |
create_agent |
mutate | never | no | Register an external agent and show its token once. |
create_folder |
mutate | never | no | Make a folder under Inbox, and any folders above it. A path that already exists is fine. |
create_label |
mutate | never | no | Make a label (a tag for finding mail). A label that already exists is fine. |
enrich_message |
mutate | never | no | Run the enrichers on one message now. |
events_tail |
read | never | no | The most recent events core published, from its event log: what happened before this page was opened, or before core was last restarted. Ids, states and numbers, never mail text. |
get_account |
read | never | no | One account: provider, its non-secret settings, what the provider's settings are, and why it cannot sync if it cannot. |
get_action |
read | on by default | no | Show what the actions did about a message: for each action and route, whether it succeeded, failed or was skipped. An action that is waiting for approval is a parked job. |
get_enrichment |
read | on by default | no | Show the stored enrichment results (summary, actions, inspector) for a message. The triage verdict is get_triage. |
get_message |
read | on by default | no | One message: its summary and triage when stored, the cleaned text and metadata. Prefer include_text=false and read the summary first; open the text only when you need it. Never marks it read. |
get_message_rules |
read | on by default | no | How a message was filed: its labels, flags and disposition, and the rule behind each. |
get_plugin_config |
read | never | no | Read one plugin's settings: its [plugins.NAME] table, the schema of its settings and an example to start from. Non-secret only. |
get_raw |
read | never | no | The raw headers of a message, and optionally its raw bytes, for inspection. Not for MCP. |
get_settings |
read | never | no | Core's own settings that a client may edit: each key's value, default, where the value comes from (default, config.toml or an environment variable), its schema, and what changing it costs (a reload, a reindex). Name a section or get them all. |
get_thread |
read | on by default | no | A conversation as a tree: every message that shares a thread, in reading order, each with its parent and depth. |
get_triage |
read | on by default | no | Show the stored triage verdict for a message: which triager rated it, the category, level (priority) and whether a reply is owed. |
get_workspace |
read | off until you turn it on | no | One workspace: its settings as editable TOML, the effective LLM backend, and usage numbers. |
list_accounts |
read | on by default | no | The configured accounts: id, provider and display name (never credentials). |
list_actions |
read | off until you turn it on | no | The actions waiting for approval or for a route to be answered, and what the actions did lately. No message text. |
list_agents |
read | never | no | List the registered agents (never their tokens). |
list_audit |
read | never | no | The newest audit-log rows: who changed what, why, and whether it can be undone. |
list_jobs |
read | on by default | no | The newest jobs in the durable queue, with their status, attempts and any scrubbed error. |
list_labels |
read | on by default | no | Every label, folder (location) and disposition with how many live messages carry it. |
list_mailbox |
read | on by default | no | The sidebar: Inbox and Discarded, the folder tree under Inbox, and labels, each with how many messages are in it and how many are unread. Empty folders and labels are included. |
list_messages |
read | on by default | no | List the newest messages that match the filters, with a short snippet of each. |
list_operations |
read | never | no | Every operation with its permission class, and whether MCP clients may call it. |
list_plugins |
read | on by default | no | Every plugin: kind, version, capabilities, health, the operations it offers, its settings. |
list_schedules |
read | on by default | no | Every sync schedule: when it next runs, how the last run went, and whether it is paused. |
list_workspaces |
read | off until you turn it on | no | List every configured workspace plus the implicit 'default', with its trust level, effective LLM backend, and aggregate usage numbers. |
mailbox_counts |
read | on by default | no | The sidebar's numbers in one call: Inbox, Starred and Discarded, every folder (location) and every label, each with how many messages and how many are unread. No mail content. |
mark_read |
mutate | on by default | yes | Mark messages read. Written back to the mailbox; undoable. |
mark_unread |
mutate | on by default | yes | Mark messages unread. Written back to the mailbox; undoable. |
message_dismissed |
read | never | no | The user stopped looking before the delay passed: cancel the pending mark. |
message_presented |
mutate | never | yes | The user is looking at this message: core marks it read after the configured delay. |
move_to_folder |
mutate | never | no | File messages into a folder under Inbox (made if new), or back into the Inbox. The person's choice beats a Sieve rule's. |
pause_backfill |
mutate | never | no | Pause the model-bound ingest stages (embed, enrich), or just one with stage. Mail keeps landing and being filtered; a running job finishes. It survives a restart. |
pause_schedule |
mutate | never | no | Pause a sync schedule until it is resumed. |
pipeline_status |
read | on by default | no | Where ingest stands: each stage's queue, throughput and ETA, and jobs parked as failed. |
plugin_disable |
mutate | never | no | Stop a plugin and keep it off until plugin_enable or a restart, without reloading core. Put enabled = false in the plugin's [plugins] table to make it last. |
plugin_enable |
mutate | never | no | Start a plugin that plugin_disable stopped. A plugin whose table says enabled = false stays off until that line is removed and the plugin is reloaded. |
plugin_health |
read | on by default | no | Whether plugins are started and healthy, and why not if they are not. |
plugin_reload |
mutate | never | no | Restart one plugin on the current config.toml (and pick up a plugin installed since boot) without reloading core. |
rebuild_index |
mutate | never | no | Rebuild the search index from the raw store (resumable). |
remove_account |
mutate | never | no | Remove an account and its sync schedules. Stored mail is kept; the credential is dropped. |
remove_schedule |
mutate | never | no | Remove a sync schedule (a per-folder one, or an account's, which stops its sync). |
remove_workspace |
mutate | never | no | Remove a workspace from config.toml. Refuses to remove 'default'. LLM cache and usage rows are kept; clear them separately. |
reprocess |
mutate | never | no | Bring one pipeline stage up to date for old mail (parse, filter, embed, triage, enrich, action, scan or start). |
reset_usage |
mutate | never | no | Clear the token-usage record (the figures the stats page shows). Model calls and the context savings both go; mail, the index and the enrichment cache are untouched. The accounting starts fresh from the next call. |
resume_backfill |
mutate | never | no | Resume the model-bound ingest stages after a pause, or just one with stage. |
resume_schedule |
mutate | never | no | Resume a paused sync schedule: it is due now and its failure count is cleared. |
retry_job |
mutate | never | no | Re-queue a failed or cancelled job to run now, clearing its last error. |
retry_parked |
mutate | never | no | Re-queue one parked ingest job, or with all=true every parked ingest job, to run again. |
revoke_agent |
mutate | never | no | Revoke an agent at once; the jobs it holds go back to the queue. |
savings_summary |
read | on by default | no | Tokens saved, by caller: model calls the cache skipped, and mail text kept out of a client's context. Estimates. |
search |
read | on by default | no | Hybrid search: keyword and meaning together. Understands from:, before:, after:, is:unread, category: and "quoted phrases". |
search_keyword |
read | on by default | no | Keyword search (BM25) over the index: words, phrases, -exclusions and from:/label:/after:. |
set_account_config |
mutate | never | no | Replace an account's non-secret settings (and, if given, its display name). |
set_flagged |
mutate | off until you turn it on | no | Star or unstar messages. Written back to the mailbox through \Flagged; undoable. |
set_labels |
mutate | never | no | Add labels to messages (made if new) and remove labels the person added earlier. |
set_operation_exposure |
mutate | never | no | Choose whether MCP clients may call an operation, or all of a plugin's operations. |
set_pipeline_limits |
mutate | never | no | Change how many jobs of a stage run at once, now and after a restart. A running job is never dropped: a lower number takes effect as running jobs finish. |
set_plugin_config |
mutate | never | no | Change one plugin's settings in its [plugins.KIND.NAME] table (or the older [plugins.NAME]) and leave the rest of config.toml, comments included, as it is. Keys are merged onto the saved ones (or replace them); text from an editor keeps the person's comments. Validated first; the previous file is backed up. Does not restart the plugin: call plugin_reload to apply. |
set_schedule |
mutate | never | no | Create or change a sync schedule. The floor and the timezone are checked now. |
set_settings |
mutate | never | no | Change core's settings in one section of config.toml, keeping the file's comments and every other table. Validated first (the whole file), and the previous file is backed up. It does not reload core: apply it with config_reload (oaken reload). The result says which keys need a reload, a reindex or a restart. |
set_workspace |
mutate | never | no | Create or update a workspace in config.toml, keeping all other tables and comments. The change takes effect immediately (live reload); no restart needed. |
sieve_check |
read | never | no | Compile a Sieve script and report the first error, with its line. |
sieve_delete |
mutate | never | no | Remove one Sieve script. It stops running on the next filter pass. |
sieve_get |
read | never | no | Read one Sieve script's text, so an editor can load it. |
sieve_list |
read | never | no | List the Sieve scripts on disk, and any skipped with the reason. |
sieve_save |
mutate | never | no | Compile a Sieve script and, only if it compiles, save it so it runs on the next filter pass. |
sieve_test |
read | never | no | Run a Sieve script on one message and show each effect and its rule. Stores nothing. |
status |
read | on by default | no | A short health summary: accounts, messages, index, queue, plugins and paused schedules. |
storage_info |
read | never | no | Where Oaken keeps its data and how big it is: the two databases, their write-ahead logs and the quarantine folder. Read from the filesystem, not by scanning mail. |
summarize_message |
mutate | on by default | yes | Summarize messages with the local model. Optionally mark the summarized ones read. |
sync_now |
mutate | on by default | no | Sync an account (or one folder) now, or every account on every provider when none is named. Each is a job that calls the provider's pull; it joins a sync already queued or running. |
trace_set |
mutate | never | no | Turn the trace on or off now (`oaken trace on |
trace_status |
read | never | no | Whether the trace is on, and where its file is. The trace records what a model or an agent is told, thinks and returns, with the full text. |
trace_tail |
read | never | no | The most recent trace events (oldest first), optionally for one plugin (plugin.KIND.NAME), one job or one message: prompts, responses, thinking, tool calls, timings and what was committed. Holds mail text. |
triage_message |
mutate | never | no | Run the triagers on one message now and store the verdict. |
try_triage |
read | on by default | no | Run triage on one stored message, or on pasted text, and show the verdict without storing it: which triager decided (a header rule or a model), the category, priority and whether a reply is owed. For tuning: change a rule or the triage model, then try again. |
undo |
mutate | on by default | yes | Undo a read-state change from the audit log, restoring exactly what each message was. |
usage_summary |
read | on by default | no | Model calls and tokens per workspace, stage and model, and what the cache saved. |
vacuum |
mutate | never | no | Rewrite raw.db and index.db to give back the space deleted rows left. One at a time, and not while a rebuild runs. It holds each database's write lock while it works (ingest waits, reads go on) and needs about the database's own size free on the disk. |
Inputs and outputs
A trailing ? marks an optional field.
approve_action
Say yes to an action that is waiting for approval: it runs now, for this message and route.
- Input:
message_id,action,route - Output:
approved
cache_stats
The enrichment cache: how many answers it holds, how big, from which prompt versions, and how often it saved a model call.
- Input: none
- Output:
entries,bytes,by_task?,prompt_versions?,oldest?,hits,misses,hit_rate?
cancel_job
Cancel a queued job, or ask a running one to stop at its next safe point.
- Input:
job_id - Output:
job_id,status
check_plugin_config
Test one plugin's settings before saving them: they are checked against the plugin's own schema and capabilities, then a throwaway instance is started on them and asked if it is healthy. Give no change to test the saved settings. The running plugin is not touched and nothing is written.
- Input:
plugin,text?,config?,unset?,replace?,kind? - Output:
ok,problems?,probes?
check_settings
Test a change to one section of core's settings without saving it: field-level errors, which keys would change, and whether it needs a reload, a reindex or a restart.
- Input:
section,values?,unset? - Output:
ok,errors?,changed?,reload_needed?,reindex_needed?,restart_needed?,env_overridden?,warnings?
check_workspace
Validate workspace settings without saving: field errors, the effective backend, and a warning when trust would drop from secure to insecure.
- Input:
name,toml? - Output:
valid,errors?,warnings?,effective_backend?
clear_cache
Delete cached model answers (all, or one task's). Only derived results go: mail, the index and the usage record are untouched, and anything cleared is recomputed the next time it is asked for, at the cost of the model calls the cache had saved.
- Input:
task? - Output:
deleted
config_get
Read the current config.toml text (non-secret; tokens are never stored here).
- Input: none
- Output:
path,text,exists
config_reload
Reload core on the saved config.toml (the Reload button). Core rebuilds in place: the old config is restored automatically if the new one fails to start. Watch /v1/health to see it come back (the port may change).
- Input: none
- Output:
ok,requested,error?
config_save
Validate and save config.toml, backing up the previous file (the Save button). Does not reload core; call config_reload to apply.
- Input:
text - Output:
ok,path,backup?,error?
config_validate
Test an edited config.toml against the settings schema without saving it (the Test button).
- Input:
text - Output:
ok,error?
create_account
Add an account. Its credential is stored separately by the provider's own auth command (for example gmail.auth).
- Input:
account_id,provider,display_name,config? - Output:
account_id,provider,display_name,config,receive_only?,capabilities?,problem?,config_schema?
create_agent
The swarm must be enabled and every kind listed in [swarm] allowed_kinds.
- Input:
label,kinds,account_ids?,max_leases?,max_per_hour? - Output:
agent,token
create_folder
Make a folder under Inbox, and any folders above it. A path that already exists is fine.
- Input:
path - Output:
path,created
create_label
Make a label (a tag for finding mail). A label that already exists is fine.
- Input:
name - Output:
name,created
enrich_message
Run the enrichers on one message now.
- Input:
message_id,enrichers?,force? - Output:
message_id,ran,cached,results
events_tail
The most recent events core published, from its event log: what happened before this page was opened, or before core was last restarted. Ids, states and numbers, never mail text.
- Input:
limit?,since?,kinds? - Output:
events
get_account
One account: provider, its non-secret settings, what the provider's settings are, and why it cannot sync if it cannot.
- Input:
account_id - Output:
account_id,provider,display_name,config,receive_only?,capabilities?,problem?,config_schema?
get_action
Show what the actions did about a message: for each action and route, whether it succeeded, failed or was skipped. An action that is waiting for approval is a parked job.
- Input:
message_id - Output:
message_id,actions
get_enrichment
Show the stored enrichment results (summary, actions, inspector) for a message. The triage verdict is get_triage.
- Input:
message_id,enricher? - Output:
message_id,results,content_is_untrusted?
get_message
The cleaned text (quotes and signatures removed), cut to the caller's limit. Reading a message here does not change read state: only opening or summarizing it, by the user, does.
- Input:
message_id,include_text?,text_chars? - Output:
message_id,account_id,thread_key?,subject?,from_addr?,from_name?,date?,labels?,disposition?,location?,is_read?,starred?,to_addrs?,cc_addrs?,message_id_header?,in_reply_to?,references?,indexed?,text?,truncated?,attachments?,summary?,key_points?,category?,priority?,needs_reply?,content_is_untrusted?
get_message_rules
How a message was filed: its labels, flags and disposition, and the rule behind each.
- Input:
message_id - Output:
message_id,attrs,filter?
get_plugin_config
Read one plugin's settings: its [plugins.NAME] table, the schema of its settings and an example to start from. Non-secret only.
- Input:
plugin,kind? - Output:
plugin,kind?,exists,config,text?,config_schema?,config_example?
get_raw
The raw headers of a message, and optionally its raw bytes, for inspection. Not for MCP.
- Input:
message_id,include_raw? - Output:
message_id,size_raw,in_lfs,headers,raw_base64?,truncated?
get_settings
Core's own settings that a client may edit: each key's value, default, where the value comes from (default, config.toml or an environment variable), its schema, and what changing it costs (a reload, a reindex). Name a section or get them all.
- Input:
section? - Output:
sections
get_thread
Ask by any message id or by thread key. parent_id is the message it replies to (the nearest ancestor we hold when its direct parent never arrived); a message that answers nothing we have is a root. Never marks anything read.
- Input:
message_id?,thread_key?,limit? - Output:
thread_key,items?,total?,truncated?,content_is_untrusted?,warnings?
get_triage
Show the stored triage verdict for a message: which triager rated it, the category, level (priority) and whether a reply is owed.
- Input:
message_id - Output:
message_id,rated,triager?,version?,model?,result?,content_is_untrusted?
get_workspace
One workspace: its settings as editable TOML, the effective LLM backend, and usage numbers.
- Input:
name - Output:
name,trust,llm_backend,llm_backend_raw,toml,overridden_keys?,usage?
list_accounts
The configured accounts: id, provider and display name (never credentials).
- Input: none
- Output:
accounts
list_actions
The actions waiting for approval or for a route to be answered, and what the actions did lately. No message text.
- Input:
limit? - Output:
waiting,recent
list_agents
List the registered agents (never their tokens).
- Input:
include_revoked? - Output:
agents
list_audit
The newest audit-log rows: who changed what, why, and whether it can be undone.
- Input:
limit?,op?,since?,cursor? - Output:
entries,next_cursor?
list_jobs
The newest jobs in the durable queue, with their status, attempts and any scrubbed error.
- Input:
status?,kind?,account_id?,limit? - Output:
jobs
list_labels
Every label, folder (location) and disposition with how many live messages carry it.
- Input: none
- Output:
labels,dispositions,locations,unread?,content_is_untrusted?
list_mailbox
The sidebar: Inbox and Discarded, the folder tree under Inbox, and labels, each with how many messages are in it and how many are unread. Empty folders and labels are included.
- Input: none
- Output:
inbox,discarded,folders,labels,content_is_untrusted?
list_messages
Newest first unless sort says otherwise. Snippets by default; include_text adds the cleaned text within the reply's character budget. Never marks anything read.
- Input:
account_id?,label?,location?,from?,after?,before?,disposition?,unread_only?,starred?,has_attachment?,thread_key?,limit?,offset?,sort?,include_text?,text_chars? - Output:
items,truncated?,offset?,total?,total_exact?,content_is_untrusted?,warnings?
list_operations
Every operation with its permission class, and whether MCP clients may call it.
- Input: none
- Output:
operations
list_plugins
Every plugin: kind, version, capabilities, health, the operations it offers, its settings.
- Input:
name? - Output:
plugins
list_schedules
Every sync schedule: when it next runs, how the last run went, and whether it is paused.
- Input:
crontab? - Output:
schedules,crontab?
list_workspaces
List every configured workspace plus the implicit 'default', with its trust level, effective LLM backend, and aggregate usage numbers.
- Input: none
- Output:
workspaces
mailbox_counts
The sidebar's numbers in one call: Inbox, Starred and Discarded, every folder (location) and every label, each with how many messages and how many are unread. No mail content.
- Input:
account_id?,include_discarded? - Output:
inbox?,starred?,discarded?,locations?,labels?,content_is_untrusted?
mark_read
Mark messages read. Written back to the mailbox; undoable.
- Input:
ids,after_summary? - Output:
changed,unchanged,missing,local_only,audit_ids,batch_id?,skipped?
mark_unread
Mark messages unread. Written back to the mailbox; undoable.
- Input:
ids,after_summary? - Output:
changed,unchanged,missing,local_only,audit_ids,batch_id?,skipped?
message_dismissed
The user stopped looking before the delay passed: cancel the pending mark.
- Input:
message_id - Output:
cancelled
message_presented
The user is looking at this message: core marks it read after the configured delay.
- Input:
message_id - Output:
armed
move_to_folder
File messages into a folder under Inbox (made if new), or back into the Inbox. The person's choice beats a Sieve rule's.
- Input:
ids,path? - Output:
path,moved
pause_backfill
Pause the model-bound ingest stages (embed, enrich), or just one with stage. Mail keeps landing and being filtered; a running job finishes. It survives a restart.
- Input:
why?,stage? - Output:
llm_paused,reason?,paused_stages?
pause_schedule
Pause a sync schedule until it is resumed.
- Input:
account_id,folder?,why? - Output:
schedule
pipeline_status
Where ingest stands: each stage's queue, throughput and ETA, and jobs parked as failed.
- Input:
stages?,counts? - Output:
stages,docs,chunks,index_stale,vector_model?,vectors,embedder_model?,embeddings_stale,backfill_paused,llm_paused?,quarantined_files,parked?,enrichers?
plugin_disable
Stop a plugin and keep it off until plugin_enable or a restart, without reloading core. Put enabled = false in the plugin's [plugins] table to make it last.
- Input:
name - Output:
changed,plugins
plugin_enable
Start a plugin that plugin_disable stopped. A plugin whose table says enabled = false stays off until that line is removed and the plugin is reloaded.
- Input:
name - Output:
changed,plugins
plugin_health
Whether plugins are started and healthy, and why not if they are not.
- Input:
name? - Output:
plugins
plugin_reload
Restart one plugin on the current config.toml (and pick up a plugin installed since boot) without reloading core.
- Input:
name - Output:
changed,plugins
rebuild_index
Rebuild the search index from the raw store (resumable).
- Input:
account_id?,force? - Output:
job_id,created
remove_account
Remove an account and its sync schedules. Stored mail is kept; the credential is dropped.
- Input:
account_id - Output:
removed,schedules_removed?,restart_needed?,mail_kept?
remove_schedule
Remove a sync schedule (a per-folder one, or an account's, which stops its sync).
- Input:
account_id,folder? - Output:
removed
remove_workspace
Remove a workspace from config.toml. Refuses to remove 'default'. LLM cache and usage rows are kept; clear them separately.
- Input:
name - Output:
removed,name,path?,backup?,cache_kept?,error?
reprocess
Bring one pipeline stage up to date for old mail (parse, filter, embed, triage, enrich, action, scan or start).
- Input:
stage,account_id?,since?,limit?,route? - Output:
job_id,created
reset_usage
Clear the token-usage record (the figures the stats page shows). Model calls and the context savings both go; mail, the index and the enrichment cache are untouched. The accounting starts fresh from the next call.
- Input: none
- Output:
deleted
resume_backfill
Resume the model-bound ingest stages after a pause, or just one with stage.
- Input:
stage? - Output:
llm_paused,reason?,paused_stages?
resume_schedule
Resume a paused sync schedule: it is due now and its failure count is cleared.
- Input:
account_id,folder? - Output:
schedule
retry_job
Re-queue a failed or cancelled job to run now, clearing its last error.
- Input:
job_id - Output:
job_id,status
retry_parked
Re-queue one parked ingest job, or with all=true every parked ingest job, to run again.
- Input:
job_id?,all? - Output:
retried
revoke_agent
Revoke an agent at once; the jobs it holds go back to the queue.
- Input:
agent_id - Output:
revoked
savings_summary
Tokens saved, by caller: model calls the cache skipped, and mail text kept out of a client's context. Estimates.
- Input:
since_hours? - Output:
cache,context,totals,note?
search
Each hit says which retrievers found it (why). When the embedder or the vectors are unavailable the keyword results still come back, with degraded set. Never marks read.
- Input:
account_id?,label?,location?,from?,after?,before?,disposition?,unread_only?,starred?,has_attachment?,thread_key?,query,limit?,category?,min_priority?,offset?,sort? - Output:
items,truncated?,offset?,total?,total_exact?,content_is_untrusted?,warnings?,degraded?,degraded_reason?
search_keyword
Hits come back with the matching words marked **like this**. Never marks read.
- Input:
account_id?,label?,location?,from?,after?,before?,disposition?,unread_only?,starred?,has_attachment?,thread_key?,query,limit?,offset?,sort? - Output:
items,truncated?,offset?,total?,total_exact?,content_is_untrusted?,warnings?
set_account_config
Replace an account's non-secret settings (and, if given, its display name).
- Input:
account_id,config,display_name? - Output:
account,restart_needed
set_flagged
Star or unstar messages. Written back to the mailbox through \Flagged; undoable.
- Input:
ids,flagged? - Output:
changed,unchanged,missing,local_only,audit_ids,batch_id?,skipped?
set_labels
Add labels to messages (made if new) and remove labels the person added earlier.
- Input:
ids,add?,remove? - Output:
changed
set_operation_exposure
Choose whether MCP clients may call an operation, or all of a plugin's operations.
- Input:
scope,name,mcp - Output:
scope,before,after,operations
set_pipeline_limits
Change how many jobs of a stage run at once, now and after a restart. A running job is never dropped: a lower number takes effect as running jobs finish.
- Input:
stage,concurrency - Output:
stage,concurrency
set_plugin_config
Change one plugin's settings in its [plugins.KIND.NAME] table (or the older [plugins.NAME]) and leave the rest of config.toml, comments included, as it is. Keys are merged onto the saved ones (or replace them); text from an editor keeps the person's comments. Validated first; the previous file is backed up. Does not restart the plugin: call plugin_reload to apply.
- Input:
plugin,text?,config?,unset?,replace?,kind? - Output:
ok,path,backup?,error?
set_schedule
Create or change a sync schedule. The floor and the timezone are checked now.
- Input:
account_id,folder?,schedule,timezone?,quiet?,clear_quiet?,run_now? - Output:
schedule
set_settings
Change core's settings in one section of config.toml, keeping the file's comments and every other table. Validated first (the whole file), and the previous file is backed up. It does not reload core: apply it with config_reload (oaken reload). The result says which keys need a reload, a reindex or a restart.
- Input:
section,values?,unset? - Output:
ok,errors?,changed?,reload_needed?,reindex_needed?,restart_needed?,env_overridden?,warnings?,path?,backup?,error?
set_workspace
Create or update a workspace in config.toml, keeping all other tables and comments. The change takes effect immediately (live reload); no restart needed.
- Input:
name,toml? - Output:
ok,name,path?,backup?,error?,errors?
sieve_check
Compile a Sieve script and report the first error, with its line.
- Input:
script,name? - Output:
ok,error?,line?,requires?,sha256?
sieve_delete
Remove one Sieve script. It stops running on the next filter pass.
- Input:
name - Output:
deleted
sieve_get
Read one Sieve script's text, so an editor can load it.
- Input:
name - Output:
name,text,sha256
sieve_list
List the Sieve scripts on disk, and any skipped with the reason.
- Input: none
- Output:
enabled,directory,sha256,scripts,problems
sieve_save
Compile a Sieve script and, only if it compiles, save it so it runs on the next filter pass.
- Input:
name,text - Output:
saved,check,sha256?
sieve_test
Run a Sieve script on one message and show each effect and its rule. Stores nothing.
- Input:
script,name?,message_id?,eml_base64? - Output:
check,disposition?,rule?,effects?,errors?,steps?
status
A short health summary: accounts, messages, index, queue, plugins and paused schedules.
- Input: none
- Output:
version,accounts,messages,indexed,index_stale,queue_depth?,plugins_healthy?,plugins_total?,schedules_paused?,schedules_failing?,mcp_workspaces?
storage_info
Where Oaken keeps its data and how big it is: the two databases, their write-ahead logs and the quarantine folder. Read from the filesystem, not by scanning mail.
- Input: none
- Output:
data_dir,raw_db,raw_db_bytes,index_db,index_db_bytes,wal_bytes,quarantine_dir?,quarantined_files?,quarantine_bytes?
summarize_message
Summaries are cached by content and model, and made in the message's own workspace (a secure one never reaches a remote model). Mail text goes to the model only as UntrustedText. A message that cannot be summarized says why and does not stop the others. Read state changes only if mark_read is true, and only for the ones that got a summary.
- Input:
message_ids,mark_read? - Output:
items,marked_read?,content_is_untrusted?
sync_now
Sync an account (or one folder) now, or every account on every provider when none is named. Each is a job that calls the provider's pull; it joins a sync already queued or running.
- Input:
account_id?,folder? - Output:
job_id,created,jobs?,skipped?
trace_set
Turn the trace on or off now (oaken trace on|off). It holds mail text, so it is off until asked for; [log] trace = true is the start-up default. Not applied across a restart.
- Input:
enabled - Output:
enabled,file,content_is_untrusted?
trace_status
Whether the trace is on, and where its file is. The trace records what a model or an agent is told, thinks and returns, with the full text.
- Input: none
- Output:
enabled,file,content_is_untrusted?
trace_tail
The most recent trace events (oldest first), optionally for one plugin (plugin.KIND.NAME), one job or one message: prompts, responses, thinking, tool calls, timings and what was committed. Holds mail text.
- Input:
limit?,since?,kinds?,plugin?,job_id?,message_id? - Output:
events,enabled,content_is_untrusted?
triage_message
Run the triagers on one message now and store the verdict.
- Input:
message_id,force? - Output:
message_id,ran,cached,rated
try_triage
Run triage on one stored message, or on pasted text, and show the verdict without storing it: which triager decided (a header rule or a model), the category, priority and whether a reply is owed. For tuning: change a rule or the triage model, then try again.
- Input:
message_id?,text?,subject?,sender? - Output:
triager,rated,result?,model?,note?,stored?,content_is_untrusted?
undo
Undo a read-state change from the audit log, restoring exactly what each message was.
- Input:
audit_id - Output:
changed,unchanged,missing,local_only,audit_ids,batch_id?,skipped?
usage_summary
Model calls and tokens per workspace, stage and model, and what the cache saved.
- Input:
since_hours?,workspace? - Output:
rows
vacuum
Rewrite raw.db and index.db to give back the space deleted rows left. One at a time, and not while a rebuild runs. It holds each database's write lock while it works (ingest waits, reads go on) and needs about the database's own size free on the disk.
- Input: none
- Output:
job_id,created
Plugin operations
A plugin may offer more, named <plugin>.<name> (a provider's login, say). They are listed by list_operations at run time, are always off over MCP until the user turns them on, and are reachable from the CLI as oaken <plugin> <name> (or oaken operation <plugin>.<name>, with one flag per input field). A plugin declares one with the @command decorator in oaken.plugins.base.
Plugins installed with this version, and the functions each offers. A plugin you install yourself adds its own, which show up on your machine, not here.
| Plugin | Kind | Version | Functions |
|---|---|---|---|
attachment |
action | 1 | none yet |
clamav |
action | 1 | none yet |
ollama |
embedder | 0.2.0 | none yet |
actions |
enricher | 1 | none yet |
inspector |
enricher | 1 | none yet |
summary |
enricher | 1 | none yet |
ollama |
llm_backend | 0.2.0 | none yet |
ollama-remote |
llm_backend | 0.2.0 | none yet |
gmail |
provider | 1 | gmail.auth, gmail.auth_status, gmail.labels, gmail.send_as |
imap |
provider | 1 | imap.auth |
smtp |
provider | 1 | smtp.auth |
ai |
triager | 1 | ai.levels, ai.level_set, ai.level_remove |
rules |
triager | 1 | rules.levels, rules.level_set, rules.level_remove, rules.list, rules.add, rules.update, rules.remove, rules.order, rules.test, rules.apply, rules.discard, rules.page_new, rules.page_order |
spamcheck |
triager | 1 | spamcheck.levels, spamcheck.level_set, spamcheck.level_remove |
sqlite-vec |
vector_store | 1 | none yet |
gmail.auth
Sign in through the provider's consent page. Returns the address to open. Offered by the gmail provider plugin; permission mutate, MCP off.
- Input:
account_id?,check? - Output:
account_id,state,detail?,open_url?,poll?,poll_input?
gmail.auth_status
How a sign-in that is waiting for the person is going. Offered by the gmail provider plugin; permission read, MCP off.
- Input:
account_id?,check? - Output:
account_id,state,detail?
gmail.labels
List this account's Gmail labels (the names and ids include_labels and exclude_labels accept). Offered by the gmail provider plugin; permission read, MCP off.
- Input:
account_id? - Output:
labels
gmail.send_as
List the addresses this account may send as (its verified send-as aliases). Offered by the gmail provider plugin; permission read, MCP off.
- Input:
account_id? - Output:
addresses
imap.auth
Store this account's password in the OS keyring and check the login. Offered by the imap provider plugin; permission mutate, MCP off.
- Input:
account_id?,check?,password? - Output:
account_id,state,detail?,open_url?,poll?,poll_input?
smtp.auth
Store this account's password in the OS keyring and check the login. Offered by the smtp provider plugin; permission mutate, MCP off.
- Input:
account_id?,check?,password? - Output:
account_id,state,detail?,open_url?,poll?,poll_input?
ai.levels
List the triage levels: built in and the reader's own. Offered by the ai triager plugin; permission read, MCP off.
- Input: none
- Output:
levels
ai.level_set
Add a triage level (4 to 99), or rename one of yours. Offered by the ai triager plugin; permission mutate, MCP off.
- Input:
value,name - Output:
levels
ai.level_remove
Remove one of your triage levels. Offered by the ai triager plugin; permission mutate, MCP off.
- Input:
value - Output:
levels
rules.levels
List the triage levels: built in and the reader's own. Offered by the rules triager plugin; permission read, MCP off.
- Input: none
- Output:
levels
rules.level_set
Add a triage level (4 to 99), or rename one of yours. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
value,name - Output:
levels
rules.level_remove
Remove one of your triage levels. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
value - Output:
levels
rules.list
List the rules in the order they run (the staged copy, if there is one). Offered by the rules triager plugin; permission read, MCP off.
- Input: none
- Output:
rules,staged,note?
rules.add
Stage a new rule, last in order. Apply writes it to config.toml. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
from?,to?,subject?,subject_contains?,body_contains?,header_present?,has_attachment?,is_reply?,has_label?,name,level?,category?,route?,labels?,enabled? - Output:
rules,staged,note?
rules.update
Stage a change to one rule, found by name. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
from?,to?,subject?,subject_contains?,body_contains?,header_present?,has_attachment?,is_reply?,has_label?,name,level?,category?,enabled?,route?,labels? - Output:
rules,staged,note?
rules.remove
Stage the removal of one rule. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
name - Output:
rules,staged,note?
rules.order
Stage a new order: the rule names, first to last. Offered by the rules triager plugin; permission mutate, MCP off.
- Input:
order - Output:
rules,staged,note?
rules.test
Check a rule as typed, without staging it. Offered by the rules triager plugin; permission read, MCP off.
- Input:
from?,to?,subject?,subject_contains?,body_contains?,header_present?,has_attachment?,is_reply?,has_label?,name,level?,category?,route?,labels?,enabled? - Output:
ok,summary,notes?
rules.apply
Write the staged rules to config.toml (one backup) and reload this plugin. Offered by the rules triager plugin; permission mutate, MCP off.
- Input: none
- Output:
rules,staged,note?
rules.discard
Throw the staged rules away. Offered by the rules triager plugin; permission mutate, MCP off.
- Input: none
- Output:
rules,staged,note?
rules.page_new
The values for the new-rule page. Offered by the rules triager plugin; permission read, MCP off.
- Input: none
- Output:
values?,messages?,rows?
rules.page_order
The rules, for the order page. Offered by the rules triager plugin; permission read, MCP off.
- Input: none
- Output:
values?,messages?,rows?
spamcheck.levels
List the triage levels: built in and the reader's own. Offered by the spamcheck triager plugin; permission read, MCP off.
- Input: none
- Output:
levels
spamcheck.level_set
Add a triage level (4 to 99), or rename one of yours. Offered by the spamcheck triager plugin; permission mutate, MCP off.
- Input:
value,name - Output:
levels
spamcheck.level_remove
Remove one of your triage levels. Offered by the spamcheck triager plugin; permission mutate, MCP off.
- Input:
value - Output:
levels