{"id":50335385,"url":"https://github.com/bdombro/mcpyeahyouknowme","last_synced_at":"2026-05-29T13:02:08.441Z","repository":{"id":347877992,"uuid":"1195391276","full_name":"bdombro/mcpyeahyouknowme","owner":"bdombro","description":"A data gateway MCP with local caching and natural language searching","archived":false,"fork":false,"pushed_at":"2026-04-14T19:46:49.000Z","size":62774,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T21:28:02.492Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bdombro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-29T16:06:53.000Z","updated_at":"2026-04-14T19:46:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bdombro/mcpyeahyouknowme","commit_stats":null,"previous_names":["bdombro/mcpyeahyouknowme"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bdombro/mcpyeahyouknowme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Fmcpyeahyouknowme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Fmcpyeahyouknowme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Fmcpyeahyouknowme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Fmcpyeahyouknowme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bdombro","download_url":"https://codeload.github.com/bdombro/mcpyeahyouknowme/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Fmcpyeahyouknowme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33652986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-29T13:02:07.222Z","updated_at":"2026-05-29T13:02:08.408Z","avatar_url":"https://github.com/bdombro.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MCP Yeah You Know Me\n\n**One MCP server. All your personal data.** `mcpyeahyouknowme` connects WhatsApp, Gmail, Docs, Sheets, Calendar, Tasks, Contacts, Slides, local notes, browser history, live web search, and Google Places behind a single [MCP](https://modelcontextprotocol.io/) endpoint — so your AI assistant uses one consistent toolset instead of juggling a patchwork of separate servers.\n\n**Global search across everything.** A single `search` tool performs BM25 keyword search across every connected source at once — emails, chats, calendar events, documents, notes, browser history — ranked by relevance with follow-up metadata pointing to the right source-specific tool for deep reads.\n\n**Offline-first, privacy-preserving.** All data syncs into local SQLite databases. Every read tool queries local files directly — no network latency, nothing leaves your machine until you explicitly ask for it. The background daemon handles sync; the MCP server reads from local caches.\n\n\u003e *Caution:* as with many MCP servers, this is subject to [the lethal trifecta](https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/). Prompt injection could lead to private data exfiltration.\n\n## Architecture\n\nA single Go binary with a pluggable `DataSource` interface. Two long-running modes:\n\n| Mode | Command | Description |\n|------|---------|-------------|\n| Core daemon | `mcpyeahyouknowme core` | Syncs all sources into local SQLite, maintains the global search index, exposes a REST API for writes |\n| MCP server  | `mcpyeahyouknowme mcp`  | Stdio MCP server — reads from local SQLite for every query, proxies writes to the core daemon |\n\nAll reads hit local SQLite; the MCP server never calls external APIs directly. Write operations (send message, download media) are proxied through the core daemon's loopback REST API.\n\nSee the [product spec](docs/spec.md) for full details.\n\n## Security\n\nOptional controls live in `~/.local/share/mcpyeahyouknowme/config.json` under a top-level **`mcp`** object (safe to omit; defaults apply at runtime without rewriting the file). Any ongoing MCP connections would need to be restarted/loaded to take effect. A **full annotated template** (all sources + `mcp` keys) is in [**config.json reference**](#configjson-reference) below.\n\n| Field | Default | What it does |\n|-------|---------|----------------|\n| `read_only` | `false` | When `true`, the MCP server registers **no** mutating tools (nothing that changes state or hits write paths). |\n| `disabled_tools` | `[]` | Tool names to omit entirely (e.g. `whatsapp_send_message`). |\n| `mutating_tools_per_min` | `10` | Per-tool sliding window: each **non–read-only** tool may run at most this many times per minute; further calls return a rate-limit tool error. |\n| `whatsapp_send_max_runes` | `1000` | Max Unicode characters allowed in one `whatsapp_send_message` body. Omit or set `≤ 0` to keep the default (`1000`). Set higher if you routinely send long texts via MCP. |\n\n**Audit log:** every MCP tool invocation appends one JSON line to `mcp-audit.log` in the same data directory. Sensitive argument keys (`message`, `query`, `path`, `body`, `base64`, `media_path`) are logged as length-only redactions. The file is trimmed like `core.log` when it grows past 5\u0026nbsp;MiB (newest ~1\u0026nbsp;MiB kept).\n\n**Untrusted content:** results from external or user-controlled sources (e.g. WhatsApp/Gmail message bodies, web search, browser history, notebook reads, and global `search` / `profile_about_me` when hits include those sources) are prefixed with a short security warning and include `_meta` hints where supported.\n\n**`whatsapp_send_message` size cap (complement to rate limits):** not a substitute for `mutating_tools_per_min`, but it bounds how much text one send can carry—useful when an automated agent might otherwise paste huge blobs (accidentally or via prompt injection). Default **1000** Unicode characters per call; override with `mcp.whatsapp_send_max_runes`.\n\n**2FA / OTP redaction (what gets censored):** before persisting to SQLite (and therefore before full-text indexing and MCP reads that come from the local DB), the server runs a **conservative heuristic** on message text to determine if it's a one-time password message and to censor if so.\n\n## Prerequisites\n\n- **macOS** (Apple Silicon or Intel)\n- **Homebrew** (for installing dependencies)\n- **Go** (to build)\n\n## Quick Start\n\n1. **Clone the repository**\n\n   ```bash\n   git clone https://github.com/bdombro/mcpyeahyouknowme.git\n   cd mcpyeahyouknowme\n   ```\n\n2. **Install**\n\n   ```bash\n   ./scripts/install.sh\n   ```\n\n   This builds the Go binary, copies it to `/usr/local/bin/mcpyeahyouknowme`, sets up the core daemon, and adds shell completions.\n\n3. **Log in** (first time only)\n\n   ```bash\n   mcpyeahyouknowme whatsapp login\n   ```\n\n   Scan the QR code with your WhatsApp app. The initial history sync will be captured during login. The daemon will handle reconnection from now on.\n\n4. **Configure the MCP server** in your AI client:\n\n   ```json\n   {\n     \"mcpServers\": {\n       \"whatsapp\": {\n         \"command\": \"mcpyeahyouknowme\",\n         \"args\": [\"mcp\"]\n       }\n     }\n   }\n   ```\n\n   - **Claude Desktop**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n   - **Cursor**: `~/.cursor/mcp.json`\n\n5. **Restart Claude Desktop / Cursor**\n\n## Google Suite Setup\n\nGoogle Suite uses a desktop OAuth client with PKCE. Google still expects both `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` during token exchange, but the binary can still be built without them. If either is missing at build time, the `gsuite` source is marked unavailable until you rebuild with both values.\n\n1. **Bootstrap the Google Cloud project**\n\n   ```bash\n   just google-project-setup your-google-project-id\n   ```\n\n   This validates `gcloud`, selects the project, enables the required APIs, creates a restricted Places API key, and prints the remaining manual Google Cloud Console steps.\n\n2. **Finish the manual Google Cloud Console steps**\n\n   - Open [Google Cloud Console](https://console.cloud.google.com/) and confirm the project\n   - Open **Google Auth Platform**\n   - Configure Branding / app information\n   - Choose the Audience (`External` for a public app, `Internal` only for Workspace-only use)\n   - Add support/contact email and test users while the app is unverified\n   - Review the requested scopes\n   - Create an OAuth client of type **Desktop app**\n   - Copy the Desktop app **Client ID** and **Client Secret**\n\n   A Desktop app client secret is not a meaningful trusted secret in a shipped macOS binary, but Google currently still requires it during token exchange.\n\n3. **Set the client credentials**\n\n   ```bash\n   export GOOGLE_CLIENT_ID='your-desktop-client-id'\n   export GOOGLE_CLIENT_SECRET='your-desktop-client-secret'\n   ```\n\n   Add them to your shell profile or put them in `.env` before building if you want the `gsuite` source enabled in the binary.\n\n4. **Build-time Places API key** (optional)\n\n   `just google-project-setup` will also create a restricted Places API key and write it to `.env` as `GOOGLE_PLACE_API_KEY`. When present during `just build`, it enables the `google_places_*` MCP tools for live business and address lookup.\n\n5. **Build-time Brave Search API key** (optional)\n\n   Set `BRAVE_API_KEY` in `.env` before building to enable the `brave_search_*` MCP tools for live web search and URL metadata lookup. Get a key from the [Brave Search API Dashboard](https://api-dashboard.search.brave.com/).\n\n6. **Authenticate and enable the apps you want**\n\n   ```bash\n   mcpyeahyouknowme gsuite login\n   ```\n\n   This opens your browser for OAuth authorization, stores the token in `~/.local/share/mcpyeahyouknowme/gsuite_token.json`, stores the account email in `~/.local/share/mcpyeahyouknowme/gsuite_email.txt`, and prompts you to choose which Google apps to enable. Apps start disabled until you explicitly enable them.\n\n7. **Manage enabled apps**\n\n   ```bash\n  mcpyeahyouknowme gsuite manage\n   ```\n\n8. **Reset Google Suite data** (optional)\n\n   ```bash\n   mcpyeahyouknowme gsuite reset\n   ```\n\n   This removes the token and synced Google data, then leaves the source disabled until you log in again.\n\n## Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `BRAVE_API_KEY` | Optional | Build-time Brave Search API key that enables the `brave_search_*` tools |\n| `GOOGLE_CLIENT_ID` | Optional | Desktop OAuth client ID from Google Cloud Console; required only if you want the `gsuite` source available |\n| `GOOGLE_CLIENT_SECRET` | Optional | Matching desktop OAuth client secret; required only if you want the `gsuite` source available |\n| `GOOGLE_PLACE_API_KEY` | Optional | Build-time Places API key that enables the `google_places_*` tools |\n| `GOOGLE_PROJECT_ID` | Optional | Used by `scripts/google-project-setup.sh` / `just google-project-setup` |\n\n## Managing the Daemon\n\nInstall the core daemon (runs on login, auto-restarts) and manage it:\n\n```bash\nmcpyeahyouknowme start\nmcpyeahyouknowme stop\nmcpyeahyouknowme restart\n```\n\nOther commands:\n\n```bash\n# Show status and data locations\nmcpyeahyouknowme status\n\n# Refresh the status view every 10 seconds\nmcpyeahyouknowme status --live\n\n# Wipe WhatsApp data and session (only WhatsApp)\nmcpyeahyouknowme whatsapp reset\n\n# Wipe Google Suite token and synced data\nmcpyeahyouknowme gsuite reset\n```\n\n## Uninstalling\n\nTo completely remove mcpyeahyouknowme:\n\n```bash\ncd /path/to/mcpyeahyouknowme\n./scripts/uninstall.sh\n```\n\nThis will:\n- Kill all running mcpyeahyouknowme processes\n- Clean up database lock files\n- Unload and remove the daemon\n- Delete the data directory (`~/.local/share/mcpyeahyouknowme`)\n- Remove shell completions from `~/.zshrc`\n- Remove the binary from `/usr/local/bin/mcpyeahyouknowme`\n\n## Troubleshooting\n\n- **QR code not displaying**: Restart the CLI. Check that your terminal supports QR rendering.\n- **Already logged in**: The CLI reconnects automatically without a QR code.\n- **Device limit reached**: Remove an existing device from WhatsApp on your phone (Settings \u003e Linked Devices).\n- **No messages loading**: Initial history sync can take several minutes for large accounts. History is only pushed during first pairing. If your database is empty, run `mcpyeahyouknowme whatsapp login --relogin` to re-pair and capture the initial sync.\n- **Out of sync**: Run `mcpyeahyouknowme whatsapp reset` to wipe all data, then `mcpyeahyouknowme whatsapp login` to re-authenticate.\n- **Session expired / 405 error**: Run `mcpyeahyouknowme whatsapp login --relogin` to clear the stale session and re-pair. The daemon will be restarted automatically.\n\nFor additional Claude Desktop troubleshooting, see the [MCP documentation](https://modelcontextprotocol.io/quickstart/server#claude-for-desktop-integration-issues).\n\n## config.json reference\n\n**Path:** `~/.local/share/mcpyeahyouknowme/config.json` (same folder as the SQLite databases and `mcp-audit.log`).\n\nThe daemon normalizes this file over time: every **registered source** gets a `sources.\u003cname\u003e` entry even when disabled, so keys may appear before you configure a source. The **`mcp`** block is optional and is read only by the **`mcpyeahyouknowme mcp`** subprocess.\n\n### Full reference (JSON with comments, tsconfig-style)\n\n**Important:** The Go runtime uses strict **JSON** — **`//` and `/* */` comments are not allowed** in the real file on disk. Treat the block below as documentation: copy the structure and values you need, **delete all comment lines**, then save. (Some editors can strip JSONC to JSON on export.)\n\n```jsonc\n{\n  // --- sources: one object per integration (names are fixed) ---\n  \"sources\": {\n    \"brave_search\": {\n      // Whether this source is turned on in config. Live Brave tools also need\n      // BRAVE_API_KEY at build time; there is no API key stored here.\n      \"enabled\": false,\n      // When true, the core daemon runs source Reset() on its next loop, then\n      // tooling normally clears this flag. You rarely set it by hand.\n      // \"reset\": false,\n      // No \"auth\" blob for brave_search.\n    },\n    \"browser_history\": {\n      \"enabled\": false,\n      // \"auth\" selects which Chromium profile DB to snapshot (macOS).\n      // Typical values: \"chrome\", \"brave\". Use: mcpyeahyouknowme browser_history enable \u003cbrowser\u003e\n      \"auth\": {\n        \"browser\": \"chrome\"\n      }\n    },\n    \"google_places\": {\n      \"enabled\": false,\n      // Places needs GOOGLE_PLACE_API_KEY at build time; nothing stored under \"auth\".\n    },\n    \"gsuite\": {\n      \"enabled\": false,\n      // \"auth\" only holds per-app toggles. OAuth tokens live in gsuite_token.json\n      // next to this file (written by: mcpyeahyouknowme gsuite login).\n      \"auth\": {\n        \"apps\": {\n          \"docs\": false,\n          \"sheets\": false,\n          \"gmail\": false,\n          \"calendar\": false,\n          \"tasks\": false,\n          \"contacts\": false,\n          \"slides\": false\n        }\n      }\n    },\n    \"notebook\": {\n      \"enabled\": false,\n      // Local directories to index (markdown, PDF, images). Use:\n      // mcpyeahyouknowme notebook add \u003cpath\u003e  (populates dirs for you)\n      \"auth\": {\n        \"dirs\": []\n      }\n    },\n    \"whatsapp\": {\n      \"enabled\": false\n      // Pairing/session files live under the data directory; login sets enabled.\n      // No \"auth\" object in config.json for WhatsApp.\n    }\n  },\n\n  // --- mcp: optional; used only by `mcpyeahyouknowme mcp` (restart MCP to apply) ---\n  \"mcp\": {\n    // When true, no mutating tools are registered (no sends, downloads, etc.).\n    \"read_only\": false,\n\n    // Exact tool names to hide entirely, e.g. \"whatsapp_send_message\".\n    \"disabled_tools\": [],\n\n    // Per mutating tool name: max calls per sliding minute (default 10 if omitted or \u003c= 0).\n    \"mutating_tools_per_min\": 10,\n\n    // Max Unicode runes/words per whatsapp_send_message body (default 1000 if omitted or \u003c= 0).\n    \"whatsapp_send_max_runes\": 1000\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdombro%2Fmcpyeahyouknowme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbdombro%2Fmcpyeahyouknowme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdombro%2Fmcpyeahyouknowme/lists"}