{"id":48360639,"url":"https://github.com/klemensgc/modular-context-obsidian-plugin","last_synced_at":"2026-04-20T14:04:04.180Z","repository":{"id":349325291,"uuid":"1201902918","full_name":"klemensgc/modular-context-obsidian-plugin","owner":"klemensgc","description":"Modular Context | Karpathy LLM Knowledge Base + Gmail \u0026 G-Cal — multi-account MCP server for Claude Code, encrypted local-first","archived":false,"fork":false,"pushed_at":"2026-04-18T19:02:08.000Z","size":10140,"stargazers_count":76,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-18T21:07:51.303Z","etag":null,"topics":["ai","claude","claude-code","electron","gmail","google-calendar","google-workspace","karpathy","knowledge-base","llm-knowledge-base","local-first","mcp-server","model-context-protocol","oauth2","obsidian-plugin","second-brain","terminal"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/klemensgc.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-04-05T10:20:43.000Z","updated_at":"2026-04-18T19:02:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/klemensgc/modular-context-obsidian-plugin","commit_stats":null,"previous_names":["klemensgc/modular-context-obsidian-plugin"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/klemensgc/modular-context-obsidian-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemensgc%2Fmodular-context-obsidian-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemensgc%2Fmodular-context-obsidian-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemensgc%2Fmodular-context-obsidian-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemensgc%2Fmodular-context-obsidian-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klemensgc","download_url":"https://codeload.github.com/klemensgc/modular-context-obsidian-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemensgc%2Fmodular-context-obsidian-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32050454,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai","claude","claude-code","electron","gmail","google-calendar","google-workspace","karpathy","knowledge-base","llm-knowledge-base","local-first","mcp-server","model-context-protocol","oauth2","obsidian-plugin","second-brain","terminal"],"created_at":"2026-04-05T12:06:47.470Z","updated_at":"2026-04-20T14:04:04.172Z","avatar_url":"https://github.com/klemensgc.png","language":"TypeScript","readme":"# Modular Context | Karpathy LLM Knowledge Base + Gmail \u0026 G-Cal\n\n![banner](banner.png)\n\n\u003e *Your Obsidian vault as LLM-native knowledge base + multi-account Google Workspace (Gmail, Calendar, Drive, Docs, Sheets, Slides) exposed as 25 MCP tools for Claude Code. Local-first, encrypted, no telemetry.*\n\n![Version](https://img.shields.io/github/v/release/klemensgc/modular-context-obsidian-plugin)\n![License](https://img.shields.io/github/license/klemensgc/modular-context-obsidian-plugin)\n![Platform](https://img.shields.io/badge/platform-macOS-blue)\n![Obsidian](https://img.shields.io/badge/Obsidian-0.15+-purple)\n\n---\n\n## What is this?\n\n**Two things in one plugin:**\n\n1. **LLM Knowledge Base** — Your Obsidian vault structured as Sources → Wiki → Schema (Karpathy-aligned framing). Multi-terminal Claude Code + Codex with skills sidebar, agent tracking, session glyphs. Your second brain seen by LLMs as a first-class context.\n\n2. **G-Suite MCP Server** — Multi-account Google Workspace (Gmail, Calendar, Drive, Docs, Sheets, Slides) exposed as 25 native tools for Claude Code (`gmail_search`, `drive_list_files`, `docs_create_doc`, `sheets_append_row`, `slides_read_presentation`, …). OAuth 2.0 + PKCE desktop flow, tokens encrypted via Electron `safeStorage` (OS keychain), no telemetry, no cloud.\n\nOne install, one onboarding, two productivity frontiers.\n\n---\n\n## Architecture\n\n```\n                    🦀  LLM KNOWLEDGE BASE\n                    ┌────────────────────────┐\n                    │   Sources · Wiki ·     │\n                    │   Schema  (vault)      │\n                    └───────┬────────▲───────┘\n                            │        │\n                 feed every │        │ write digest /\n                 new session│        │ synthesise back\n                            ▼        │\n           ╔═════════════════════════╧════════════════════╗\n           ║     🦀  CLAUDE CODE  (sessions · terminals)  ║\n           ║                                              ║\n           ║     ⟲  inbox digest loop                     ║\n           ║     ⟲  meeting prep loop                     ║\n           ║     ⟲  synthesise-files loop                 ║\n           ╚═══════════╦════════════════════╦═════════════╝\n                       │                    │\n                pulls  │                    │  pushes\n                       ▼                    ▼\n           ┌──────────────────────────────────────────┐\n           │   🦀  mcp-google   (stdio · Node)        │\n           └───────────┬──────────────────────┬───────┘\n                       ▼                      ▼\n                    🦀  GOOGLE WORKSPACE (multi-account)\n                    ├─ Gmail   ✓    ← read   → send/draft/label\n                    ├─ GCal    ✓    ← list   → create/update/delete\n                    ├─ Docs    ⋯  coming soon\n                    └─ Drive   ⋯  coming soon\n\n        ── configured by ──▶  🦀  Modular Context Plugin\n                               (infra · OAuth · sidecar)\n```\n\n**Architecture decisions** ([full ADRs in `docs/adrs/`](docs/adrs/)):\n- [ADR-001](docs/adrs/ADR-001-oauth-strategy.md) — Hybrid OAuth: Quick Connect (shared client) + BYO (user-provided client)\n- [ADR-002](docs/adrs/ADR-002-token-storage.md) — Electron `safeStorage` token storage (OS keychain)\n- [ADR-003](docs/adrs/ADR-003-mcp-server-lifecycle.md) + [addendum](docs/adrs/ADR-003-addendum-shared-state.md) — MCP server stdio lifecycle + plaintext credentials sidecar\n- [ADR-005](docs/adrs/ADR-005-multi-account-storage.md) — Multi-account storage model (per-account folder + index)\n\n---\n\n## Features\n\n### LLM Knowledge Base\n\n- **Multi-terminal split layouts** — single, side-by-side, stacked, 2×2, 2×3, 2×4. Up to 8 sessions.\n- **Claude Code + Codex** — toggle AI provider in settings; auto-launch on new terminal.\n- **Skills sidebar** — 3 primary skills (full-width), rest in secondary grid. One-click launches.\n- **Agent tracker** — Working / To Review / Standby states per session.\n- **Session glyphs** — unique geometric shape per terminal. Skills inherit their icon.\n- **Compact mode** — 48px icon-only sidebar, maximum terminal real estate.\n- **Fullscreen overlay** — terminal fills Obsidian; sidebar docks right. `Esc` to exit.\n- **Real PTY** — zsh in a pseudo-terminal, not a basic runner.\n- **Wiki-link autocomplete** — `[[` inside terminal searches vault notes.\n- **Drag-and-drop** — Finder / Obsidian → terminal as shell-escaped paths.\n- **Session persistence** — tab names, glyphs, layouts survive restarts.\n- **Smart Session Restore** — on reopen, picker modal classifies saved sessions (Needs attention / Idle / Archive) instead of silent auto-resume. You choose what materializes — no accidental skill re-runs.\n- **Auto-onboarding** — first install triggers a setup agent that scaffolds your vault.\n\n### G-Suite MCP Server (v2.1 — 25 tools)\n\n- **Multi-account** — unlimited Google accounts in parallel (Testing mode: up to 100 test users per account)\n- **25 tools** for Claude Code across 6 Workspace products (Gmail ×4, Calendar ×6, Drive ×4, Docs ×3, Sheets ×5, Slides ×3 — see table below)\n- **Zero telemetry** — no metrics, no crash reports, no external calls beyond OAuth + Google API\n- **Local-first** — tokens encrypted via OS keychain (macOS Keychain / Windows DPAPI / Linux libsecret via `libsecret`)\n- **Auto-refresh** — 50-minute timer per account, 5-minute expiry buffer\n- **Error taxonomy** — `TOKEN_EXPIRED`, `ACCOUNT_NOT_FOUND`, `SCOPE_OUTDATED`, `RATE_LIMITED`, `PERMISSION_DENIED`, `QUOTA_EXCEEDED`, `NETWORK_ERROR`\n- **Hot reload** — server re-reads credentials per tool call, zero-downtime refresh\n\n---\n\n## 3 primary skills (post-onboarding)\n\n| Skill | Purpose | Uses |\n|-------|---------|------|\n| **Synthesise Files** | Turn raw files (transcripts, notes, backlog) into vault modules — categorize, tag, update, reweave neighbors | Your vault, optional `_transcripts-backlog/` |\n| **WhatsApp Digest** | Analyze WhatsApp groups for action items, blindspots, staleness vs vault | macOS WhatsApp.app |\n| **Gmail + G-Suite** | Inbox sweep, stale follow-ups, calendar gap analysis, meeting prep, doc extraction, sheet logging, deck prep | MCP tools below |\n\nAll three write artifacts to `_workspace/{YYYY-MM}/w{N}/`. Secondary skills (Pulse, Brief, Log, Reweave, Graph, Graduate, Ideas, Vault-Audit) available in sidebar grid.\n\n---\n\n## 25 MCP tools\n\n### Gmail (4)\n\n| Tool | Purpose |\n|------|---------|\n| `gmail_search` | Query with Gmail syntax (`is:unread`, `from:X`, `after:2026-04-01`). Optional body extraction. |\n| `gmail_draft` | Create draft — not sent. User opens `webUrl` in Gmail UI to send. |\n| `gmail_send` | Send immediately. Skip draft for trusted, scripted sends. |\n| `gmail_modify_labels` | Add/remove labels — system presets (`INBOX`, `UNREAD`, `STARRED`, `IMPORTANT`, `SPAM`, `TRASH`) + custom labels by name. |\n\n### Calendar (6)\n\n| Tool | Purpose |\n|------|---------|\n| `calendar_list_calendars` | Enumerate all calendars user has access to. |\n| `calendar_list_events` | Events in time range. |\n| `calendar_create_event` | Create event (`sendUpdates: \"none\"` default — no auto-invite spam). |\n| `calendar_update_event` | Patch existing (only provided fields changed). |\n| `calendar_delete_event` | Delete. |\n| `calendar_freebusy` | Query busy windows across multiple calendars — ideal for \"find time to meet\". |\n\n### Drive (4)\n\n| Tool | Purpose |\n|------|---------|\n| `drive_list_files` | List with Drive query syntax filter, pagination, ordering. |\n| `drive_search` | Full-text search across file content + names. Optional `mimeType` filter. Excludes trashed. |\n| `drive_download_file` | Get file content. Google-native files auto-exported as text; binary returned as base64. |\n| `drive_upload_file` | Create file with content + optional `parentFolderId`. Supports utf-8 / base64. |\n\n### Docs (3)\n\n| Tool | Purpose |\n|------|---------|\n| `docs_read_doc` | Plain-text extraction from doc body (walks paragraphs + tables). |\n| `docs_create_doc` | New doc with title + optional `initialContent`. |\n| `docs_update_doc` | `mode: \"append\"` (at document end) or `mode: \"replace\"` (wipe body + insert). |\n\n### Sheets (5)\n\n| Tool | Purpose |\n|------|---------|\n| `sheets_list_sheets` | Spreadsheet metadata + list of sheet tabs. |\n| `sheets_read_range` | Read A1-notation range. Supports `majorDimension` + `valueRenderOption`. |\n| `sheets_write_range` | Overwrite values at range. `USER_ENTERED` parses formulas + dates. |\n| `sheets_append_row` | Append row(s) to data region end. |\n| `sheets_create_spreadsheet` | New spreadsheet with optional initial sheet titles. |\n\n### Slides (3)\n\n| Tool | Purpose |\n|------|---------|\n| `slides_read_presentation` | Metadata + plain-text summary per slide. |\n| `slides_create_presentation` | New presentation with title. |\n| `slides_add_slide` | Insert slide with layout (BLANK / TITLE / TITLE_AND_BODY / SECTION_HEADER / TITLE_AND_TWO_COLUMNS / CAPTION_ONLY). |\n\n**Every tool accepts optional `account` param** (email, case-insensitive). Omit → primary account. Unknown email → `ACCOUNT_NOT_FOUND` error.\n\n**OAuth scopes required** (10 total): `gmail.modify`, `calendar`, `drive.file`, `drive.metadata.readonly`, `documents`, `spreadsheets`, `presentations`, plus OIDC `openid email profile`.\n\n**Google Cloud setup:** Enable 6 APIs in your OAuth project — Gmail, Calendar, Drive, Docs, Sheets, Slides. Missing API returns `PERMISSION_DENIED` with direct enable link.\n\n---\n\n## Install\n\n### Plugin\n\nRequires Obsidian ≥ 0.15 and macOS (Linux + Windows may work; untested).\n\n**Via BRAT (Beta Reviewer plugin, recommended for now):**\n1. Install BRAT from Community Plugins\n2. `Cmd+P` → \"BRAT: Add a beta plugin\" → `klemensgc/modular-context-obsidian-plugin`\n3. Enable in Settings → Community plugins\n\n**Manual:**\n1. Download `main.js`, `manifest.json`, `styles.css`, `mcp-server.js` from [latest release](https://github.com/klemensgc/modular-context-obsidian-plugin/releases)\n2. Copy to `\u003cvault\u003e/.obsidian/plugins/modular-context/`\n3. Enable plugin in Settings → Community plugins → Modular Context\n\n### MCP server\n\n**Auto-installed** on first `Google Workspace: Connect`. Plugin copies bundled binary to `~/.modular-context/mcp-google/dist/index.js` (~100 MB one-time).\n\n---\n\n## Repo structure\n\nMonorepo with three packages:\n\n```\nmodular-context-obsidian-plugin/\n├── packages/\n│   ├── plugin/        ← Obsidian plugin (main.ts, manifest, features + MCP client glue)\n│   ├── mcp-google/    ← standalone MCP server (25 Google Workspace tools, Node)\n│   ├── shared/        ← portable types + AgentTracker + PTY helper + UI primitives\n│   └── app/           ← experimental standalone Electron app (WIP, not shipped)\n├── README.md          ← you are here\n├── banner.png\n└── package.json       ← monorepo scripts (build:shared → build:mcp-google → build:plugin)\n```\n\n- **[packages/plugin/CHANGELOG.md](packages/plugin/CHANGELOG.md)** — user-facing release notes (v1.0 → v2.0)\n- **[packages/plugin/RELEASE-v2.0.0.md](packages/plugin/RELEASE-v2.0.0.md)** — v2.0 release highlights\n- **[packages/mcp-google/README.md](packages/mcp-google/README.md)** — MCP server docs (25 tools, accounts, env contract)\n- **[packages/mcp-google/CHANGELOG.md](packages/mcp-google/CHANGELOG.md)** — MCP server version history\n- Skill library: separate repo [klemensgc/modular-context-skills](https://github.com/klemensgc/modular-context-skills) — plugin auto-syncs\n\n---\n\n## Connect Google Workspace\n\nTwo paths:\n\n- **Quick Connect** (no GCP setup) — use the shared OAuth client bundled with the pre-built release. Comment your email on [#3 — Quick Connect: request test-user access](https://github.com/klemensgc/modular-context-obsidian-plugin/issues/3) to be added as a test user (usually within 24h). Then skip to step 5 below.\n- **BYO** (your own GCP project) — full control, no test-user limit. Follow all 6 steps below.\n\n### 6 steps (BYO path)\n\n1. **Create GCP OAuth Client**\n   - [Google Cloud Console](https://console.cloud.google.com) → new project (e.g. `modular-context-gcp`)\n   - Enable APIs: Gmail API, Google Calendar API\n   - OAuth consent screen → External, Testing mode → add scopes: `gmail.modify`, `calendar`, plus `openid`, `email`, `profile`\n   - Add yourself as test user\n   - Create credentials → OAuth 2.0 Client ID → Desktop app\n   - Copy Client ID + Client Secret\n\n2. **Fill `.env.local`** in the plugin's build folder:\n   ```\n   GOOGLE_OAUTH_CLIENT_ID=...\n   GOOGLE_OAUTH_CLIENT_SECRET=...\n   ```\n\n3. **Rebuild** (`npm run build` in `packages/plugin`) if self-building. Pre-built release uses the shared Quick Connect client.\n\n4. **Reload plugin** — `Cmd+P` → \"Reload app without saving\"\n\n5. **Connect** — `Cmd+P` → \"Google Workspace: Connect (or add account)\" → browser OAuth → authorize → done\n\n6. **Add more accounts** — \"Google Workspace: Add another account\" any time\n\nThe plugin writes `.mcp.json` to your vault root + per-account sidecars to `~/.modular-context/mcp-google/accounts/{filename}/`. **Restart Claude Code session** to pick up the MCP server.\n\n---\n\n## Plugin commands\n\n| Command | Purpose |\n|---------|---------|\n| `Google Workspace: Connect (or add account)` | Launch OAuth flow for new/additional account |\n| `Google Workspace: Add another account` | Alias for above — clearer intent |\n| `Google Workspace: Reconnect (upgrade scopes)` | Nuke tokens, re-auth all accounts with current scope set |\n| `Google Workspace: Disconnect all accounts` | Remove all credentials + `.mcp.json` entry |\n| `Google Workspace: Status` | List connected accounts, expiry times, scope status |\n| `Google Workspace: Show MCP server logs` | Open `~/.modular-context/mcp-google/logs/server.log` |\n\nPlus 5+ non-Google commands for terminal / skill management. See Command Palette.\n\n---\n\n## Security\n\n- **Tokens** encrypted via Electron `safeStorage` (OS keychain). Never leave disk in plaintext.\n- **Credentials sidecar** for MCP server: plaintext JSON at `0600` perms in user-scope folder (comparable to `~/.aws/credentials`, `~/.config/gcloud/`). Plugin may re-encrypt in v2.1 (see ADR-003 addendum).\n- **No telemetry.** No crash reports. No metrics. Zero phone-home.\n- **Logs** scrub tokens, emails, subjects via regex on every line.\n- **Multi-account isolation.** Each account has separate credentials; MCP server honors `account` param strictly.\n\nFull threat model in [docs/adrs/ADR-003-addendum-shared-state.md](docs/adrs/ADR-003-addendum-shared-state.md).\n\n---\n\n## What's new in v2.0\n\n- 3 primary skills reorganization — `Synthesise Files` (was \"Ingest Data\"), `WhatsApp Digest`, `Gmail + Calendar`\n- New `gsuite-analysis` skill — orchestrates 10 MCP tools with 4 playbook patterns\n- Graduated v1.5 / v1.6 / v1.7 beta milestones: OAuth + storage + MCP server + multi-account + full control\n- OAuth scope upgrade: `gmail.modify` + `calendar` full (replaces `gmail.readonly`, `gmail.send`, `calendar.events`)\n- `mcp-google-workspace` @ 1.1.0 stable (from 1.1.0-beta.1)\n- New tools: `gmail_send`, `gmail_modify_labels`, `calendar_list_calendars`, `calendar_update_event`, `calendar_delete_event`, `calendar_freebusy`\n- **Smart Session Restore Picker** — replaces silent auto-resume on plugin reopen. Modal classifies saved sessions into Needs attention / Idle / Archive buckets; you pick what materializes. No accidental skill re-runs, no hidden respawns.\n\nFull list in [packages/plugin/CHANGELOG.md](packages/plugin/CHANGELOG.md).\n\n---\n\n## Troubleshooting\n\n| Issue | Fix |\n|-------|-----|\n| Notice: \"Reconnect required for {email}\" | `Google Workspace: Reconnect (upgrade scopes)` — scopes changed |\n| `TOKEN_EXPIRED` from MCP tool | User revoked access or refresh token rotated — `Reconnect` |\n| `ACCOUNT_NOT_FOUND` | Account not connected — `Add another account` |\n| MCP server not visible in Claude Code | Restart Claude Code session. `.mcp.json` loaded at session start. |\n| Plugin reloaded but old behavior | Hard reload: `Cmd+P` → \"Reload app without saving\" (not just disable+enable) |\n| Server logs empty | Normal — server only runs when Claude Code calls a tool. Not a daemon. |\n\n---\n\n## Contributing\n\nPlugin: [modular-context-obsidian-plugin](https://github.com/klemensgc/modular-context-obsidian-plugin)\n\nSkills library: [modular-context-skills](https://github.com/klemensgc/modular-context-skills) (separate repo, auto-synced)\n\nPRs welcome. Issues welcome. No support contract, but I read everything.\n\n---\n\n## License\n\nMIT © klemensgc / receptionOS\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemensgc%2Fmodular-context-obsidian-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklemensgc%2Fmodular-context-obsidian-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemensgc%2Fmodular-context-obsidian-plugin/lists"}