Skip to content

jochien/macaroni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🍝 Macaroni

Your Mac, at your command.

Macaroni is a friendly bridge between you and your Mac. Text a quick note, either to your AI agent or to yourself with the agent listening, and your Mac acts on it. Ask your AI assistant to check your messages, and soon to add a reminder, jot a note, or check your calendar. One bowl, many noodles: a growing suite of macOS app tools that any AI agent can use.

Today it serves the first noodle: Messages (iMessage), exposed three ways that share one core: a local MCP server, a roni CLI, and an iMessage control loop that lets you drive an agent from your phone over iMessage.

macOS only. Everything runs locally on your Mac, with no server to host and nothing exposed to the network.

πŸ§‘β€πŸ’» Resuming work (humans & agents)? Open this repo, read AGENTS.md, then run gh issue list --label roadmap to grab a task. Full plan in ROADMAP.md.


Why "Macaroni"? 🍝

Because the name is the product.

  • Mac is in the name twice over: it's your Mac, and in Gaelic Mac‑ means "son of."
  • ‑aroni β†’ Roni. In Hebrew, Roni (Χ¨Χ•ΦΉΧ Φ΄Χ™) means "my joy / my song," and as a verb it's the imperative "rejoice!", fittingly a command. So Mac‑a‑Roni reads as "son of joy," a tool that takes your orders and brings a little delight.
  • The dish itself traces back through Italian maccheroni to the Greek makaria, rooted in makar‑, "blessed / happy." Macaroni has meant the happy dish for a very long time.

And the noodle is a shockingly good metaphor for what we're building:

🍝 The noodle πŸ› οΈ The product
Many small pieces, one warm bowl A suite of Mac tools working together
The elbow's bend is a connector The bridge between you and your Mac (over iMessage)
Comfort food An approachable, friendly agent, not a control panel
"Use your noodle" The agent's brain doing the thinking for you

So: the platform is the bowl, each app is a noodle, the iMessage link is the bridge, and Roni, a little elbow‑macaroni at the helm, is the one taking your orders.


Deployment models

Model How you talk to it Replies Setup
Dedicated agent Mac (--direct) text the agent's contact (its own Apple ID, e.g. stormclaw) genuinely incoming (left) a Mac + Apple ID for the agent
Single Mac (--mention) text yourself @roni … self-messages none

The dedicated model is the intended setup: a small always-on Mac that bridges your hardware + apps to an AI, reachable from your phone. The single-Mac/@roni model is a zero-setup way to try it. Full guide: docs/deployment.md.


Why it's local-only

Macaroni needs Full Disk Access to read ~/Library/Messages/chat.db and Automation permission for the Messages app to send. Because of that it must run on your machine anyway, so the MCP server uses stdio transport: your AI client (Claude Desktop, ChatGPT, VS Code) launches the server as a subprocess when it starts and talks to it over stdin/stdout. No hosting, no open ports, nothing leaves your Mac.

Local stdio MCP (used here) Remote HTTP MCP
Hosting None; client spawns it You run a server somewhere
Network exposure None Exposed over HTTP
Where your data goes Stays on your Mac Sent to/through a server

Install

git clone https://github.com/jochien/macaroni
cd macaroni
python3 -m pip install -e ".[mcp]"     # add ,dev for tests

Grant macOS permissions (one time)

  • Full Disk Access β†’ add your terminal app (or the AI client that launches the server). System Settings β†’ Privacy & Security β†’ Full Disk Access. Restart the app.
  • Automation β†’ Messages β†’ granted on first send; allow when prompted.

One-command checkup

roni setup            # checks permissions + path, prints client config
roni setup --write    # also writes the config into detected clients (backs up)

Use it from the CLI

The suite namespaces each app under roni <app> <action>, so it grows cleanly:

roni messages recent 10
roni messages thread "+14255550123" 20
roni messages search "dinner"
roni messages send "you@icloud.com" "hello from the CLI"
# coming soon:  roni reminders add "milk"   Β·   roni notes new "idea"

Use it as an MCP server

Run directly to test:

roni-mcp        # stdio server; Ctrl-C to stop

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "macaroni": { "command": "roni-mcp" }
  }
}

VS Code (GitHub Copilot)

Add to .vscode/mcp.json (or your user mcp.json):

{
  "servers": {
    "macaroni": { "type": "stdio", "command": "roni-mcp" }
  }
}

ChatGPT

Use the desktop app's MCP/connector support (where available) and point it at the roni-mcp stdio command, same as above.

Full step-by-step setup for Claude, OpenAI/ChatGPT, and VS Code + Copilot, including the absolute-path gotcha, is in docs/install.md.

Tools exposed

messages_recent, messages_thread, messages_search, messages_context, messages_send, messages_send_chat.

The bridge: an iMessage control loop

Drive an agent remotely over iMessage. Two modes, matching the deployment models above:

  • --direct (dedicated agent Mac): text the agent's own contact. Every incoming message from the owner is treated as a command; --self is the owner's handle.
  • --mention (single Mac): text yourself with a mention token. Only messages you write that contain the token are commands; everything else you text yourself stays private.
# Single Mac, text yourself @roni:
roni listen --once --reset --json \
  --self "you@icloud.com" --mention "@roni"

# Dedicated agent Mac, text the agent's contact (--self is the owner):
roni listen --once --reset --json \
  --self "owner@icloud.com" --direct

Emits one JSON event and exits (re-run to continue; state is persisted so an agent can drive the loop one turn at a time):

{"event": "command", "text": "what's on my calendar", "source": "self", "group": false}
  • @roni works in group chats too; only your mention line is read, never other people's messages or surrounding context.
  • Each event carries source, chat_id, and group so an agent knows where it came from and can reply privately (default) or, on explicit request, to the whole group.

See docs/control-loop.md for the full agent loop pattern.

Privacy & safety model

  • Reads are read-only; the Messages database is never modified.
  • The control loop reads only messages you send (plus people you explicitly whitelist). See docs/permissions.md for tiered access.
  • Group context is read only on explicit request (messages_context).
  • Posting to a group (messages_send_chat) messages other people, so agents must confirm the exact text with you first.

Roadmap: more noodles

The platform is the bowl; each app is a noodle. Next up: Reminders, then Notes, Calendar, and Contacts (name β†’ handle). The full plan lives in ROADMAP.md, and the dispatcher + sub-agents design for autonomous mode is in docs/architecture.md.

Run it always-on (launchd)

roni daemon install --self you@icloud.com --mention "@roni"   # single-Mac listener
# or, dedicated agent Mac:  roni daemon install --self owner@icloud.com --direct
roni daemon status
roni daemon uninstall

Project

Feedback

This is early and experimental, and feedback is very welcome. Open an issue with bugs, ideas, or how you'd like to use it. PRs welcome too (see CONTRIBUTING.md).

roni reminders add "milk"     # πŸ”œ next noodle
roni notes new "idea"          # πŸ”œ
roni calendar today           # πŸ”œ

License

MIT. See LICENSE.

About

🍝 Macaroni β€” your Mac, at your command. A local MCP/CLI suite that bridges macOS apps (starting with Messages) to AI agents.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages