{
  "markdown": "<div align=\"center\">\n\n# ✅ RemindersBridge\n\n**Use your Apple Reminders inside ChatGPT — through your own Mac.**\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-f5b942.svg)](./LICENSE)\n[![npm](https://img.shields.io/npm/v/apple-reminders-agent.svg?color=4ade80&label=apple-reminders-agent)](https://www.npmjs.com/package/apple-reminders-agent)\n\n</div>\n\nRemindersBridge is a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) connector that lets ChatGPT work with your **Apple Reminders**. It never uploads your reminders to a third party — every action runs on **your own Mac** through a tiny local agent. The cloud piece is only a stateless relay that shuttles requests between ChatGPT and your Mac.\n\n```\n  ChatGPT  ──OAuth──►  RemindersBridge relay  ──job queue──►  apple-reminders-agent  ──►  Reminders.app\n (connector)          (Vercel, stateless)      (your Mac, polls & executes)        (on your Mac)\n```\n\nYour Mac is the only place your reminders are ever read or written. The relay stores only short-lived job payloads and your account record; it never sees a reminder unless a job is in flight, and jobs expire in seconds.\n\n---\n\n## For users — 3 steps\n\n**1. Create your account** at **[remindersbridge.vercel.app](https://remindersbridge.vercel.app)** and generate a pairing code.\n\n**2. Install the Mac agent** (needs [Node 18+](https://nodejs.org)):\n\n```bash\nnpx apple-reminders-agent pair <YOUR-CODE>   # link this Mac to your account\nnpx apple-reminders-agent install            # keep it running on every restart\n```\n\nThe first time it touches Reminders, macOS asks **\"Terminal wants to control Reminders\"** — click **OK** (one time).\n\n**3. Connect ChatGPT:** Settings → **Plugins** → turn on **Developer mode** (Security & login) → **Create** a custom plugin → paste the MCP Server URL **`https://remindersbridge.vercel.app/mcp`** → Authentication **OAuth** → sign in & **Allow**.\n\nThat's it. In a new chat: *\"Search my Apple Reminders for the dentist appointment\"* or *\"Add oat milk to my Groceries list, due tomorrow.\"*\n\n> Your Mac must be awake with the agent running. `npx apple-reminders-agent install` makes it start automatically at login and restart if it ever crashes.\n\n### Managing the agent\n\n```bash\nnpx apple-reminders-agent status      # is it paired & reachable?\nnpx apple-reminders-agent logs        # recent activity\nnpx apple-reminders-agent uninstall   # stop auto-start\n```\n\n---\n\n## What ChatGPT can do\n\n| Tool | Action |\n|------|--------|\n| `search` | Search reminders by keyword |\n| `fetch` | Fetch full details of one reminder by id |\n| `list_lists` | List all reminder lists with open (incomplete) counts |\n| `list_reminders` | List reminders (optionally filter to one list, or include completed) |\n| `get_reminder` | Read a reminder by id or name |\n| `create_reminder` | Create a reminder (name, optional notes, due date, target list) |\n| `complete_reminder` | Mark a reminder complete (or reopen it) |\n| `update_reminder` | Edit a reminder's name, notes, or due date |\n\n---\n\n## Self-hosting\n\nYou can run your own relay so nothing depends on the hosted instance.\n\n**Prereqs:** a [Vercel](https://vercel.com) account and a [Supabase](https://supabase.com) project (free tiers are fine).\n\n1. **Storage** — in your Supabase project's SQL editor, run [`supabase/schema.sql`](./supabase/schema.sql). It creates a tiny Redis-shaped KV + queue surface (`nb_*` functions) with RLS on.\n2. **Deploy** the `server/` directory to Vercel.\n3. **Set env vars** (see [`server/.env.example`](./server/.env.example)):\n   - `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY` — your project + service-role key\n   - `JWT_SECRET` — `openssl rand -hex 32`\n4. **Verify:** `curl https://YOUR-APP.vercel.app/api/health` → `redisConfigured`, `redisOk`, `jwtSecretSet` all `true`.\n5. Point the agent at it: `npx apple-reminders-agent pair <CODE> --server https://YOUR-APP.vercel.app`.\n\n---\n\n## How it works\n\n- **Auth** — OAuth 2.1 with PKCE and Dynamic Client Registration (RFC 7591). ChatGPT registers itself, the user signs in on the RemindersBridge consent page, and ChatGPT gets a scoped MCP access token. JWTs are HMAC-signed; three kinds (`session`, `agent`, `mcp`) with distinct privileges. Optional email verification via Resend (`RESEND_API_KEY`); off unless configured, and enforcement is opt-in (`REQUIRE_EMAIL_VERIFICATION`).\n- **Relay** — MCP tool call → job pushed to `jobs:<user>` (TTL ≤ the caller's wait window, so an abandoned job can't run late) → the Mac agent (holding a hanging long-poll) is handed the job within ~200ms, executes it, pushes the result → the MCP handler returns it. The long-poll means jobs are delivered on arrival rather than on a fixed interval, so relay overhead is ~300ms instead of ~1s. The agent is considered \"online\" only while it's actively connected.\n- **Agent** — a dependency-free Node CLI. Tools run via JXA (`osascript -l JavaScript`) against Reminders.app; arguments are passed as JSON over argv (never shell-interpolated). A macOS LaunchAgent keeps it alive across logins and crashes.\n\n## Repository layout\n\n```\nserver/    Vercel functions: OAuth + MCP endpoint + relay        (deploy this)\nagent/     apple-reminders-agent — the npm-published Mac CLI          (users npx this)\nkit/       Browser automations: register the dev-mode connector AND\n           fill the OpenAI directory submission (see kit/README.md)\nsupabase/  schema.sql for self-hosting the storage\ntest/      end-to-end OAuth + MCP integration test\n```\n\n## Development\n\n```bash\n# server\ncd server && cp .env.example .env.local   # fill in, then: vercel dev\n# end-to-end test against a live deployment (reads ../.env.local)\nnode test/e2e-oauth.mjs\n# agent unit tests\nnode --test agent/test-agent-unit.mjs\n```\n\n## Security & privacy\n\n- Reminders are read/written **only on your Mac**. The relay never persists reminder content — job payloads live in Redis-shaped storage with a short TTL and are deleted on delivery.\n- The agent token is stored at `~/.remindersbridge-agent.json` (mode `600`).\n- No secrets are committed; see [`.gitignore`](./.gitignore) and the `.env.example` files.\n- Write tools are marked destructive so ChatGPT asks before changing a reminder.\n\n## License\n\n[MIT](./LICENSE) © Isaiah Dupree\n",
  "bytes": 6258,
  "sha": "1399401d132df1a3130fabc67cdbca7f00117ef00b3ee31764874d3675dd5aed",
  "repo_slug": "isaiahdupree/reminders-bridge",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_isaiahdupree_reminders_bridge_dcfddea4/readme"
}