Documentation ▼

missionctl Documentation

67 MCP tools across 9 terminal apps. Local-first, no cloud, no subscriptions.

Getting Started

Installation

Fastest way — install via Homebrew. All 8 tools are free, MIT-licensed, and tapped from one repo:

brew tap aeon022/tap https://github.com/aeon022/homebrew-tap
brew install aeon022/tap/calctl   # repeat for any of: mailctl taskctl notectl budgetctl diaryctl timectl habctl

Or clone and build from source. Every repo has a setup.sh that compiles the binary and installs it to ~/.local/bin/:

for repo in mailctl calctl taskctl notectl budgetctl diaryctl timectl habctl; do
  git clone https://github.com/aeon022/$repo
  cd $repo && ./setup.sh && cd ..
done

Make sure ~/.local/bin is on your $PATH:

export PATH="$HOME/.local/bin:$PATH"
# add to ~/.zshrc or ~/.bashrc

Initial Sync

After installing, run the initial sync for each tool to populate the local SQLite cache:

mailctl sync      # Apple Mail → local cache
calctl sync       # Apple Calendar → local cache
taskctl sync      # Apple Reminders → local cache
notectl sync      # Obsidian, Apple Notes, or Joplin → local index

budgetctl is import-driven — there's no background sync:

budgetctl import bank.csv --account checking

Claude Desktop Config

Add all 9 tools to Claude Desktop in one config block. Edit~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "mailctl":   { "command": "mailctl",   "args": ["mcp"] },
    "calctl":    { "command": "calctl",    "args": ["mcp"] },
    "taskctl":   { "command": "taskctl",   "args": ["mcp"] },
    "notectl":   { "command": "notectl",   "args": ["mcp"] },
    "budgetctl": { "command": "budgetctl", "args": ["mcp"] },
    "diaryctl":  { "command": "diaryctl",  "args": ["mcp"] },
    "timectl":   { "command": "timectl",   "args": ["mcp"] },
    "habctl":    { "command": "habctl",    "args": ["mcp"] },
    "postctl":   { "command": "postctl",   "args": ["mcp"] }
  }
}

Restart Claude Desktop. All 67 MCP tools appear automatically in every conversation.

Colour themes

