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 |
|---|---|---|---|---|
ask |
read | off until you turn it on | no | Answer a question from the mail, citing the messages and quoting the lines it came from. |
authorization_status |
read | never | no | How an interactive authorization is going. |
cancel_job |
mutate | never | no | Cancel a queued job, or ask a running one to stop at its next safe point. |
check_account |
read | never | no | Check the account's credential: connect, require TLS and log in. Sends and reads nothing. |
create_account |
mutate | never | no | Add an account. Its credential is stored separately with set_account_password or start_authorization. |
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. |
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_enrichment |
read | on by default | no | Show the stored enrichment results (summary, triage, actions, inspector) for a message. |
get_message |
read | on by default | no | One message: cleaned text and metadata. 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_raw |
read | never | no | The raw headers of a message, and optionally its raw bytes, for inspection. Not for MCP. |
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. |
list_accounts |
read | on by default | no | The configured accounts: id, provider and display name (never credentials). |
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. |
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). Mail keeps landing and being filtered. |
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_health |
read | on by default | no | Whether plugins are started and healthy, and why not if they are not. |
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). |
reprocess |
mutate | never | no | Bring one pipeline stage up to date for old mail (parse, filter, embed or enrich). |
resume_backfill |
mutate | never | no | Resume the model-bound ingest stages after a pause. |
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_account_password |
mutate | never | no | Store an account's password in the OS keyring (SMTP and IMAP). It is never shown again. |
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_schedule |
mutate | never | no | Create or change a sync schedule. The floor and the timezone are checked now. |
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. |
start_authorization |
mutate | never | no | Begin an interactive consent (Gmail). Returns the address to open; poll authorization_status. |
status |
read | on by default | no | A short health summary: accounts, messages, index, queue, plugins and paused schedules. |
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. Joins a sync already queued or running. |
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. |
Inputs and outputs
A trailing ? marks an optional field.
ask
Every quote is checked against the message it cites; claims that fail are dropped, and with none left the answer is insufficient_evidence. Never marks anything read.
- Input:
account_id?,label?,location?,from?,after?,before?,disposition?,unread_only?,starred?,has_attachment?,thread_key?,question - Output:
answer,message_ids?,citations?,confidence?,insufficient_evidence?,dropped_claims?,degraded?,degraded_reason?,evidence_tokens?,full_body_tokens?,content_is_untrusted?,warnings?
authorization_status
How an interactive authorization is going.
- Input:
account_id - Output:
state,detail?
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_account
Check the account's credential: connect, require TLS and log in. Sends and reads nothing.
- Input:
account_id - Output:
ok,detail?
create_account
Add an account. Its credential is stored separately with set_account_password or start_authorization.
- 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
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_enrichment
Show the stored enrichment results (summary, triage, actions, inspector) for a message.
- 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?,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_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_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?
list_accounts
The configured accounts: id, provider and display name (never credentials).
- Input: none
- Output:
accounts
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? - Output:
entries
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?
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). Mail keeps landing and being filtered.
- Input:
why? - Output:
llm_paused,reason?
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: none
- Output:
stages,docs,chunks,index_stale,vector_model?,vectors,embedder_model?,embeddings_stale,backfill_paused,llm_paused?,quarantined_files,parked?
plugin_health
Whether plugins are started and healthy, and why not if they are not.
- Input:
name? - Output:
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
reprocess
Bring one pipeline stage up to date for old mail (parse, filter, embed or enrich).
- Input:
stage,account_id? - Output:
job_id,created
resume_backfill
Resume the model-bound ingest stages after a pause.
- Input: none
- Output:
llm_paused,reason?
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_account_password
Store an account's password in the OS keyring (SMTP and IMAP). It is never shown again.
- Input:
account_id,password - Output:
stored
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_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
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?
start_authorization
Begin an interactive consent (Gmail). Returns the address to open; poll authorization_status.
- Input:
account_id - Output:
url
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?
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. Joins a sync already queued or running.
- Input:
account_id,folder? - Output:
job_id,created
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
Plugin operations
A plugin may offer more, named <plugin>.<name>. They are listed by list_operations at run time, and are always off over MCP until the user turns them on.