Skip to content

[Cal.com] Add AI Extension tools (MCP parity) + EU server support#27992

Merged
raycastbot merged 3 commits into
raycast:mainfrom
andrewbenson:cal-com-ai-tools-and-eu
May 17, 2026
Merged

[Cal.com] Add AI Extension tools (MCP parity) + EU server support#27992
raycastbot merged 3 commits into
raycast:mainfrom
andrewbenson:cal-com-ai-tools-and-eu

Conversation

@andrewbenson
Copy link
Copy Markdown
Contributor

@andrewbenson andrewbenson commented May 17, 2026

Summary

Adds two cohesive changes to the Cal.com extension:

  1. 33 AI Extension tools that mirror Cal.com's MCP server surface (mcp.cal.com), invokable via @cal-com-share-meeting-links in Raycast AI chat. Tools wrap the existing v2 API client so they reuse the user's API key — no OAuth handshake or separate auth surface.
  2. EU server support (fixes [Cal.com] Support for Cal.eu (European instance) API base URL #27697). New "Server Region" preference (Global default / Europe) so cal.eu accounts no longer hit 401.

Why one PR for all this

Both changes share the same src/api/cal.com.ts axios client. The AI tools route through that client, so wiring the region toggle there makes EU work for the AI tools automatically — splitting into two PRs would force the second to refactor the first's exports. Happy to split if reviewers prefer.

What's in this PR

1. AI Extension tools (33 tools, MCP parity)

Cal.com released an MCP server at mcp.cal.com (https://cal.com/docs/mcp-server) that wraps their v2 API and exposes 33 tools. This PR exposes those same 33 tools as native Raycast AI Extension tools so users can invoke Cal.com via @cal-com-share-meeting-links in Raycast AI chat. The implementation calls the existing v2 axios client directly — Cal.com's MCP server is just a v2 wrapper, so bridging to it (with Streamable HTTP + OAuth 2.1) would add ~300 LOC of plumbing for zero capability gain.

Tool surface (file-per-tool in src/tools/):

  • User profile (2): get-me, update-me*
  • Event types (5): get-event-types, get-event-type, create-event-type, update-event-type, delete-event-type*
  • Bookings (10): get-bookings, get-booking, create-booking, reschedule-booking, cancel-booking, confirm-booking, mark-booking-absent, get-booking-attendees, add-booking-attendee, get-booking-attendee
  • Schedules (6): get-schedules, get-schedule, get-default-schedule, create-schedule, update-schedule, delete-schedule*
  • Availability (2): get-availability, get-busy-times
  • Conferencing (1): get-conferencing-apps
  • Routing forms (1): calculate-routing-form-slots
  • Organizations (6): get-org-memberships, create-org-membership, get-org-membership, delete-org-membership, get-org-routing-forms, get-org-routing-form-responses

(* = requires a Raycast confirmation dialog before executing. 16 of 33 are write-tools.)

ai.instructions covers the routing rules: always look up booking UIDs via get-bookings before per-booking actions, never invent UIDs, pass IANA timezones (not abbreviations), pass ISO 8601 with offset (not naive local strings), only call org-* tools if the user is in an org, etc.

ai.evals: 5 golden-path tests, all passing (npx ray evals → 5/5 100%).

Out-of-office is intentionally NOT included — it's not part of Cal.com's MCP server surface, so the strict-parity stance keeps it command-only. Easy to add in a follow-up if requested.

2. EU server support — fixes #27697

  • New region dropdown preference (global default, eu opt-in).
  • src/api/cal.com.ts now derives and exports userBaseUrl (api.cal.com / api.cal.eu), appBaseUrl (app.cal.com / app.cal.eu), and publicBaseUrl (cal.com / cal.eu) from the preference.
  • All hardcoded URLs across index.tsx, view-bookings.tsx, view-availability.tsx, out-of-office.tsx, components/schedule-detail.tsx, and normalizeAvatarUrl switched to the dynamic exports.
  • AI tools route through the same axios instance, so they automatically respect the region — no per-tool wiring.

Dependency cleanup

  • Bumps @raycast/api ^1.104.12 → ^1.104.17 and @raycast/utils ^2.2.3 → ^2.2.4 (current as of writing).
  • Removes unused dayjs from dependencies (greptile flagged this on the prior PR; the comment was acknowledged but not fixed at the time).

Implementation notes

  • AI tool inputs avoid TypeScript constructs the Raycast schema extractor rejects. Record<*, *> and unknown aren't supported, and cross-file imported types can't be resolved. For complex objects (locations, metadata, booking-field responses, schedule availability/overrides, routing form responses), tools accept a *Json parameter that's JSON.parsed server-side — keeps the schema extractable while still allowing full v2 API expressiveness. Documented in tool descriptions.
  • Number ids, not unions. Raycast's extractor only allows string unions, so id parameters are typed as number (the helper assertId in src/lib/ai-tools.ts coerces via String() for URL construction).
  • Tool.Confirmation payload shape kept minimal (message, image) — matches the in-repo pattern in extensions/superhuman/src/tools/.
  • formatBookingForAI in src/lib/ai-tools.ts slims booking responses for AI consumption (drops large bookingFieldsResponses and nested metadata blobs that burn context for no benefit).

Test plan

  • npm run build clean across all 38 entry points (5 commands + 33 tool files)
  • npm run lint clean (only the pre-existing "Create out of Office" title-casing warning from PR [Cal.com] Major expansion: availability management, out of office, and View Bookings redesign #27133, deliberately left as-is)
  • npx ray evals5/5 passing (100%)
  • Verified the existing 5 Raycast commands still work end-to-end with the new dynamic URLs (Global region)
  • EU region: I don't have a cal.eu test account. Verified at code level that all axios + link URLs now route to api.cal.eu / app.cal.eu / cal.eu when the preference is set. Would appreciate a reviewer with a cal.eu account to confirm.

Breaking changes

None. Existing users keep their API key and cached state. The default region is global, which matches the previous hardcoded behavior.

Open items

Adds 33 Raycast AI Extension tools that mirror Cal.com's MCP server
surface (mcp.cal.com), invokable via `@cal-com-share-meeting-links` in
Raycast AI chat. Tools call the existing v2 API client so they reuse
the user's API key and automatically respect the new region toggle —
no OAuth handshake needed.

Adds a Server Region preference (Global default / Europe) so cal.eu
accounts work. Fixes raycast#27697.

- 33 tool files in src/tools/ (event types, bookings, schedules,
  availability, busy times, conferencing apps, routing forms, orgs).
  16 write-tools export Tool.Confirmation.
- ai.instructions guides the model: always look up uids via
  get-bookings before per-booking actions, IANA timezones only,
  ISO 8601 with offset, etc.
- ai.evals: 5 golden-path tests, all passing.
- Dynamic URL routing: userBaseUrl/appBaseUrl/publicBaseUrl exported
  from src/api/cal.com.ts and used everywhere previously hardcoded.
- Bumps @raycast/api to ^1.104.17 and @raycast/utils to ^2.2.4.
  Removes unused dayjs dep (flagged by greptile on the prior PR).
@raycastbot raycastbot added extension fix / improvement Label for PRs with extension's fix improvements extension: cal-com-share-meeting-links Issues related to the cal-com-share-meeting-links extension AI Extension platform: macOS OP is contributor The OP of the PR is a contributor of the extension labels May 17, 2026
@raycastbot
Copy link
Copy Markdown
Collaborator

raycastbot commented May 17, 2026

Thank you for your contribution! 🎉

🔔 @eluce2 @peduarte @pernielsentikaer @AlexIsMaking @jfkisafk @runofthemillgeek you might want to have a look.

You can use this guide to learn how to check out the Pull Request locally in order to test it.

📋 Quick checkout commands
BRANCH="cal-com-ai-tools-and-eu"
FORK_URL="https://github.com/andrewbenson/raycast-extensions.git"
EXTENSION_NAME="cal-com-share-meeting-links"
REPO_NAME="raycast-extensions"

git clone -n --depth=1 --filter=tree:0 -b $BRANCH $FORK_URL
cd $REPO_NAME
git sparse-checkout set --no-cone "extensions/$EXTENSION_NAME"
git checkout
cd "extensions/$EXTENSION_NAME"
npm install && npm run dev

We're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 10-15 business days.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 17, 2026

Greptile Summary

This PR adds 33 AI Extension tools mirroring Cal.com's MCP server surface and introduces a "Server Region" preference (global / eu) so cal.eu accounts no longer hit 401s. Both features share the same axios client in src/api/cal.com.ts, which now derives and exports region-aware base URLs consumed by all tools and existing commands.

  • AI tools (33): One file per tool under src/tools/, wrapping the existing calAPI helper. Write tools (16) use Tool.Confirmation; read tools return slim, AI-optimised payloads via formatBookingForAI. Complex API shapes are accepted as *Json strings and parsed server-side to stay compatible with Raycast's schema extractor.
  • EU region support: New region dropdown preference drives userBaseUrl / appBaseUrl / publicBaseUrl exports; all hardcoded app.cal.com / cal.com / api.cal.com references across five existing views have been switched to these dynamic exports. Dependency cleanup removes unused dayjs.

Confidence Score: 5/5

Safe to merge after fixing the changelog placeholder — all functional changes are well-contained and low-risk.

The region-switching logic is a straightforward URL substitution with a safe global default, and the 33 tool files are thin wrappers over the existing, tested calAPI client. Write tools all gate behind Tool.Confirmation, inputs are validated with assertId, and the complex JSON-string pattern avoids schema-extractor edge cases. The only issue found is a cosmetic changelog date that should be the {PR_MERGE_DATE} placeholder.

CHANGELOG.md — hardcoded date needs to be replaced with {PR_MERGE_DATE}.

Important Files Changed

Filename Overview
extensions/cal-com-share-meeting-links/CHANGELOG.md New entry uses hardcoded date 2026-05-17 instead of the required {PR_MERGE_DATE} template placeholder.
extensions/cal-com-share-meeting-links/package.json Registers 33 tools, adds region preference dropdown, bumps deps, removes unused dayjs. Well-formed.
extensions/cal-com-share-meeting-links/src/api/cal.com.ts Derives and exports region-aware userBaseUrl, appBaseUrl, publicBaseUrl from the new region preference; exports calAPI for tool use. Clean, minimal change.
extensions/cal-com-share-meeting-links/src/lib/ai-tools.ts New helper library with assertId, formatBookingForAI, and confirmDestructive; straightforward and well-documented.
extensions/cal-com-share-meeting-links/src/tools/create-booking.ts Clean booking creation tool with confirmation, JSON parsing for optional complex fields, and slim response formatting.
extensions/cal-com-share-meeting-links/src/tools/get-bookings.ts Correctly uses !== undefined guard for skip; falsy check for eventTypeId is acceptable given IDs are always positive.
extensions/cal-com-share-meeting-links/src/tools/reschedule-booking.ts Validates bookingUid, posts to reschedule endpoint, returns slim booking for AI context.
extensions/cal-com-share-meeting-links/src/tools/update-me.ts Patches /me with the full input object; JSON serialization correctly drops undefined optional fields.
extensions/cal-com-share-meeting-links/src/view-bookings.tsx Hardcoded app.cal.com URLs replaced with appBaseUrl dynamic export; correct and complete.
extensions/cal-com-share-meeting-links/src/view-availability.tsx All hardcoded app.cal.com links replaced with region-aware appBaseUrl.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
extensions/cal-com-share-meeting-links/CHANGELOG.md:3
The changelog entry uses a hardcoded date (`2026-05-17`) instead of the required `{PR_MERGE_DATE}` placeholder. Per the repository convention, the placeholder is replaced automatically on merge — using a literal date bypasses that process and leaves the timestamp wrong if the PR merges on a different day.

```suggestion
## [AI Tools + EU server support] - {PR_MERGE_DATE}
```

Reviews (3): Last reviewed commit: "Update CHANGELOG.md" | Re-trigger Greptile

Greptile flagged the inconsistency: this tool used `if (input.skip)` /
`if (input.take)` which silently drops `skip: 0` / `take: 0`.
The sibling `get-bookings.ts` already uses the correct `!== undefined`
guard. Aligned with that pattern.
@andrewbenson
Copy link
Copy Markdown
Contributor Author

Addressed greptile's finding in 69cc9f2a: get-org-routing-form-responses.ts now uses !== undefined for the take / skip pagination guards, matching the pattern in get-bookings.ts. Thanks for the catch.

Copy link
Copy Markdown
Contributor

@0xdhrv 0xdhrv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, approved ✅

@raycastbot raycastbot merged commit eba5494 into raycast:main May 17, 2026
3 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

Published to the Raycast Store:
https://raycast.com/cal/cal-com-share-meeting-links

@raycastbot
Copy link
Copy Markdown
Collaborator

🎉 🎉 🎉

We've rewarded your Raycast account with some credits. You will soon be able to exchange them for some swag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Extension extension: cal-com-share-meeting-links Issues related to the cal-com-share-meeting-links extension extension fix / improvement Label for PRs with extension's fix improvements OP is contributor The OP of the PR is a contributor of the extension platform: macOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Cal.com] Support for Cal.eu (European instance) API base URL

3 participants