@rubytech/create-maxy-code 0.1.469 → 0.1.471
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +40 -0
- package/package.json +1 -1
- package/payload/platform/config/brand.json +2 -1
- package/payload/platform/docs/superpowers/plans/2026-07-18-graph-native-ledger.md +807 -0
- package/payload/platform/docs/superpowers/specs/2026-07-18-graph-native-ledger-design.md +241 -0
- package/payload/platform/lib/ledger-core/dist/ageing.d.ts +14 -0
- package/payload/platform/lib/ledger-core/dist/ageing.d.ts.map +1 -0
- package/payload/platform/lib/ledger-core/dist/ageing.js +38 -0
- package/payload/platform/lib/ledger-core/dist/ageing.js.map +1 -0
- package/payload/platform/lib/ledger-core/dist/balance.d.ts +25 -0
- package/payload/platform/lib/ledger-core/dist/balance.d.ts.map +1 -0
- package/payload/platform/lib/ledger-core/dist/balance.js +38 -0
- package/payload/platform/lib/ledger-core/dist/balance.js.map +1 -0
- package/payload/platform/lib/ledger-core/dist/index.d.ts +5 -0
- package/payload/platform/lib/ledger-core/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/ledger-core/dist/index.js +5 -0
- package/payload/platform/lib/ledger-core/dist/index.js.map +1 -0
- package/payload/platform/lib/ledger-core/dist/money.d.ts +12 -0
- package/payload/platform/lib/ledger-core/dist/money.d.ts.map +1 -0
- package/payload/platform/lib/ledger-core/dist/money.js +16 -0
- package/payload/platform/lib/ledger-core/dist/money.js.map +1 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.d.ts +51 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.d.ts.map +1 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.js +77 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.js.map +1 -0
- package/payload/platform/lib/ledger-core/package.json +16 -0
- package/payload/platform/lib/ledger-core/src/__tests__/ageing.test.ts +42 -0
- package/payload/platform/lib/ledger-core/src/__tests__/balance.test.ts +48 -0
- package/payload/platform/lib/ledger-core/src/__tests__/reconcile.test.ts +87 -0
- package/payload/platform/lib/ledger-core/src/ageing.ts +51 -0
- package/payload/platform/lib/ledger-core/src/balance.ts +52 -0
- package/payload/platform/lib/ledger-core/src/index.ts +4 -0
- package/payload/platform/lib/ledger-core/src/money.ts +17 -0
- package/payload/platform/lib/ledger-core/src/reconcile.ts +109 -0
- package/payload/platform/lib/ledger-core/tsconfig.json +6 -0
- package/payload/platform/neo4j/schema.cypher +16 -0
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/.claude-plugin/marketplace.json +10 -0
- package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +2 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +171 -2
- package/payload/platform/plugins/cloudflare/bin/__tests__/portal-brand-css.test.sh +139 -0
- package/payload/platform/plugins/cloudflare/bin/portal-brand-css.mjs +128 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-enrol.test.ts +1 -1
- package/payload/platform/plugins/cloudflare/mcp/__tests__/skill-contract.test.ts +25 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/template-config.test.ts +55 -3
- package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +38 -3
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/{public/portal.css → portal.css} +13 -2
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/wrangler.toml +1 -1
- package/payload/platform/plugins/docs/references/admin-ui.md +48 -0
- package/payload/platform/plugins/docs/references/google-guide.md +68 -0
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/docs/references/ledger.md +43 -0
- package/payload/platform/plugins/email/PLUGIN.md +4 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/display-truncation.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/display-truncation.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/display-truncation.test.js +196 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/display-truncation.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.js +10 -8
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/truncation-tool-output.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/truncation-tool-output.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/truncation-tool-output.test.js +110 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/truncation-tool-output.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +22 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +90 -36
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.js +6 -2
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.js +6 -2
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.js.map +1 -1
- package/payload/platform/plugins/email/skills/email-ingest/SKILL.md +4 -0
- package/payload/platform/plugins/google/.claude-plugin/plugin.json +21 -0
- package/payload/platform/plugins/google/PLUGIN.md +104 -0
- package/payload/platform/plugins/google/lib/mcp-spawn-tee/index.js +193 -0
- package/payload/platform/plugins/google/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js +60 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/calendar-tools.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/calendar-tools.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/calendar-tools.test.js +48 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/calendar-tools.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.js +25 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.js +40 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/pending-store.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/pending-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/pending-store.test.js +35 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/pending-store.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/token-store.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/token-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/token-store.test.js +85 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/token-store.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts +25 -0
- package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/auth/pending-store.js +87 -0
- package/payload/platform/plugins/google/mcp/dist/auth/pending-store.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/auth/token-store.d.ts +46 -0
- package/payload/platform/plugins/google/mcp/dist/auth/token-store.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/auth/token-store.js +138 -0
- package/payload/platform/plugins/google/mcp/dist/auth/token-store.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/index.d.ts +25 -0
- package/payload/platform/plugins/google/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/index.js +300 -0
- package/payload/platform/plugins/google/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.d.ts +28 -0
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.js +102 -0
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/lib/log.d.ts +3 -0
- package/payload/platform/plugins/google/mcp/dist/lib/log.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/lib/log.js +16 -0
- package/payload/platform/plugins/google/mcp/dist/lib/log.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-info.d.ts +12 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-info.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-info.js +23 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-info.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-list.d.ts +12 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-list.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-list.js +9 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-list.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts +42 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.js +102 -0
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-cancel.d.ts +10 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-cancel.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-cancel.js +9 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-cancel.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-create.d.ts +20 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-create.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-create.js +25 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-create.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-event.d.ts +6 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-event.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-event.js +7 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-event.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-freebusy.d.ts +14 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-freebusy.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-freebusy.js +16 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-freebusy.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-list.d.ts +44 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-list.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-list.js +36 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-list.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-respond.d.ts +16 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-respond.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-respond.js +29 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-respond.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-update.d.ts +16 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-update.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-update.js +32 -0
- package/payload/platform/plugins/google/mcp/dist/tools/calendar-update.js.map +1 -0
- package/payload/platform/plugins/google/mcp/package.json +20 -0
- package/payload/platform/plugins/google/references/auth.md +35 -0
- package/payload/platform/plugins/ledger/.claude-plugin/plugin.json +21 -0
- package/payload/platform/plugins/ledger/PLUGIN.md +82 -0
- package/payload/platform/plugins/ledger/lib/mcp-spawn-tee/index.js +193 -0
- package/payload/platform/plugins/ledger/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/ledger/mcp/dist/index.d.ts +2 -0
- package/payload/platform/plugins/ledger/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/index.js +168 -0
- package/payload/platform/plugins/ledger/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/ids.d.ts +4 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/ids.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/ids.js +0 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/ids.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/neo4j.d.ts +5 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/neo4j.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/neo4j.js +40 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/neo4j.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.d.ts +29 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.js +138 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.d.ts +47 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.js +14 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/balance.d.ts +18 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/balance.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/balance.js +23 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/balance.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.d.ts +26 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.js +33 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.d.ts +27 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.js +40 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.d.ts +46 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.js +68 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.d.ts +20 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.js +30 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/statement.d.ts +26 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/statement.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/statement.js +35 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/statement.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/package.json +21 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/ledger-vertical-coverage.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/ledger-vertical-coverage.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/ledger-vertical-coverage.test.js +81 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/ledger-vertical-coverage.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.d.ts +9 -7
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js +10 -8
- package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js.map +1 -1
- package/payload/platform/plugins/memory/references/schema-base.md +22 -0
- package/payload/platform/plugins/memory/references/schema-construction.md +0 -18
- package/payload/platform/plugins/scheduling/PLUGIN.md +20 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.js +11 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +3 -3
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts +138 -0
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js +268 -0
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +20 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +6 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +42 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +10 -1
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts +80 -6
- package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-census.js +96 -20
- package/payload/platform/services/claude-session-manager/dist/pty-census.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js.map +1 -1
- package/payload/platform/templates/specialists/agents/database-operator.md +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
- package/payload/server/{chunk-POBXIHOF.js → chunk-BSTIQX52.js} +59 -1
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/activity.html +17 -0
- package/payload/server/public/assets/AdminLoginScreens-Rf94VD9w.js +1 -0
- package/payload/server/public/assets/AdminShell-CyGKg7MG.js +2 -0
- package/payload/server/public/assets/Checkbox-B0jmI2y2.js +1 -0
- package/payload/server/public/assets/HeaderMenu-BnTYGNaB.js +9 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-pu0jjLCz.css → HeaderMenu-DtIEBHOU.css} +1 -1
- package/payload/server/public/assets/activity-BOBTWFr-.js +1 -0
- package/payload/server/public/assets/admin-HDLzwbLl.js +1 -0
- package/payload/server/public/assets/{arc-qKfXIt8v.js → arc-CFMJyMm-.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Cypt5qHL.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DkVrGn7G.js → architectureDiagram-Q4EWVU46-CmOpXLsH.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DqavswGH.js → blockDiagram-DXYQGD6D-CmS8f9YF.js} +1 -1
- package/payload/server/public/assets/browser-D4_XLSSm.js +1 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-B7fyKiXe.js → c4Diagram-AHTNJAMY-BXIjMl6A.js} +1 -1
- package/payload/server/public/assets/calendar-s5V_gbI7.js +1 -0
- package/payload/server/public/assets/channel-DhrFAm7m.js +1 -0
- package/payload/server/public/assets/chat-40WyKzGb.js +1 -0
- package/payload/server/public/assets/chevron-left-C35qGP5f.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-DsgMtGkv.js → chunk-2KRD3SAO-D4fktAwW.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-CkdISfNt.js → chunk-336JU56O-C2MKnRTj.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-BhU7-TyS.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-CYpiF2bl.js → chunk-4BX2VUAB-C13Wz3zS.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CWyc_F7v.js → chunk-4TB4RGXK-CalYahTR.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-BbzKMw2Z.js → chunk-55IACEB6-TmOKdy8a.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-u19Nai9e.js → chunk-5FUZZQ4R-C-i0BVag.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-Ba8by6Uy.js → chunk-5PVQY5BW-D6bJMLnf.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-BwUuxtyb.js → chunk-67CJDMHE-Cif9Uu5C.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-BRH9iM9L.js → chunk-7N4EOEYR-WjTHCXnd.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-BGoztgLL.js → chunk-AA7GKIK3-CwCfdQmb.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-C5GDAZTl.js → chunk-BSJP7CBP-9A67yXwT.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-ChY32VPS.js → chunk-CIAEETIT-DPMiWSBi.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-CPSD3p6p.js → chunk-EDXVE4YY-B9PBdwiT.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-D1oL-iUr.js → chunk-ENJZ2VHE-CM5OqcQ5.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-CPvYEr54.js → chunk-FMBD7UC4-Bmt_ZRlV.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-9Yyj7Vbz.js → chunk-FOC6F5B3-DfGJGxpX.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-BaYgh8FR.js → chunk-ICPOFSXX-D6M89DA0.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-5ucpeRvm.js → chunk-K5T4RW27-DMpoaqw2.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-DW-FHk7T.js → chunk-KGLVRYIC-DYUFgri2.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-CGGVfAyG.js → chunk-LIHQZDEY-x3LmeKmx.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-Bv8EUa5d.js → chunk-ORNJ4GCN-BeuNAWkW.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-C1mXJnyw.js → chunk-OYMX7WX6-Bv6gisQ6.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-7_kS3RBy.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-PwSQz6EP.js → chunk-U2HBQHQK-C2iT9Av2.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP--NPHTBlU.js → chunk-X2U36JSP-Bd6bv87A.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-Bbc7Da32.js → chunk-XPW4576I-ByFnN4JO.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-D-9v8e--.js → chunk-YZCP3GAM-Bt8I6ZDb.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-CMPg670Q.js → chunk-ZZ45TVLE-DBMPgZ_A.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BrWqm88p.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D0wzG5Fd.js +1 -0
- package/payload/server/public/assets/clone-DQA-nNrl.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-NVSb1Bhy.js → cose-bilkent-S5V4N54A-DgLEaApT.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-V2Ai1DFl.js → dagre-KV5264BT-kWVPgmmL.js} +1 -1
- package/payload/server/public/assets/{dagre-QfLcO-1j.js → dagre-mSazqXgG.js} +1 -1
- package/payload/server/public/assets/data-Bq0vU3qJ.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-Caw21693.js → diagram-5BDNPKRD-BHe_omJD.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-CgwVkT2q.js → diagram-G4DWMVQ6-fUFsmM3x.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DFUrLZhs.js → diagram-MMDJMWI5-DmujPLlM.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CEEiEuZJ.js → diagram-TYMM5635-B7Aoas89.js} +1 -1
- package/payload/server/public/assets/{dist-Cvgxm7qv.js → dist-C9D_xz81.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-CG10NrT3.js → erDiagram-SMLLAGMA-6hS1rGiO.js} +1 -1
- package/payload/server/public/assets/{flatten-DAO0sfCM.js → flatten-BXzaHgtL.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BqkV9Okv.js → flowDiagram-DWJPFMVM-Bqhr_r5b.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DRiCDQF6.js → ganttDiagram-T4ZO3ILL-B8kjyN4o.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-C_-XjxLd.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BZV2voyy.js → gitGraphDiagram-UUTBAWPF--TTRq4ir.js} +1 -1
- package/payload/server/public/assets/{graph-BZiudUGr.js → graph-C252ZHjp.js} +3 -3
- package/payload/server/public/assets/graph-labels-DzPbbhLc.js +1 -0
- package/payload/server/public/assets/{graphlib-DGPThX8M.js → graphlib-CWkjawc5.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BH8yDCfL.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-D8U4M0pK.js +2 -0
- package/payload/server/public/assets/{isEmpty-Cb_U81C6.js → isEmpty-uB1dEu_Z.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-BKsAxSvp.js → ishikawaDiagram-UXIWVN3A-CR8B7VzM.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CmliuOd-.js → journeyDiagram-VCZTEJTY-45lWAvtq.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DAlElMb-.js → kanban-definition-6JOO6SKY-DkrPXLVb.js} +1 -1
- package/payload/server/public/assets/{line-DKZqLKAC.js → line-Db0H446a.js} +1 -1
- package/payload/server/public/assets/{linear-CbSGdh1x.js → linear-X3O7lwK3.js} +1 -1
- package/payload/server/public/assets/maximize-2-CEbXFpQT.js +1 -0
- package/payload/server/public/assets/{mermaid-parser.core-DFvbao9C.js → mermaid-parser.core-CixBHOya.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-C0vEBxDm.js → mermaid.core-BGQq98L7.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CShASUKd.js → mindmap-definition-QFDTVHPH-v9cJl1mj.js} +1 -1
- package/payload/server/public/assets/operator-zKk4HMdX.js +1 -0
- package/payload/server/public/assets/{ordinal-H0tVmBDP.js → ordinal-CZY9laxg.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Bajcns4r.js +1 -0
- package/payload/server/public/assets/page-BrmN_vzV.js +1 -0
- package/payload/server/public/assets/page-Cts-ESBe.js +32 -0
- package/payload/server/public/assets/{pdf-render-jAQU0nXt.js → pdf-render-7HZBTZ0_.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-D7hjM5w1.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CBZHpDAJ.js → pieDiagram-DEJITSTG-DQ0b6edX.js} +1 -1
- package/payload/server/public/assets/public-BItzHBc0.js +1 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-n3bB3K91.js → quadrantDiagram-34T5L4WZ-B64mj7Ei.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-B46d5x7a.js +1 -0
- package/payload/server/public/assets/{reduce-DAvwat-a.js → reduce-BGQzAenn.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DiDvQK3c.js → requirementDiagram-MS252O5E-CE2JIEWo.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-B0EYGhGx.js +1 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DWDQQZmd.js → sankeyDiagram-XADWPNL6-Cmt5cfCz.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DmAqRlBT.js → sequenceDiagram-FGHM5R23-B5vVn_sw.js} +1 -1
- package/payload/server/public/assets/{src-DV4LKv2E.js → src-BTKk8KAG.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-D4R-n6bZ.js → stateDiagram-FHFEXIEX-DiUEJ-RZ.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DIm3XuAD.js +1 -0
- package/payload/server/public/assets/tasks-ClE8-be8.js +1 -0
- package/payload/server/public/assets/time-entry-format-BwjGLnXu.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CjiHGP4l.js → timeline-definition-GMOUNBTQ-C9jprDVw.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-3XQh5xQ1.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DwR-_l5z.js +1 -0
- package/payload/server/public/assets/triangle-alert-DejWYn1x.js +1 -0
- package/payload/server/public/assets/useCopyFeedback-CpSgOavK.js +1 -0
- package/payload/server/public/assets/useSelectionMode-ZQZQUgze.js +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DuRLvCfO.js +1 -0
- package/payload/server/public/assets/useVoiceRecorder-BTYYeUJW.js +2 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CBdDQ7c-.js → vennDiagram-DHZGUBPP-DWqQJ9X0.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DZp9oCGv.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BlIQPKLb.js → wardleyDiagram-NUSXRM2D-Dg6c2Voh.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CslKgh9B.js → xychartDiagram-5P7HB3ND-EhN-zeDj.js} +1 -1
- package/payload/server/public/browser.html +7 -6
- package/payload/server/public/calendar.html +8 -7
- package/payload/server/public/chat.html +15 -14
- package/payload/server/public/data.html +14 -12
- package/payload/server/public/graph.html +13 -12
- package/payload/server/public/index.html +17 -15
- package/payload/server/public/operator.html +17 -16
- package/payload/server/public/public.html +15 -14
- package/payload/server/public/tasks.html +7 -6
- package/payload/server/server.js +1064 -536
- package/payload/server/public/assets/AdminLoginScreens-Bed8SDxY.js +0 -1
- package/payload/server/public/assets/AdminShell-BLh9O6dn.js +0 -2
- package/payload/server/public/assets/Checkbox-BC_KSbpS.js +0 -1
- package/payload/server/public/assets/admin-DfWgJVI3.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-FPHT7s-C.js +0 -1
- package/payload/server/public/assets/browser-C0vkv-hH.js +0 -1
- package/payload/server/public/assets/calendar-_pfHw0Hp.js +0 -1
- package/payload/server/public/assets/channel-j70eMvcL.js +0 -1
- package/payload/server/public/assets/chat-DYT5H81o.js +0 -1
- package/payload/server/public/assets/chevron-left-BnpVBu51.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-D-NcAlTW.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CAwbQBtf.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Ct6Rn0vt.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B_2XCIFv.js +0 -1
- package/payload/server/public/assets/clone-DjPWA_NH.js +0 -1
- package/payload/server/public/assets/data-CR-fbPWr.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-B8Hx7f-D.js +0 -1
- package/payload/server/public/assets/graph-labels-BzmmJwCR.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-BicCJTqU.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-tf-8rOez.js +0 -2
- package/payload/server/public/assets/maximize-2-Bhdsv0U-.js +0 -1
- package/payload/server/public/assets/operator-gm2eP4r6.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Ckn_5hq0.js +0 -1
- package/payload/server/public/assets/page-8AB3jUa_.js +0 -1
- package/payload/server/public/assets/page-BoPorLg-.js +0 -32
- package/payload/server/public/assets/pie-ZZUOXDRM-DzlGQW3J.js +0 -1
- package/payload/server/public/assets/public-DqJk6qgW.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-BHo2YD8b.js +0 -1
- package/payload/server/public/assets/rotate-ccw-D_5cETGt.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BcFRbGRu.js +0 -1
- package/payload/server/public/assets/tasks-EyKLXINi.js +0 -1
- package/payload/server/public/assets/time-entry-format-DAwmmR3i.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-BtRr5vXp.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-D8p0sbyo.js +0 -1
- package/payload/server/public/assets/useCopyFeedback-rOWd_lzl.js +0 -1
- package/payload/server/public/assets/useSelectionMode-DDmLmPph.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CU-lOxTd.js +0 -9
- package/payload/server/public/assets/useVoiceRecorder-azG8zSUI.js +0 -2
- package/payload/server/public/assets/wardley-RL74JXVD-DgMn-9ZJ.js +0 -1
- /package/payload/platform/plugins/cloudflare/skills/data-portal/{template/schema.sql → schema.sql} +0 -0
- /package/payload/platform/plugins/cloudflare/skills/data-portal/template/{public/index.html → index.html} +0 -0
- /package/payload/platform/plugins/cloudflare/skills/data-portal/template/{public/portal.js → portal.js} +0 -0
- /package/payload/server/public/assets/{_baseFor-D3BqAOBr.js → _baseFor-CMWvz0uA.js} +0 -0
- /package/payload/server/public/assets/{array-iYP9fzJp.js → array-Cny_NT6T.js} +0 -0
- /package/payload/server/public/assets/{chunk-Ck5AOu5v.js → chunk-TPjIAO9U.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-BQSBzPsB.js → cytoscape.esm-De0CCmB2.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-BrdA1gDi.js → defaultLocale-BahRht8U.js} +0 -0
- /package/payload/server/public/assets/{init-Bx0S6pkp.js → init-DoIvjoJ_.js} +0 -0
- /package/payload/server/public/assets/{katex-BsiH_a6d.js → katex-Bfn1OZEl.js} +0 -0
- /package/payload/server/public/assets/{path-BLSgTy3w.js → path-CTezU8L5.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-ClBMtM1g.js → preload-helper-CT1Z6Pdu.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-BMOtDaaS.js → rough.esm-BJo4pvXu.js} +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @maxy/google MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Live Google Calendar for one account: read plus create, update, cancel,
|
|
6
|
+
* respond and free/busy. Admin agent only; no public surface.
|
|
7
|
+
*
|
|
8
|
+
* Auth: per-account OAuth authorization-code + PKCE. The consent URL is minted
|
|
9
|
+
* here; the exchange happens in platform/ui, which holds the house-only
|
|
10
|
+
* client secret. Tokens persist encrypted to
|
|
11
|
+
* {ACCOUNTS_DIR}/{accountId}/secrets/google/accounts/{email}/tokens.enc
|
|
12
|
+
*
|
|
13
|
+
* There is deliberately no Gmail surface — mail runs on the `email` plugin's
|
|
14
|
+
* IMAP/SMTP path, and Gmail's restricted scopes would force Google's annual
|
|
15
|
+
* security assessment. Calendar is a sensitive scope only.
|
|
16
|
+
*
|
|
17
|
+
* Required environment:
|
|
18
|
+
* ACCOUNT_ID — provided by getMcpServers when spawned per account.
|
|
19
|
+
* PLATFORM_ROOT — repo root; used to derive ACCOUNTS_DIR.
|
|
20
|
+
* GOOGLE_CLIENT_ID — brand.json#googleClientId. Operator-set per brand.
|
|
21
|
+
* GOOGLE_PUBLIC_BASE — https origin of this install's public host.
|
|
22
|
+
* MAXY_UI_INTERNAL_PORT — loopback port of platform/ui (holds the secret).
|
|
23
|
+
*/
|
|
24
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
25
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
26
|
+
import { resolve, join } from "node:path";
|
|
27
|
+
import { existsSync } from "node:fs";
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
import { TokenStore } from "./auth/token-store.js";
|
|
30
|
+
import { log } from "./lib/log.js";
|
|
31
|
+
import { runAccountRegisterStart, runAccountRegisterPoll, listConnected, } from "./tools/account-register.js";
|
|
32
|
+
import { runCalendarList } from "./tools/calendar-list.js";
|
|
33
|
+
import { runCalendarEvent } from "./tools/calendar-event.js";
|
|
34
|
+
import { runCalendarCreate } from "./tools/calendar-create.js";
|
|
35
|
+
import { runCalendarUpdate } from "./tools/calendar-update.js";
|
|
36
|
+
import { runCalendarCancel } from "./tools/calendar-cancel.js";
|
|
37
|
+
import { runCalendarRespond } from "./tools/calendar-respond.js";
|
|
38
|
+
import { runCalendarFreebusy } from "./tools/calendar-freebusy.js";
|
|
39
|
+
import { runAccountInfo } from "./tools/account-info.js";
|
|
40
|
+
import { runAccountList } from "./tools/account-list.js";
|
|
41
|
+
import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
|
|
42
|
+
// Plugin-system boot tolerance — see Task 202. Module init must never exit;
|
|
43
|
+
// the plugin-system spawn enumerates tools/list before any per-account env is
|
|
44
|
+
// set. Per-call refusal preserves isolation without emptying the registry.
|
|
45
|
+
const ACCOUNT_ID = process.env.ACCOUNT_ID ?? null;
|
|
46
|
+
const PLATFORM_ROOT = process.env.PLATFORM_ROOT ?? process.cwd();
|
|
47
|
+
const ACCOUNTS_DIR = resolve(PLATFORM_ROOT, "..", "data/accounts");
|
|
48
|
+
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID ?? "";
|
|
49
|
+
const GOOGLE_PUBLIC_BASE = process.env.GOOGLE_PUBLIC_BASE ?? "";
|
|
50
|
+
// The loopback UI port is per-brand and already on the spawn env. A guessed
|
|
51
|
+
// default would be a brand-isolation hazard on a co-resident host: brand A
|
|
52
|
+
// would POST its refresh to brand B's server, which would service it with
|
|
53
|
+
// brand B's house client secret. Unset is refused per call, never defaulted.
|
|
54
|
+
const UI_INTERNAL_PORT = process.env.MAXY_UI_INTERNAL_PORT ?? "";
|
|
55
|
+
// Presence is checked before register; the contents are never read here.
|
|
56
|
+
const HOUSE_ENV_PATH = join(PLATFORM_ROOT, "config", "google-house.env");
|
|
57
|
+
// Standing per-boot reconciliation of expected (brand.json googleClientId,
|
|
58
|
+
// stamped onto the session-manager env) vs actual. clientIdConfigured=false on
|
|
59
|
+
// a brand that ships a value is the mis-stamp signature.
|
|
60
|
+
process.stderr.write(`[google-mcp] boot accountId=${ACCOUNT_ID ?? "null"} clientIdConfigured=${GOOGLE_CLIENT_ID ? "true" : "false"} publicBaseConfigured=${GOOGLE_PUBLIC_BASE ? "true" : "false"} uiPortConfigured=${UI_INTERNAL_PORT ? "true" : "false"} houseSecretPresent=${existsSync(HOUSE_ENV_PATH) ? "true" : "false"}\n`);
|
|
61
|
+
function refuseNoAccount(toolName) {
|
|
62
|
+
process.stderr.write(`[google-mcp] tool=${toolName} refuse reason=no-account-context\n`);
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `${toolName} cannot execute: this MCP instance was launched without ACCOUNT_ID (plugin-system metadata-only mode). Per-account access requires ACCOUNT_ID at spawn.`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function ok(payload) {
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: typeof payload === "string" ? payload : JSON.stringify(payload, null, 2),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function fail(message) {
|
|
84
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
85
|
+
}
|
|
86
|
+
/** Optional account selector. One Maxy account can hold several Google
|
|
87
|
+
* accounts; omit when there is one, name it when there are more. */
|
|
88
|
+
const accountArg = z
|
|
89
|
+
.string()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Target Google account (its email address). Omit when a single Google account is connected. With two or more, omitting it returns a refusal listing them; call google-account-list to see them.");
|
|
92
|
+
/**
|
|
93
|
+
* Resolve a config for the named or sole connected Google account. Resolution
|
|
94
|
+
* order: explicit `account` -> the sole connected account -> a typed refusal
|
|
95
|
+
* naming the candidates. Every resolution logs one cred-resolve line, so a
|
|
96
|
+
* wrong or absent selector is diagnosable from that line alone.
|
|
97
|
+
*/
|
|
98
|
+
function getConfig(account) {
|
|
99
|
+
if (!ACCOUNT_ID)
|
|
100
|
+
throw new Error("getConfig() called without ACCOUNT_ID — handler guard missing");
|
|
101
|
+
if (!GOOGLE_CLIENT_ID) {
|
|
102
|
+
throw new Error("GOOGLE_CLIENT_ID is not configured for this brand; google tools are inert until a vendor app exists.");
|
|
103
|
+
}
|
|
104
|
+
const connected = listConnected(ACCOUNT_ID, ACCOUNTS_DIR);
|
|
105
|
+
let key;
|
|
106
|
+
if (account) {
|
|
107
|
+
key = account;
|
|
108
|
+
}
|
|
109
|
+
else if (connected.length === 1) {
|
|
110
|
+
key = connected[0].email;
|
|
111
|
+
}
|
|
112
|
+
else if (connected.length === 0) {
|
|
113
|
+
throw new Error("no Google account connected for this account; run google-account-register");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
throw new Error(`two or more Google accounts are connected (${connected.map((c) => c.email).join(", ")}); name one with the account argument`);
|
|
117
|
+
}
|
|
118
|
+
log({
|
|
119
|
+
tag: "[google-mcp]",
|
|
120
|
+
op: "cred-resolve",
|
|
121
|
+
account: ACCOUNT_ID,
|
|
122
|
+
target: key,
|
|
123
|
+
source: account ? "arg" : "sole",
|
|
124
|
+
});
|
|
125
|
+
if (!UI_INTERNAL_PORT) {
|
|
126
|
+
throw new Error("MAXY_UI_INTERNAL_PORT is not set; the token-refresh endpoint cannot be addressed without it. Refusing rather than guessing a port, which on a co-resident host would reach another brand's server.");
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
accountId: ACCOUNT_ID,
|
|
130
|
+
clientId: GOOGLE_CLIENT_ID,
|
|
131
|
+
store: new TokenStore(ACCOUNT_ID, ACCOUNTS_DIR, key),
|
|
132
|
+
refreshEndpoint: `http://127.0.0.1:${UI_INTERNAL_PORT}/api/google/oauth/refresh`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const server = new McpServer({ name: "google", version: "0.1.0" });
|
|
136
|
+
lifelineTool(server, "google-account-register", "Start connecting a Google Calendar for this account. Returns a consent URL immediately — relay it to the user, who opens it on any device, signs in and approves. Then call google-account-register-poll to confirm. Does NOT block. Refuses while another registration is already live.", {}, async () => {
|
|
137
|
+
if (!ACCOUNT_ID)
|
|
138
|
+
return refuseNoAccount("google-account-register");
|
|
139
|
+
try {
|
|
140
|
+
if (!GOOGLE_CLIENT_ID) {
|
|
141
|
+
return fail("GOOGLE_CLIENT_ID is not configured for this brand; google tools are inert until a vendor app exists.");
|
|
142
|
+
}
|
|
143
|
+
if (!GOOGLE_PUBLIC_BASE) {
|
|
144
|
+
return fail("GOOGLE_PUBLIC_BASE is not configured; the consent redirect cannot be built without this install's public host.");
|
|
145
|
+
}
|
|
146
|
+
// Pre-flight the house secret by PRESENCE ONLY — never read, the secret
|
|
147
|
+
// must not enter this process. Without this the operator discovers the
|
|
148
|
+
// gap only at the callback, i.e. after they have already consented, and
|
|
149
|
+
// the failure looks like a broken flow rather than a missing file.
|
|
150
|
+
if (!existsSync(HOUSE_ENV_PATH)) {
|
|
151
|
+
return fail(`The Google client secret is not installed on this device. Create ${HOUSE_ENV_PATH} (mode 600) containing GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from the brand's Google Cloud OAuth client, then try again. Without it the consent flow completes and then fails at the final step.`);
|
|
152
|
+
}
|
|
153
|
+
const res = await runAccountRegisterStart({
|
|
154
|
+
accountId: ACCOUNT_ID,
|
|
155
|
+
accountsDir: ACCOUNTS_DIR,
|
|
156
|
+
clientId: GOOGLE_CLIENT_ID,
|
|
157
|
+
publicBase: GOOGLE_PUBLIC_BASE,
|
|
158
|
+
});
|
|
159
|
+
return ok(res);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
return fail(`google-account-register failed: ${err.message}`);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
lifelineTool(server, "google-account-register-poll", "Report the state of a Google Calendar registration for this account: registered, pending, expired, or none. Reads local stores only — no network call.", {}, async () => {
|
|
166
|
+
if (!ACCOUNT_ID)
|
|
167
|
+
return refuseNoAccount("google-account-register-poll");
|
|
168
|
+
try {
|
|
169
|
+
return ok(await runAccountRegisterPoll({ accountId: ACCOUNT_ID, accountsDir: ACCOUNTS_DIR }));
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
return fail(`google-account-register-poll failed: ${err.message}`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
lifelineTool(server, "google-calendar-list", "List calendar events in the next rangeDays days (default 7, max 365). Returns id, summary, start, end, location, attendees, allDay, organizer, htmlLink. Recurring series are expanded into instances.", {
|
|
176
|
+
rangeDays: z.number().int().min(1).max(365).optional(),
|
|
177
|
+
maxResults: z.number().int().min(1).max(250).optional(),
|
|
178
|
+
account: accountArg,
|
|
179
|
+
}, async ({ rangeDays, maxResults, account }) => {
|
|
180
|
+
if (!ACCOUNT_ID)
|
|
181
|
+
return refuseNoAccount("google-calendar-list");
|
|
182
|
+
try {
|
|
183
|
+
return ok(await runCalendarList(getConfig(account), { rangeDays, maxResults }));
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
return fail(`google-calendar-list failed: ${err.message}`);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
lifelineTool(server, "google-calendar-event", "Fetch a single calendar event by id.", { eventId: z.string().min(1), account: accountArg }, async ({ eventId, account }) => {
|
|
190
|
+
if (!ACCOUNT_ID)
|
|
191
|
+
return refuseNoAccount("google-calendar-event");
|
|
192
|
+
try {
|
|
193
|
+
return ok(await runCalendarEvent(getConfig(account), { eventId }));
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
return fail(`google-calendar-event failed: ${err.message}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
lifelineTool(server, "google-calendar-create", "Create a calendar event. Times are RFC3339 (2026-07-20T09:00:00Z) unless allDay is true, in which case they are dates (2026-07-20). Attendees are notified.", {
|
|
200
|
+
summary: z.string().min(1),
|
|
201
|
+
start: z.string().min(1),
|
|
202
|
+
end: z.string().min(1),
|
|
203
|
+
location: z.string().optional(),
|
|
204
|
+
description: z.string().optional(),
|
|
205
|
+
attendees: z.array(z.string()).optional(),
|
|
206
|
+
allDay: z.boolean().optional(),
|
|
207
|
+
account: accountArg,
|
|
208
|
+
}, async ({ account, ...args }) => {
|
|
209
|
+
if (!ACCOUNT_ID)
|
|
210
|
+
return refuseNoAccount("google-calendar-create");
|
|
211
|
+
try {
|
|
212
|
+
return ok(await runCalendarCreate(getConfig(account), args));
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
return fail(`google-calendar-create failed: ${err.message}`);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
lifelineTool(server, "google-calendar-update", "Update an existing calendar event. Only the fields you name are changed; omitted fields are left as they are. Attendees are notified.", {
|
|
219
|
+
eventId: z.string().min(1),
|
|
220
|
+
summary: z.string().optional(),
|
|
221
|
+
start: z.string().optional(),
|
|
222
|
+
end: z.string().optional(),
|
|
223
|
+
location: z.string().optional(),
|
|
224
|
+
description: z.string().optional(),
|
|
225
|
+
attendees: z.array(z.string()).optional(),
|
|
226
|
+
allDay: z.boolean().optional(),
|
|
227
|
+
account: accountArg,
|
|
228
|
+
}, async ({ account, ...args }) => {
|
|
229
|
+
if (!ACCOUNT_ID)
|
|
230
|
+
return refuseNoAccount("google-calendar-update");
|
|
231
|
+
try {
|
|
232
|
+
return ok(await runCalendarUpdate(getConfig(account), args));
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
return fail(`google-calendar-update failed: ${err.message}`);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
lifelineTool(server, "google-calendar-cancel", "Cancel (delete) a calendar event by id. Attendees are notified.", { eventId: z.string().min(1), account: accountArg }, async ({ eventId, account }) => {
|
|
239
|
+
if (!ACCOUNT_ID)
|
|
240
|
+
return refuseNoAccount("google-calendar-cancel");
|
|
241
|
+
try {
|
|
242
|
+
return ok(await runCalendarCancel(getConfig(account), { eventId }));
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
return fail(`google-calendar-cancel failed: ${err.message}`);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
lifelineTool(server, "google-calendar-respond", "Respond to an invitation on behalf of the connected account: accepted, declined or tentative. Every other attendee's response is left untouched.", {
|
|
249
|
+
eventId: z.string().min(1),
|
|
250
|
+
response: z.enum(["accepted", "declined", "tentative"]),
|
|
251
|
+
account: accountArg,
|
|
252
|
+
}, async ({ eventId, response, account }) => {
|
|
253
|
+
if (!ACCOUNT_ID)
|
|
254
|
+
return refuseNoAccount("google-calendar-respond");
|
|
255
|
+
try {
|
|
256
|
+
return ok(await runCalendarRespond(getConfig(account), { eventId, response }));
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
return fail(`google-calendar-respond failed: ${err.message}`);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
lifelineTool(server, "google-calendar-freebusy", "Busy blocks between start and end (RFC3339) for the account's own calendar, or for the calendar ids you name. Free time is the complement.", {
|
|
263
|
+
start: z.string().min(1),
|
|
264
|
+
end: z.string().min(1),
|
|
265
|
+
calendars: z.array(z.string()).optional(),
|
|
266
|
+
account: accountArg,
|
|
267
|
+
}, async ({ start, end, calendars, account }) => {
|
|
268
|
+
if (!ACCOUNT_ID)
|
|
269
|
+
return refuseNoAccount("google-calendar-freebusy");
|
|
270
|
+
try {
|
|
271
|
+
return ok(await runCalendarFreebusy(getConfig(account), { start, end, calendars }));
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
return fail(`google-calendar-freebusy failed: ${err.message}`);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
lifelineTool(server, "google-account-info", "Auth state for one connected Google account: connected, whether its access token is near expiry, and the granted scopes. Local stores only.", { email: z.string().min(1) }, async ({ email }) => {
|
|
278
|
+
if (!ACCOUNT_ID)
|
|
279
|
+
return refuseNoAccount("google-account-info");
|
|
280
|
+
try {
|
|
281
|
+
return ok(runAccountInfo({ accountId: ACCOUNT_ID, accountsDir: ACCOUNTS_DIR, email }));
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
return fail(`google-account-info failed: ${err.message}`);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
lifelineTool(server, "google-account-list", "Every Google account connected to this account, each with its own status. Local stores only, no network. A count alone is not 'connected' — check each status.", {}, async () => {
|
|
288
|
+
if (!ACCOUNT_ID)
|
|
289
|
+
return refuseNoAccount("google-account-list");
|
|
290
|
+
try {
|
|
291
|
+
return ok(runAccountList({ accountId: ACCOUNT_ID, accountsDir: ACCOUNTS_DIR }));
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
return fail(`google-account-list failed: ${err.message}`);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
const transport = new StdioServerTransport();
|
|
298
|
+
await server.connect(transport);
|
|
299
|
+
process.stderr.write(`[google-mcp] ready account=${ACCOUNT_ID ?? "null"}\n`);
|
|
300
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authenticated access to Google Calendar API v3.
|
|
3
|
+
*
|
|
4
|
+
* Refresh is delegated to platform/ui rather than performed here. A
|
|
5
|
+
* Web-application OAuth client must present its client_secret at Google's
|
|
6
|
+
* token endpoint, and that secret is house-only (${PLATFORM_ROOT}/config/
|
|
7
|
+
* google-house.env) — it must never reach a per-account MCP spawn. The server
|
|
8
|
+
* holds it and exposes POST /api/google/oauth/refresh for this purpose.
|
|
9
|
+
*/
|
|
10
|
+
import { TokenStore, type TokenBlob } from "../auth/token-store.js";
|
|
11
|
+
export interface GoogleConfig {
|
|
12
|
+
accountId: string;
|
|
13
|
+
clientId: string;
|
|
14
|
+
store: TokenStore;
|
|
15
|
+
/** Loopback URL of the platform/ui route that holds the client secret. */
|
|
16
|
+
refreshEndpoint: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildQuery(q: Record<string, string | number | undefined>): string;
|
|
19
|
+
export declare function isExpiring(blob: TokenBlob): boolean;
|
|
20
|
+
export declare function callCalendar<T>(config: GoogleConfig, path: string, init?: {
|
|
21
|
+
method?: string;
|
|
22
|
+
body?: unknown;
|
|
23
|
+
query?: Record<string, string | number | undefined>;
|
|
24
|
+
}): Promise<T>;
|
|
25
|
+
/** The primary calendar's id IS the account's email address. Used instead of a
|
|
26
|
+
* userinfo call, because the identity scopes are deliberately not requested. */
|
|
27
|
+
export declare function resolvePrimaryEmail(config: GoogleConfig): Promise<string>;
|
|
28
|
+
//# sourceMappingURL=google-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-client.d.ts","sourceRoot":"","sources":["../../src/lib/google-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAwB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAK1F,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAOjF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEnD;AA6CD,wBAAsB,YAAY,CAAC,CAAC,EAClC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CAChD,GACL,OAAO,CAAC,CAAC,CAAC,CA8BZ;AAED;iFACiF;AACjF,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authenticated access to Google Calendar API v3.
|
|
3
|
+
*
|
|
4
|
+
* Refresh is delegated to platform/ui rather than performed here. A
|
|
5
|
+
* Web-application OAuth client must present its client_secret at Google's
|
|
6
|
+
* token endpoint, and that secret is house-only (${PLATFORM_ROOT}/config/
|
|
7
|
+
* google-house.env) — it must never reach a per-account MCP spawn. The server
|
|
8
|
+
* holds it and exposes POST /api/google/oauth/refresh for this purpose.
|
|
9
|
+
*/
|
|
10
|
+
import { REFRESH_THRESHOLD_MS } from "../auth/token-store.js";
|
|
11
|
+
import { log } from "./log.js";
|
|
12
|
+
const CALENDAR_BASE = "https://www.googleapis.com/calendar/v3";
|
|
13
|
+
export function buildQuery(q) {
|
|
14
|
+
const parts = [];
|
|
15
|
+
for (const [k, v] of Object.entries(q)) {
|
|
16
|
+
if (v === undefined)
|
|
17
|
+
continue;
|
|
18
|
+
parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
|
|
19
|
+
}
|
|
20
|
+
return parts.length ? `?${parts.join("&")}` : "";
|
|
21
|
+
}
|
|
22
|
+
export function isExpiring(blob) {
|
|
23
|
+
return blob.accessTokenExpiry - Date.now() <= REFRESH_THRESHOLD_MS;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Refresh through platform/ui. An IO or HTTP failure here NEVER clears held
|
|
27
|
+
* tokens — it throws, leaving the store untouched, so a transient outage
|
|
28
|
+
* cannot cost the account its credentials (Task 1601's lesson applied to the
|
|
29
|
+
* refresh path rather than the write path).
|
|
30
|
+
*/
|
|
31
|
+
async function refresh(config, blob) {
|
|
32
|
+
if (!blob.refreshToken) {
|
|
33
|
+
throw new Error("no refresh token held for this Google account; run google-account-register");
|
|
34
|
+
}
|
|
35
|
+
const res = await fetch(config.refreshEndpoint, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "content-type": "application/json" },
|
|
38
|
+
body: JSON.stringify({ accountId: config.accountId, refreshToken: blob.refreshToken }),
|
|
39
|
+
});
|
|
40
|
+
const text = await res.text();
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
log({
|
|
43
|
+
tag: "[google-mcp]",
|
|
44
|
+
op: "refresh-failed",
|
|
45
|
+
account: config.accountId,
|
|
46
|
+
status: res.status,
|
|
47
|
+
body: text.slice(0, 300),
|
|
48
|
+
});
|
|
49
|
+
throw new Error(`token refresh failed (${res.status}): ${text.slice(0, 300)}`);
|
|
50
|
+
}
|
|
51
|
+
const json = JSON.parse(text);
|
|
52
|
+
const next = config.store.store(json.access_token, null, json.expires_in, {
|
|
53
|
+
scopes: json.scope ? json.scope.split(" ") : undefined,
|
|
54
|
+
});
|
|
55
|
+
log({ tag: "[google-mcp]", op: "refresh-ok", account: config.accountId, ttlSec: json.expires_in });
|
|
56
|
+
return next;
|
|
57
|
+
}
|
|
58
|
+
async function accessToken(config) {
|
|
59
|
+
const blob = config.store.read();
|
|
60
|
+
if (!blob) {
|
|
61
|
+
throw new Error("no Google account connected for this account; run google-account-register");
|
|
62
|
+
}
|
|
63
|
+
if (!isExpiring(blob))
|
|
64
|
+
return blob.accessToken;
|
|
65
|
+
return (await refresh(config, blob)).accessToken;
|
|
66
|
+
}
|
|
67
|
+
export async function callCalendar(config, path, init = {}) {
|
|
68
|
+
const token = await accessToken(config);
|
|
69
|
+
const url = `${CALENDAR_BASE}${path}${buildQuery(init.query ?? {})}`;
|
|
70
|
+
const res = await fetch(url, {
|
|
71
|
+
method: init.method ?? "GET",
|
|
72
|
+
headers: {
|
|
73
|
+
authorization: `Bearer ${token}`,
|
|
74
|
+
...(init.body === undefined ? {} : { "content-type": "application/json" }),
|
|
75
|
+
},
|
|
76
|
+
body: init.body === undefined ? undefined : JSON.stringify(init.body),
|
|
77
|
+
});
|
|
78
|
+
const text = await res.text();
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
// Cardinal observability rule: never discard an error body.
|
|
81
|
+
log({
|
|
82
|
+
tag: "[google-mcp]",
|
|
83
|
+
op: "api-error",
|
|
84
|
+
account: config.accountId,
|
|
85
|
+
path,
|
|
86
|
+
status: res.status,
|
|
87
|
+
body: text.slice(0, 500),
|
|
88
|
+
});
|
|
89
|
+
if (res.status === 403 && text.includes("insufficient")) {
|
|
90
|
+
throw new Error(`Google refused this call for missing scope (403). The connected account granted a narrower consent than https://www.googleapis.com/auth/calendar. Re-run google-account-register to re-consent. Body: ${text.slice(0, 300)}`);
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`Google Calendar API ${res.status}: ${text.slice(0, 300)}`);
|
|
93
|
+
}
|
|
94
|
+
return (text ? JSON.parse(text) : {});
|
|
95
|
+
}
|
|
96
|
+
/** The primary calendar's id IS the account's email address. Used instead of a
|
|
97
|
+
* userinfo call, because the identity scopes are deliberately not requested. */
|
|
98
|
+
export async function resolvePrimaryEmail(config) {
|
|
99
|
+
const cal = await callCalendar(config, "/calendars/primary");
|
|
100
|
+
return cal.id;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=google-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-client.js","sourceRoot":"","sources":["../../src/lib/google-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/lib/log.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,CAW9F"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** One structured stderr line. Never throws; logging must not break a tool. */
|
|
2
|
+
export function log(fields) {
|
|
3
|
+
try {
|
|
4
|
+
const parts = [];
|
|
5
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
6
|
+
if (v === undefined)
|
|
7
|
+
continue;
|
|
8
|
+
parts.push(`${k}=${v === null ? "null" : String(v)}`);
|
|
9
|
+
}
|
|
10
|
+
process.stderr.write(`${parts.join(" ")}\n`);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
/* logging must never throw */
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/lib/log.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,UAAU,GAAG,CAAC,MAAoE;IACtF,IAAI,CAAC;QACH,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS;YAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Auth state for one connected Google account, read from local stores only. */
|
|
2
|
+
export declare function runAccountInfo(args: {
|
|
3
|
+
accountId: string;
|
|
4
|
+
accountsDir: string;
|
|
5
|
+
email: string;
|
|
6
|
+
}): {
|
|
7
|
+
email: string;
|
|
8
|
+
connected: boolean;
|
|
9
|
+
expiring: boolean;
|
|
10
|
+
scopes: string[];
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=account-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-info.d.ts","sourceRoot":"","sources":["../../src/tools/account-info.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAgB7E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
2
|
+
import { isExpiring } from "../lib/google-client.js";
|
|
3
|
+
/** Auth state for one connected Google account, read from local stores only. */
|
|
4
|
+
export function runAccountInfo(args) {
|
|
5
|
+
let blob = null;
|
|
6
|
+
try {
|
|
7
|
+
blob = new TokenStore(args.accountId, args.accountsDir, args.email).read();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// An unreadable blob is reported as not-connected rather than thrown, so a
|
|
11
|
+
// corrupt store is diagnosable through this tool instead of crashing it.
|
|
12
|
+
return { email: args.email, connected: false, expiring: false, scopes: [] };
|
|
13
|
+
}
|
|
14
|
+
if (!blob)
|
|
15
|
+
return { email: args.email, connected: false, expiring: false, scopes: [] };
|
|
16
|
+
return {
|
|
17
|
+
email: blob.email ?? args.email,
|
|
18
|
+
connected: true,
|
|
19
|
+
expiring: isExpiring(blob),
|
|
20
|
+
scopes: blob.scopes,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=account-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-info.js","sourceRoot":"","sources":["../../src/tools/account-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,IAI9B;IACC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;QAC3E,yEAAyE;QACzE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC9E,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACvF,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;QAC/B,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC;QAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ConnectedAccount } from "./account-register.js";
|
|
2
|
+
/** Every connected Google account on this account, from local stores only — no
|
|
3
|
+
* network. `count` alone is not "connected": each entry carries its own status
|
|
4
|
+
* so an unreadable blob is distinguishable from a healthy one. */
|
|
5
|
+
export declare function runAccountList(args: {
|
|
6
|
+
accountId: string;
|
|
7
|
+
accountsDir: string;
|
|
8
|
+
}): {
|
|
9
|
+
count: number;
|
|
10
|
+
accounts: ConnectedAccount[];
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=account-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-list.d.ts","sourceRoot":"","sources":["../../src/tools/account-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE7E;;mEAEmE;AACnE,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B,CAGA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { listConnected } from "./account-register.js";
|
|
2
|
+
/** Every connected Google account on this account, from local stores only — no
|
|
3
|
+
* network. `count` alone is not "connected": each entry carries its own status
|
|
4
|
+
* so an unreadable blob is distinguishable from a healthy one. */
|
|
5
|
+
export function runAccountList(args) {
|
|
6
|
+
const accounts = listConnected(args.accountId, args.accountsDir);
|
|
7
|
+
return { count: accounts.length, accounts };
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=account-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-list.js","sourceRoot":"","sources":["../../src/tools/account-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyB,MAAM,uBAAuB,CAAC;AAE7E;;mEAEmE;AACnE,MAAM,UAAU,cAAc,CAAC,IAAgD;IAI7E,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACjE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const CALENDAR_SCOPE = "https://www.googleapis.com/auth/calendar";
|
|
2
|
+
/** Google refuses an authorization code older than roughly ten minutes; a
|
|
3
|
+
* pending entry past that is stranded, not live. */
|
|
4
|
+
export declare const PENDING_LIFETIME_SEC = 600;
|
|
5
|
+
export declare function newPkce(): {
|
|
6
|
+
verifier: string;
|
|
7
|
+
challenge: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function buildConsentUrl(args: {
|
|
10
|
+
clientId: string;
|
|
11
|
+
redirectUri: string;
|
|
12
|
+
state: string;
|
|
13
|
+
challenge: string;
|
|
14
|
+
accountId: string;
|
|
15
|
+
}): string;
|
|
16
|
+
export interface ConnectedAccount {
|
|
17
|
+
email: string;
|
|
18
|
+
status: "ok" | "unreadable";
|
|
19
|
+
}
|
|
20
|
+
/** Enumerate connected Google accounts from local stores only — no network.
|
|
21
|
+
* A count alone is not "connected": each entry carries its own status so an
|
|
22
|
+
* unreadable blob is distinguishable from a healthy one. */
|
|
23
|
+
export declare function listConnected(accountId: string, accountsDir: string): ConnectedAccount[];
|
|
24
|
+
export declare function runAccountRegisterStart(args: {
|
|
25
|
+
accountId: string;
|
|
26
|
+
accountsDir: string;
|
|
27
|
+
clientId: string;
|
|
28
|
+
publicBase: string;
|
|
29
|
+
}): Promise<{
|
|
30
|
+
status: "pending" | "in-progress";
|
|
31
|
+
consentUrl?: string;
|
|
32
|
+
ageSec?: number;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function runAccountRegisterPoll(args: {
|
|
35
|
+
accountId: string;
|
|
36
|
+
accountsDir: string;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
status: "registered" | "pending" | "expired" | "none";
|
|
39
|
+
accounts: ConnectedAccount[];
|
|
40
|
+
ageSec?: number;
|
|
41
|
+
}>;
|
|
42
|
+
//# sourceMappingURL=account-register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-register.d.ts","sourceRoot":"","sources":["../../src/tools/account-register.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc,6CAA6C,CAAC;AAGzE;qDACqD;AACrD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,wBAAgB,OAAO,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAGjE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAgBT;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,IAAI,GAAG,YAAY,CAAC;CAC7B;AAED;;6DAE6D;AAC7D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAaxF;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,GAAG,aAAa,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BvF;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtD,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAUD"}
|