Skip to main content
Glama
whogben

mac-messages

by whogben
README.md
# Mac Messages Host
Your Mac's entire Apple Messages (iMessage/SMS) history, read-only, for AI agents — one batched tool over REST/OpenAPI and streamable HTTP MCP.

- **One tool, batched requests**: a single `messages(requests: str)` tool takes a JSON array of requests and returns an aligned JSON array of responses — one call does many independent ops. Served identically over REST (`POST /api/messages`) and MCP (`/mcp/`).
- **Read-only by construction**: the database is opened with SQLite `mode=ro`; there is no write path. Nothing can be sent, edited, or deleted.
- **Modern macOS body decoding**: message text stored in `attributedBody` typedstream blobs (Ventura+) and edit history in `message_summary_info` plists is decoded transparently.
- **Auto-generated tool prompt**: the AI-facing prompt is generated from the Pydantic models (~615 gpt-4o tokens, counted by `tiktoken` and enforced by a test); a `tool_prompt.md` snapshot is kept in sync by a drift test.

## Install

Requires Python 3.11+ on macOS.

```bash
pip install .            # or: pip install -e . for development
mmhost info              # permission check + database status
mmhost start             # serve API + MCP on http://127.0.0.1:8761
```

### macOS permissions (important)

`~/Library/Messages/chat.db` is protected by macOS TCC. The process that runs
`mmhost` needs **Full Disk Access**:

System Settings → Privacy & Security → Full Disk Access → enable your terminal app (or whatever launches the server), then restart it.

`mmhost info` tells you immediately whether the database is readable.

## Endpoints

| Endpoint | Purpose |
|---|---|
| `POST /api/messages` | The batched tool (REST) |
| `/api/openapi.json` | OpenAPI schema |
| `/api/docs` | Interactive docs |
| `/api/health` | Liveness probe |
| `/mcp/` | Streamable-HTTP MCP endpoint (single `messages` tool) |

### Auth

`Authorization: Bearer <token>` when `admin_token` is configured (persisted config, `MMHOST_ADMIN_TOKEN`, or `--admin-token`). With no token configured, access is open — safe because the server binds `127.0.0.1` by default.

## Request kinds

- `get_info` — database status, counts, history date range
- `list_chats` — conversations by recent activity (filter, paginate)
- `get_chat` — a chat's transcript (paginate older via `before`)
- `get_recent` — newest messages across all chats (poll via `since`)
- `search_messages` — case-insensitive substring search over bodies

See [tool_prompt.md](https://github.com/whogben/mac_messages_host/blob/main/tool_prompt.md) for the exact AI-facing documentation (generated from the models).

### Example

```bash
curl -s http://127.0.0.1:8761/api/messages \
  -H 'Content-Type: application/json' \
  -d '{"requests": "[{\"kind\":\"list_chats\",\"limit\":3}]"}'
```

### MCP client configuration

```json
{
  "mcpServers": {
    "mac-messages": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8761/mcp/"
    }
  }
}
```

## Configuration

Persisted at the platform config dir (`~/Library/Application Support/mac_messages_host/config.json` on macOS); override the location with `MMHOST_CONFIG`. Server-level settings only — see [example.env](https://github.com/whogben/mac_messages_host/blob/main/example.env).

## Development

```bash
pip install -e '.[dev]'
pytest
# after changing request models:
python -m tests.regenerate_tool_prompt
```

Architecture follows the oWoHo AI Tool Server pattern (pure core library + derived FastAPI/FastMCP/CLI interfaces), like `reddit_tool_server` and `obsidian_ai_miniserver`.

## License

MIT — see [LICENSE.md](https://github.com/whogben/mac_messages_host/blob/main/LICENSE.md).