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 roadmapto grab a task. Full plan in ROADMAP.md.
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.
| 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.
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 |
git clone https://github.com/jochien/macaroni
cd macaroni
python3 -m pip install -e ".[mcp]" # add ,dev for tests- 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.
roni setup # checks permissions + path, prints client config
roni setup --write # also writes the config into detected clients (backs up)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"Run directly to test:
roni-mcp # stdio server; Ctrl-C to stopAdd to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"macaroni": { "command": "roni-mcp" }
}
}Add to .vscode/mcp.json (or your user mcp.json):
{
"servers": {
"macaroni": { "type": "stdio", "command": "roni-mcp" }
}
}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.
messages_recent, messages_thread, messages_search, messages_context,
messages_send, messages_send_chat.
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;--selfis 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" --directEmits 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}@roniworks in group chats too; only your mention line is read, never other people's messages or surrounding context.- Each event carries
source,chat_id, andgroupso 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.
- 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.
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.
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- CHANGELOG.md: versioned release notes (SemVer).
- CONTRIBUTING.md: branch β PR β release workflow.
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 # π
MIT. See LICENSE.