Press T in any app (in timectl C, because T is the task picker) or type :theme to open the theme picker — move with ↑/↓ and the whole screen previews each palette live, enter keeps it (saved to ~/.config/missionctl/theme.yaml), esc cancels, so every app and the dashboard start in the same colours. Built in: terminal (your terminal's own colours), catppuccin, classic, dracula, gruvbox, nord, one-dark, solarized and tokyo-night. habctl and budgetctl also list the theme in their Settings screens; notectl in Settings with ctrl+t. Single colours can be overridden in the same file.

An empty app greets you with a short Welcome checklist (what to press first) instead of a blank screen.

Sync Across Devices

By default, each tool keeps its SQLite database in a private directory (~/.local/share/<tool>/ — ~/Library/Application Support/<tool>/ on some tools). That's fine for a single machine. To use the same data on a laptop and a desktop, point a tool's database at a folder you already sync yourself — iCloud Drive, Dropbox, Syncthing — via the data_dir config key or a <TOOL>_DATA_DIR environment variable. All 8 dev tools (not postctl, which has its own per-profile setup) support this the same way.

Set it via config file

# ~/.config/budgetctl/budgetctl.yaml
data_dir: ~/Library/Mobile Documents/com~apple~CloudDocs/missionctl/budgetctl

Or via environment variable

export BUDGETCTL_DATA_DIR="$HOME/Library/Mobile Documents/com~apple~CloudDocs/missionctl/budgetctl"
export NOTECTL_DATA_DIR="$HOME/Dropbox/missionctl/notectl"

budgetctl also has a TUI settings screen for this — press o and set the sync folder without touching a config file by hand.

What actually makes this safe

Pointing a SQLite file at a synced folder isn't automatically safe — three specific things can go wrong, and missionctl-core/syncdir (used by every tool) exists to close them:

  • WAL journal mode splits state across up to 3 files (.db, .db-wal, .db-shm). A sync client uploads whichever one changed, whenever — with no guarantee the three land together. As soon as a tool is pointed at a user-configured directory, it switches to classic rollback-journal mode instead: one main file, plus a transient -journal sidecar that only exists mid-write and is gone the instant a transaction commits. The private default directory stays on WAL, untouched.
  • Two processes on the same machine (two terminal tabs, a crashed session that never let go) must not write at once. An advisory file lock (flock) enforces that — and releases itself automatically the moment the holding process exits, however it exits, so a crash can't leave the database stuck "locked" forever.
  • macOS can evict an iCloud Drive file to save local disk space ("Optimize Mac Storage"), replacing it with a zero-byte placeholder. Tools detect this and re-download the real file before touching it, instead of silently opening an empty database.

Licensing (Bundle features)

All 9 tools are free and MIT licensed. A small number of features that cost real compute (AI calls) or add real complexity are part of the missionctl Bundle instead of the free core — everything else stays free forever:

  • budgetctl: AI transaction categorization (--ai) and recurring-payment detection (budgetctl recurring).
  • notectl: more than one named vault (notectl vault add) — the free tier includes one.
  • mailctl: AI draft reply (the a key in the detail view).
  • calctl: AI meeting summaries (calctl summarize).
  • habctl: AI habit suggestions (habctl suggest, the s key) and the AI weekly review (habctl review, the r key).

All five use the same real Polar.sh license-key check postctl's Pro license already uses — no phone-home telemetry, just a one-time (or offline-cached) validation against your key:

budgetctl license activate <key>   # after buying the Bundle
notectl license activate <key>
mailctl license activate <key>
calctl license activate <key>
habctl license activate <key>

budgetctl license status           # ...and the same "status" subcommand for each

Without a license, gated commands print a short message pointing at the Bundle and — where it makes sense, like --ai import — fall back to the free behavior instead of failing outright.

Choosing an AI provider

Once a feature is unlocked, it still needs an LLM to actually call — and that doesn't have to mean a paid Anthropic key. mailctl, calctl, budgetctl, habctl, and diaryctl (whose AI diary generation is free, not Bundle-gated) all auto-detect whichever of these is configured, in this order — full walkthrough with model recommendations in Local AI with Ollama below:

  • ANTHROPIC_API_KEY — Claude, paid.
  • OPENAI_API_KEY — GPT-4o mini, paid.
  • GEMINI_API_KEY — free tier, no card required. Get one at aistudio.google.com/apikey in about 30 seconds.
  • A local Ollama model — no key, no signup, nothing leaves your machine. The always-available fallback if nothing else is set.

Override auto-detection with <TOOL>_PROVIDER=anthropic|openai|gemini|ollama (e.g. MAILCTL_PROVIDER=ollama). What's deliberately not supported: reusing a claude.ai or chatgpt.com browser session in place of an API key — both providers' terms of service prohibit programmatic reuse of a consumer web session, and it risks flagging your own account. Free-tier Gemini or local Ollama cover the "I don't want to pay or sign up for an API key" case without that risk.

Local AI with Ollama

Every AI-gated feature in the suite (plus diaryctl's free AI diary generation) already falls back to a local Ollama model automatically — no API key, no signup, no per-request cost, nothing leaves your machine. This is a full walkthrough: installing Ollama, picking the right model per tool, and the environment variables that control it.

1. Install Ollama

# macOS
brew install ollama
ollama serve                    # or just launch the Ollama.app — runs a background server on :11434

# Linux
curl -fsSL https://ollama.com/install.sh | sh

2. Pull a model and test it

ollama pull llama3.2
ollama run llama3.2 "Say hi in five words"

3. That's it — try a gated feature

Nothing else to configure. Provider auto-detection already tries Ollama last, with zero setup, once you've licensed the feature:

calctl summarize --event-title "Standup"

Choosing a model

Bigger isn't always better — it's a size-vs-quality-vs-RAM tradeoff. Rough guide (all sizes are approximate 4-bit-quantized RAM, what Ollama pulls by default):

ModelPull command~RAMBest for
llama3.2 (3B)ollama pull llama3.2~2 GBDefault fallback. Fast, fine for short/low-stakes text — habit suggestions, quick summaries.
mistral (7B)ollama pull mistral~4–5 GBSolid general-purpose writing — noticeably better tone than llama3.2 for email-style text.
mistral-nemo (12B)ollama pull mistral-nemo~7–8 GBBest quality-per-GB for longer synthesis — weekly reviews, meeting summaries, draft replies. 128k context.
qwen2.5 (14B)ollama pull qwen2.5:14b~9 GBVery reliable structured/JSON output — the safest pick for budgetctl's transaction categorization.
qwen2.5-coder (14B)ollama pull qwen2.5-coder~9 GBReads code/diffs accurately while still writing reasonable prose — good middle ground for diaryctl.
codestral (22B)ollama pull codestral~13 GBPurpose-built for code generation, not narrative prose — most technically literal read of a git diff, least "personal" voice. See the diaryctl note below.

Which model for which tool

Tool / featureTask typeRecommendedSet with
calctl summarizeStructured meeting summarymistral-nemoCALCTL_OLLAMA_MODEL
mailctl draft reply (a)Tone-sensitive writingmistral-nemoMAILCTL_OLLAMA_MODEL
budgetctl --ai importClassification, strict JSONqwen2.5:14bBUDGETCTL_OLLAMA_MODEL
habctl suggest (s)Short, low-stakes suggestionsllama3.2 (default is fine)—
habctl review / goal (r / g)Longer synthesis, structured reasoningmistral-nemo or qwen2.5:14bHABCTL_OLLAMA_MODEL
diaryctl narrativeReads git diffs, writes personal proseqwen2.5-coder or mistral-nemoDIARYCTL_OLLAMA_MODEL

habctl's one caveat: the override applies per tool, not per feature — HABCTL_OLLAMA_MODEL affects suggest, review, and goal alike. If you want suggest on the fast default while review uses a bigger model, override it inline for just that one call instead of exporting it permanently: HABCTL_OLLAMA_MODEL=mistral-nemo habctl review.

mistral vs. codestral for diaryctl, specifically: Codestral is trained to generate code, not write prose about code — expect a technically accurate but fairly dry read of what a diff actually did, with less of a "personal reflection" voice. General models (mistral-nemo, qwen2.5) write noticeably warmer, more narrative diary entries but occasionally miss a subtlety in what the code changed. If your diary should read like something you'd actually want to re-read in a year, start with mistral-nemo; switch to qwen2.5-coder (a middle ground — code-aware but still writes reasonable prose) only if entries keep missing what your commits actually did. Pure codestral is worth trying if you mainly want an accurate technical changelog rather than a diary in the literary sense.

Configuration reference

  • OLLAMA_HOST — default http://localhost:11434. Override if Ollama runs elsewhere (another machine on your LAN, a custom port).
  • OLLAMA_MODEL — shared default model across every tool, if no per-tool override is set. Falls back to llama3.2 if unset.
  • <TOOL>_OLLAMA_MODEL — per-tool override, wins over the shared OLLAMA_MODEL (e.g. DIARYCTL_OLLAMA_MODEL=qwen2.5-coder, MAILCTL_OLLAMA_MODEL=mistral-nemo).
  • <TOOL>_PROVIDER=ollama — forces that one tool onto Ollama even if an API key is also set (e.g. keep paying for Claude in mailctl but stay free in budgetctl).

Full precedence: <TOOL>_PROVIDER (if set) picks the provider outright. Otherwise auto-detect checks, in order: ANTHROPIC_API_KEY → OPENAI_API_KEY → GEMINI_API_KEY → Ollama (always available, no key needed — the guaranteed fallback). Once on Ollama, the model is <TOOL>_OLLAMA_MODEL → OLLAMA_MODEL → llama3.2.

Example ~/.zshrc to pin different models per tool permanently:

export MAILCTL_OLLAMA_MODEL=mistral-nemo
export DIARYCTL_OLLAMA_MODEL=qwen2.5-coder
export BUDGETCTL_OLLAMA_MODEL=qwen2.5:14b
export CALCTL_OLLAMA_MODEL=mistral-nemo
# habctl and everything else not listed here stays on the OLLAMA_MODEL default / llama3.2

Performance notes

  • Apple Silicon: unified memory means a model's RAM footprint competes directly with everything else running. A 16 GB Mac comfortably handles up to ~9–10 GB models (mistral-nemo, qwen2.5:14b); on 8 GB, stick to llama3.2 or plain mistral (7B).
  • The first call after ollama serve starts (or after switching to a different model) is slow — Ollama has to load the model into memory. Subsequent calls are fast as long as the model stays warm (Ollama keeps recently-used models loaded for a few minutes by default).
  • Every AI call in the suite streams token-by-token, so even a slower model shows visible progress instead of a long silent wait — see the live word-count in mailctl's compose view or diaryctl's editor.

Troubleshooting

  • "connection refused — is Ollama running?" — ollama serve isn't running. Launch the Ollama.app, or run ollama serve in a terminal.
  • "404 — model not found" — the model named in OLLAMA_MODEL/<TOOL>_OLLAMA_MODEL hasn't been pulled yet: ollama pull <name>.
  • Slow or low-quality output — try a larger model if your RAM allows, or confirm what's actually loaded with ollama ps.
  • Not sure which provider a tool picked? Gated commands print it in their output, and habctl's Settings screen (S key) shows the active provider directly.

Tutorial: First 10 Minutes

A concrete walkthrough for someone setting up missionctl for the first time — using calctl and taskctl as the example, but the pattern is the same for every tool.

1. Install two tools to try

brew tap aeon022/tap https://github.com/aeon022/homebrew-tap
brew install aeon022/tap/calctl
brew install aeon022/tap/taskctl

2. Run the initial sync

This reads from Apple Calendar / Apple Reminders into each tool's local SQLite cache. Nothing leaves your machine.

calctl sync
taskctl sync

3. Try the TUI

calctl        # opens the week view
taskctl       # opens the task list

Press : in either one and type a few letters — the command palette live-filters every available action, so you don't need to memorize keybindings up front.

4. Connect Claude Desktop

Add both to claude_desktop_config.json (see Claude Desktop config above), then restart Claude Desktop.

{
  "mcpServers": {
    "calctl":  { "command": "calctl",  "args": ["mcp"] },
    "taskctl": { "command": "taskctl", "args": ["mcp"] }
  }
}

5. Ask Claude something that spans both

Try: "What's on my calendar tomorrow, and do I have any overdue tasks?" Claude calls calctl's list_events and taskctl's today_tasks automatically — no explicit tool selection needed, it reads the descriptions and picks the right ones.

6. Next steps

mailctl

Terminal email client with TUI inbox, full-text search, compose, and 6 MCP tools. Syncs your inbox into a local SQLite database — all reads happen locally. Apple Mail on macOS, Thunderbird on Linux (new, currently in testing — see below).

Install

git clone https://github.com/aeon022/mailctl
cd mailctl && ./setup.sh

Sync

mailctl sync          # sync inbox
mailctl sync --all    # sync all folders

Linux (beta)

On Linux, mailctl reads mail directly from your default Thunderbird profile's local mbox files, and sends via that account's own SMTP server. Newly added and currently being tested on real hardware — feedback and bug reports welcome.

  1. Install and run Thunderbird at least once, with at least one IMAP account configured.
  2. Store the account's SMTP app password (needed for sending, not for reading/syncing):
    mailctl account set-password you@example.com
  3. mailctl sync, mailctl, etc. work the same as on macOS.

Current limitations: mbox mailbox format only (not Maildir), inbox only (no other folders), STARTTLS + password auth only (no implicit TLS on port 465, no OAuth2), no attachments on send, and no draft-saving or delete/mark-unread from mailctl — those would require writing into a Thunderbird mbox file it may have open, which mailctl avoids.

CLI commands

mailctl inbox                    # open TUI inbox
mailctl inbox --json             # JSON output
mailctl search "from:alice"      # search emails
mailctl send --to bob@x.com      # compose & send
mailctl draft --subject "Hello"  # save to Drafts
mailctl thread --subject "Re:"   # view thread
mailctl accounts                 # list accounts
mailctl license activate <key>   # activate missionctl Bundle
mailctl license status           # check license status
mailctl mcp                      # start MCP server

AI draft reply (the a key below) requires the missionctl Bundle — everything else here is free.

TUI keybindings

j / k Navigate up/downg / G Jump to top / bottom1-9 Jump to nth visible emailEnter Open selected emailTab / Shift+Tab Switch accountn Compose new emailr Reply (opens compose with quoted text)a AI draft reply (missionctl Bundle)U Open unsubscribe link (detail view)o Open in Mail.appd Delete (press again to confirm)y Copy subject + senderv Select mode — space toggles, A selects all, r marks read, d deletes selectedu Toggle unread-only filters Sync inbox/ Search: Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

inboxsearch_emailemail_threadsend_emaildraft_emailsync_inbox

calctl

Apple Calendar bridge. Browse events, create events, find free slots. Requires macOS — talks to Apple Calendar via AppleScript and EventKit.

Install

git clone https://github.com/aeon022/calctl
cd calctl && ./setup.sh

Sync

calctl sync           # sync next 30 days
calctl sync --days 90 # sync 90 days

CLI commands

calctl list                         # list upcoming events
calctl list --from 2026-07-01       # events from date
calctl add "Team sync" --time 14:00 # create event
calctl free --from today --to +7d   # find free slots
calctl export --week -o week.json   # write a range's events to a file
calctl sync                         # sync calendar
calctl summarize --event-title "Standup"   # AI meeting summary — missionctl Bundle
calctl license activate <key>       # activate missionctl Bundle
calctl license status               # check license status
calctl mcp                          # start MCP server

AI meeting summaries (calctl summarize) require the missionctl Bundle — everything else here is free.

TUI keybindings

j / k Navigate eventsh / l Previous / next week+ / - Show more / fewer days1-9 Jump to nth visible eventEnter Open event detailn Create new evente Edit eventd Delete event (asks Y/N to confirm)u Undo last deletey Copy event titlef Free slotsc Set default calendars Sync calendar/ Filter events: Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

list_eventstodaythis_weekfind_free_slotscreate_eventdelete_eventsync

taskctl

Apple Reminders bridge with TUI task manager, built-in Pomodoro timer, background sync daemon, and batch operations.

Install

git clone https://github.com/aeon022/taskctl
cd taskctl && ./setup.sh

Sync

taskctl sync           # sync Apple Reminders
taskctl daemon         # start background sync daemon

CLI commands

taskctl list                         # list all tasks
taskctl today                        # today's tasks
taskctl week                         # this week's tasks
taskctl add "Review PR" --due today  # create task
taskctl done <id>                    # mark complete
taskctl review                       # AI reviews this week, suggests follow-ups (approve each)
taskctl lists                        # list reminder lists
taskctl daemon                       # background daemon
taskctl mcp                          # start MCP server

TUI keybindings

j / k Navigate tasks1-9 Jump to nth visible taskSpace Toggle task completeEnter Task details — a/space/x add, toggle, remove a subtaskn New taske Edit taskd Delete task (asks to confirm)o Open task URLS Postpone to tomorrowy Copy titleu Undo last actionv Select mode — space toggles, A selects all, enter completes, d deletes selectedp Pomodoro timert Focus mode (today & overdue)O Filter: overdue onlyc Show / hide completedi Statss Sync/ Search: Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

today_tasksweek_taskslist_taskssynccreate_taskcomplete_taskdelete_task

notectl

Notes bridge for Obsidian, Apple Notes, or Joplin. Sync notes to local SQLite, read/write notes, search, and manage daily notes — sync one source or several at once. Works on macOS and Linux.

Install

git clone https://github.com/aeon022/notectl
cd notectl && ./setup.sh

Config

Edit ~/.config/notectl/notectl.yaml:

vault_path: ~/Documents/Obsidian/MyVault
source: obsidian   # obsidian | apple | markdown | joplin

For Joplin: enable Options → Web Clipper in Joplin, then set joplin_token to the token shown there.

source: joplin
joplin_token: <token from Joplin's Web Clipper settings>

Sync several sources into one combined cache with sync_sources (write target stays whatever source is):

sync_sources: apple,joplin

Sync

notectl sync      # index configured source(s) into SQLite cache

CLI commands

notectl list                    # list notes
notectl list --tag work         # notes tagged "work"
notectl list --event <id>       # notes linked to a calctl event
notectl read "Note title"       # read a note
notectl write "New note"        # create/update note
notectl write "Meeting" --event-id <id>  # link a note to a calctl event
notectl search "keyword"        # full-text search
notectl search "keyword" --tag work      # search within a tag
notectl daily                   # open today's daily note
notectl license activate <key>  # activate missionctl Bundle
notectl license status          # check license status
notectl mcp                     # start MCP server

Multiple vaults

The free tier includes one vault. Registering a second requires the missionctl Bundle — see Licensing.

notectl vault add work ~/Documents/Obsidian/Work
notectl vault add personal ~/Documents/Obsidian/Personal  # missionctl Bundle
notectl vault list                                        # * marks the active vault
notectl vault use work                                     # switch active vault

TUI keybindings

j / k Navigate notesg / G Jump to top / bottom1-9 Jump to nth visible noteEnter Open noteSpace Toggle checkbox on current line (detail view, writes back to Apple Notes)n New notee Edit noted Delete note (asks to confirm)u Undo last deleteo Open in external appy Copy titleS Toggle sort (date / title)t Browse tagsL Link graph ([[wiki-links]])p Settings (vault path, source)s Sync vault/ SearchTab / Shift+Tab Browse folders< / > Resize the two-pane split: Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

list_notesread_notewrite_notesearch_notessync_notesget_daily_noteappend_daily_notedelete_note

budgetctl

Personal finance tool. Import bank CSVs, categorize transactions with rules, set budget goals, and detect recurring payments. Works on macOS and Linux.

Install

git clone https://github.com/aeon022/budgetctl
cd budgetctl && ./setup.sh

Import

budgetctl import bank.csv --account checking
budgetctl import n26.csv --format n26
budgetctl import bank.csv --ai       # AI categorization — missionctl Bundle
# Supported: N26, ING, DKB, Sparkasse/George, Austrian bank Umsatzliste, Generic CSV
# File encoding is auto-detected (UTF-8, UTF-16 LE/BE, Windows-1252)

CLI commands

budgetctl list                      # list transactions
budgetctl list --month 2026-07      # filter by month
budgetctl summary                   # income/expense summary
budgetctl summary --month 2026-07   # monthly summary
budgetctl tag "Netflix" --category subscriptions
budgetctl apply-rules               # re-apply all rules
budgetctl goal set --category food --limit 400
budgetctl goal list                 # show goals + progress
budgetctl goal delete --category food
budgetctl recurring                 # detect recurring payments — missionctl Bundle
budgetctl suggest-cuts              # AI suggests budget cuts, approve each — missionctl Bundle
budgetctl export --format csv       # export data
budgetctl export --summary --year 2026   # year-end category totals (tax report)
budgetctl license activate <key>    # activate missionctl Bundle
budgetctl license status            # check license status
budgetctl mcp                       # start MCP server

See Licensing above — everything except --ai, recurring, and suggest-cuts is free.

Profiles

Keep contexts fully separate — e.g. a business ("firma") account and your personal accounts — each in its own database, so transactions, categories, and budget goals never mix. Unlike the data_dir sync setting above, which just relocates one shared database, each profile is an entirely independent one:

budgetctl profile add firma [--data-dir DIR]   # create; --data-dir optional (e.g. to sync it too)
budgetctl profile use firma                    # everything (CLI, TUI, MCP) now scopes to firma
budgetctl profile list                         # show all profiles, mark the active one
budgetctl profile use default                  # back to the unscoped default database
budgetctl profile set-data-dir firma DIR       # sync an already-created profile; "" moves it back to local
budgetctl profile remove firma                 # forgets the profile — its database stays on disk

set-data-dir refuses a folder already used by another profile or the unscoped default — profiles exist to keep data apart, so give each synced one its own folder.

With no active profile, budgetctl behaves exactly as before. In the TUI, press p to switch, create, or remove profiles the same way.

For a one-off command without switching your saved active profile, pass --profile (or -p) instead:

budgetctl import statement.csv --profile firma --account checking
budgetctl --profile firma summary

TUI keybindings

j / k Navigate transactionsg / G Jump to top / bottom1-9 Jump to nth visible transactionTab / Shift+Tab Next / previous monthy / Y Next / previous year[ / ] Cycle accountsEnter View full detailsn New entry (manual)i Import CSVe Edit selected entryd Delete entry (asks to confirm)u Undo last deletec Set categoryv Select mode — space toggles, A selects all (batch categorize)f Filter by category/ Search transactionss / S Summary (categories, charts, goals)o Settings (sync across devices)p Profiles (switch/create/remove isolated data contexts): Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

list_transactionsadd_transactiondelete_transactionbudget_summaryimport_transactionstag_transactionsapply_category_ruleslist_budget_goalsset_budget_goaldelete_budget_goaldetect_recurring_payments

habctl

Terminal-first habit tracker. Track daily habits with streaks, an AI weekly coaching review, habit chains, and streak-at-risk alerts — all stored locally in SQLite.

Install

git clone https://github.com/aeon022/habctl
cd habctl && ./setup.sh

CLI commands

habctl add "Meditate" --desc "10 minutes every morning"  # add a habit
habctl check Meditate                # check in for today
habctl today                         # today's habit status
habctl list                          # list habits with streaks
habctl stats                         # streaks + progress bars
habctl review                        # AI weekly coaching review — missionctl Bundle
habctl suggest --goal "more focus"   # AI habit suggestions — missionctl Bundle
habctl remind                        # macOS notification for unchecked habits
habctl license activate <key>        # activate missionctl Bundle
habctl license status                # check license status
habctl mcp                           # start MCP server

AI suggestions and the AI weekly review require the missionctl Bundle — everything else here is free.

TUI keybindings

j / k Navigate habits1-9 Jump to nth visible habitspace Check in / undo check-inn New habitp Add habit from curated preset liste Edit habitE Quick-edit habit descriptiond Delete habita Archive habit (history preserved)A Browse archived habits (restore / delete)V Batch-select mode — space toggles, A selects all, enter archivesm Move habit to a groupG Manage groupsc Manage habit chainsN Add/edit note on today's check-iny Copy habit names AI suggestions (missionctl Bundle)r AI weekly review (missionctl Bundle)g AI goal → decompose into linked habits (missionctl Bundle)t Stats — heatmap & completionw Toggle 7-day / 30-day windowv Toggle compact / normal viewS Settings — AI provider & API keys/ Filter habits: Command paletteT Colour theme picker (live preview, saved for the whole suite)? Helpq Quit

MCP tools

list_habitscheck_habituncheck_habitadd_habitdelete_habitget_habit_statsstreak_at_riskget_weekly_summaryget_weekly_reviewsuggest_habitsadd_checkin_notelist_chains

postctl

Social media scheduling for Instagram, Facebook, Threads, X, LinkedIn, Bluesky, Mastodon, Telegram, and Discord. Manage posts, campaigns, and drafts from your terminal — with separate profiles per account, a calendar view, and a per-profile scheduler service. Available at postctl.sh.

Install

git clone https://github.com/aeon022/postctl
cd postctl && ./setup.sh

CLI commands

postctl list                         # list posts
postctl post "Hello world"           # create post
postctl post --schedule "2026-07-05 09:00" "Hello"
postctl publish <id>                 # publish post immediately
postctl cancel <id>                  # cancel scheduled post
postctl delete <id>                  # delete post locally & remotely
postctl daemon                       # start scheduler daemon
postctl campaign list                # list campaigns
postctl import posts.csv             # import posts
postctl mcp                          # start MCP server

TUI keybindings

j / k Navigate posts/historyTab / Shift+Tab Switch tab (Dashboard/Posts/Schedule/History/Analytics/Settings/Logs)Enter Open detail view / apply filter / activate settings rowSpace Select / deselect post for bulk actionsp Publish selected post(s) immediatelys Schedule post to next queue slote Edit post contentn Create new postd Delete post locally and remotelyr Repurpose post content via AIi Import postsf Filter by campaignx Export history? Toggle quick-help footerR / F1 Open README documentationq Quit

Safety & Spam Protection

To avoid rate limits and account bans, postctl includes built-in safeguards:

  • Queue spacing: Scheduled queue slots are spaced out automatically.
  • Overdue protection: If multiple scheduled posts become overdue (e.g., system was offline), only the oldest is posted immediately. The subsequent posts are automatically rescheduled in 20-minute intervals.
  • Safe remote deletion: Deleting a post locally automatically issues API delete calls to the remote platforms to keep feeds in sync.
  • X minimum gap: At least 60 minutes must pass between two published X posts; a post that comes due earlier waits for a later check.

MCP tools

list_postsget_postcreate_postpublish_postschedule_postlist_campaignsget_campaign

diaryctl

Developer diary from your terminal. Reads git history, completed tasks (taskctl), calendar events (calctl), and time logs (timectl) to generate AI narrative diary entries.

Install

git clone https://github.com/aeon022/diaryctl
cd diaryctl && ./setup.sh

Setup

diaryctl init ~/code/myproject --name "My Project"
diaryctl repos   # list registered repos

CLI commands

diaryctl today               # generate today's entry
diaryctl today --open        # open in $EDITOR
diaryctl list                # list all entries
diaryctl show 2026-07-04     # show a specific entry
diaryctl stats --days 30     # coding stats for last 30 days
diaryctl tui                 # open TUI (heatmap + list)
diaryctl mcp                 # start MCP server

TUI keybindings

j/k     navigate entries
1-9     jump to nth visible entry
enter   open entry
n       generate today's entry
e       edit entry
d       delete entry (asks to confirm)
y       copy title
u       undo last delete
g       open corresponding note in notectl
r       browse tracked git repos
/       search entries
:       command palette
?       help
q       quit

While editing an entry:

a         stream an AI-generated continuation into the entry
ctrl+s    save
ctrl+f    toggle centered writing mode
ctrl+v    enter vim-normal mode
tab / [ / ]  jump to next / previous AI marker or "##" section

MCP tools

get_today_statsget_diary_entrywrite_diary_entryget_coding_statslist_diary_entries

timectl

Time tracking from your terminal. Start and stop timers, view a weekly bar chart, and integrate time logs into diaryctl diary entries.

Install

git clone https://github.com/aeon022/timectl
cd timectl && ./setup.sh

CLI commands

timectl start "Fix auth bug" --project myapp
timectl stop
timectl status               # check running timer
timectl today                # time log for today
timectl week                 # weekly bar chart
timectl log --days 7         # last 7 days log
timectl tui                  # open TUI
timectl mcp                  # start MCP server

TUI keybindings

n       start new timer (task@project)
T       start timer from an open taskctl task
s       stop running timer
r       restart selected entry's task
c       copy selected entry into new-task input
j/k     navigate log
1-9     jump to nth visible entry
e       edit notes
d       delete entry (asks to confirm)
u       undo last delete
y       copy task name
g       open linked taskctl task
←/→/t   browse previous/next day, back to today
w       week view
v       stats view
/       filter by task, project, notes
:       command palette
?       help
q       quit

MCP tools

start_timerstop_timerget_time_logget_time_stats

MCP Reference

Safety by default: an AI agent that reads untrusted text can be tricked, so send_email only saves a draft unless you set MAILCTL_MCP_ALLOW_SEND=1 in the MCP server's environment, postctl's publish/schedule tools need POSTCTL_MCP_ALLOW_PUBLISH=1, and every delete_* tool requires confirm=true (the model must ask you first).

All 67 tools grouped by app. Each tool is callable from Claude Desktop once the config is in place.

mailctl

inboxList recent inbox messages with sender, subject, preview
search_emailSearch by keyword across subject, sender, body
email_threadGet all messages in a thread matched by subject
send_emailSend an email via Apple Mail (opt-in: MAILCTL_MCP_ALLOW_SEND=1, otherwise saves a draft)
draft_emailSave a composed message to Apple Mail Drafts
sync_inboxSync from Apple Mail into local cache

calctl

list_eventsList events between two dates
todayToday's events
this_weekThis week's events (Monday to Sunday)
find_free_slotsFind free time within working hours
create_eventCreate a calendar event
delete_eventDelete an event by title and date
syncSync from Apple Calendar into local cache

taskctl

today_tasksTasks due today or overdue
week_tasksTasks due this week
list_tasksList tasks, filter by list or status
syncSync from Apple Reminders
create_taskCreate task with title, list, due date, notes
complete_taskMark a task completed
delete_taskDelete a task

notectl

list_notesList notes from cache (filter: folder, source)
read_noteRead full note content by title
write_noteCreate or update a note in the vault
search_notesKeyword search across title and content
sync_notesSync Obsidian vault into cache
get_daily_noteGet today's daily note (creates from template if missing)
append_daily_noteAppend content under a named section
delete_noteDelete a note by title (folder disambiguates duplicates)

budgetctl

list_transactionsList transactions, filter by month/category/query
add_transactionAdd a manual income or expense entry
delete_transactionDelete a transaction by its ID
budget_summaryMonthly income/expenses/net with category breakdown
import_transactionsImport from a bank CSV file
tag_transactionsCreate a category rule (pattern → category)
apply_category_rulesRe-apply all rules to all transactions
list_budget_goalsGoals with current-month spending progress
set_budget_goalSet a monthly spending limit for a category
delete_budget_goalRemove a goal
detect_recurring_paymentsDetect subscriptions and recurring charges

diaryctl

get_today_statsGit commits, files changed, suite data (tasks, events, time tracked) for today
get_diary_entryRead a diary entry by date (default: today)
write_diary_entrySave or overwrite a diary entry — used by Claude to fill in the narrative
get_coding_statsAggregate stats for last N days: streak, commits, most active day, repo breakdown
list_diary_entriesList recent entries with date and preview

timectl

start_timerStart a timer with task name and optional project tag
stop_timerStop the running timer, returns task name and duration
get_time_logTime entries for a date or date range with total duration
get_time_statsBreakdown by task/project, daily average, streak for last N days

habctl

list_habitsList all habits with current streak and today's status
check_habitCheck in for a habit today (or a specific date)
uncheck_habitUndo a check-in — correct an accidental entry
add_habitAdd a new habit to track
delete_habitDelete a habit and all its check-in history
get_habit_statsStreak, longest streak, and 30-day completion rate
streak_at_riskList active streaks not yet checked in today
get_weekly_summaryHabit completion summary for the last 7 days
get_weekly_reviewPer-habit 7/30-day data for an AI coaching briefing
suggest_habitsAI-suggested new habits based on goals
add_checkin_noteAdd a text note on a habit's check-in
list_chainsList habit chains — finish one, get nudged to the next

postctl

list_postsList posts, filter by platform/status/campaign
get_postGet a single post by ID with full content
create_postCreate a draft or scheduled post
publish_postPublish a post immediately
schedule_postUpdate a post's scheduled time
list_campaignsList campaigns with post counts and status breakdown
get_campaignGet all posts in a campaign with full content

AI Workflows

Once all tools are connected, Claude can orchestrate them together. A single prompt can span multiple apps and execute a dozen tool calls automatically.

Morning briefing

Ask Claude: "Give me my morning briefing". Claude callsinbox, today_tasks, and todayto pull email summaries, overdue tasks, and today's events — then synthesizes them into a prioritized briefing.

Weekly planning

Ask Claude: "Help me plan my week". Claude usesthis_week, week_tasks, find_free_slots, and get_daily_note to review your schedule and draft a plan in your Obsidian daily note.

Monthly finance review

Ask Claude: "Review my finances for June". Claude callsbudget_summary, list_transactions, anddetect_recurring_payments, then useswrite_note to save the analysis to your vault.

Email to task

Ask Claude: "Turn important emails from this week into tasks". Claude searches your inbox (search_email), identifies action items, and creates tasks in Apple Reminders (create_task).

Ready to start?  brew install — Free →