-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add Google Calendar MCP with OAuth 2.0 support #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add calendar management tools (list, get, create, delete) - Add event management tools (list, get, create, update, delete, quick_add) - Add availability tool (get_freebusy) - Add advanced tools (move_event, find_available_slots, duplicate_event) - Implement OAuth 2.0 with PKCE for Google authentication - Add Google Calendar API client with full TypeScript types - Add google-calendar to monorepo workspaces Total: 14 tools for complete calendar management
🚀 Preview Deployments Ready!Your changes have been deployed to preview environments: 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 16 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="google-calendar/server/lib/types.ts">
<violation number="1" location="google-calendar/server/lib/types.ts:148">
P2: Inconsistent typing for `accessRole`. This field uses a specific union type in `CalendarListEntry` but a generic `string` here. Consider using the same union type for consistency and better type safety.</violation>
</file>
<file name="google-calendar/server/main.ts">
<violation number="1" location="google-calendar/server/main.ts:42">
P1: Missing `redirect_uri` parameter in token exchange request. Google OAuth requires this to match the authorization request's redirect_uri. The token exchange will fail without it.</violation>
</file>
<file name="google-calendar/server/tools/advanced.ts">
<violation number="1" location="google-calendar/server/tools/advanced.ts:257">
P1: When `newStart` is provided without `newEnd`, using the original event's end time directly can create invalid events (end before start) or events with incorrect duration. Consider calculating the new end time by preserving the original event's duration when only `newStart` is specified.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Google OAuth doesn't allow 'state' inside redirect_uri. Extract state from callbackUrl and pass it as separate OAuth param.
- Add CalendarAccessRole type for better type safety - Fix redirect_uri handling in exchangeCode - Fix getAccessToken type compatibility with Env
Tools need to receive the env parameter to access the authenticated user's access token.
- Add shared/deco.gen.ts with typed Env and MeshRequestContext - Add server/lib/env.ts with getGoogleAccessToken helper - Update main.ts to use typed Env from shared/deco.gen.ts - Update google-client.ts to use env.ts helper - Fix all numeric schema fields to use z.coerce.number() for string-to-number conversion
When only newStart is provided without newEnd, calculate the new end time by preserving the original event's duration instead of using the original end time directly, which could create invalid events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 issue found across 9 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="google-calendar/server/main.ts">
<violation number="1" location="google-calendar/server/main.ts:21">
P0: Critical race condition: `lastRedirectUri` is shared global state that will be overwritten by concurrent OAuth flows. If User A starts auth, then User B starts auth before A finishes, User A's token exchange will fail because it uses B's redirect_uri.
Consider using a `Map<string, string>` keyed by the state parameter or code_verifier to store redirect URIs per-flow, or pass the redirect_uri through the OAuth state parameter.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| ].join(" "); | ||
|
|
||
| // Store the last used redirect_uri for token exchange | ||
| let lastRedirectUri: string | null = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P0: Critical race condition: lastRedirectUri is shared global state that will be overwritten by concurrent OAuth flows. If User A starts auth, then User B starts auth before A finishes, User A's token exchange will fail because it uses B's redirect_uri.
Consider using a Map<string, string> keyed by the state parameter or code_verifier to store redirect URIs per-flow, or pass the redirect_uri through the OAuth state parameter.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At google-calendar/server/main.ts, line 21:
<comment>Critical race condition: `lastRedirectUri` is shared global state that will be overwritten by concurrent OAuth flows. If User A starts auth, then User B starts auth before A finishes, User A's token exchange will fail because it uses B's redirect_uri.
Consider using a `Map<string, string>` keyed by the state parameter or code_verifier to store redirect URIs per-flow, or pass the redirect_uri through the OAuth state parameter.</comment>
<file context>
@@ -4,46 +4,80 @@
].join(" ");
+// Store the last used redirect_uri for token exchange
+let lastRedirectUri: string | null = null;
+
const runtime = withRuntime<Env>({
</file context>
Total: 14 tools for complete calendar management
Summary by cubic
Adds a Google Calendar MCP server with OAuth 2.0 (PKCE) and 14 tools for full calendar and event management, availability checks, and advanced operations. Also fixes Google OAuth state/redirect_uri handling and preserves event duration when duplicating with only a new start time.
New Features
Migration
Written for commit ac1272d. Summary will update on new commits.