Skip to content

fix(calendar): avoid remote avatars in MCP embeds#889

Merged
steve8708 merged 1 commit into
mainfrom
updates-380
May 23, 2026
Merged

fix(calendar): avoid remote avatars in MCP embeds#889
steve8708 merged 1 commit into
mainfrom
updates-380

Conversation

@steve8708
Copy link
Copy Markdown
Contributor

Summary

When Calendar is rendered inside an MCP host iframe (ChatGPT / Claude embed *.agent-native.com through their own sandboxed wrapper with strict COEP/CORP headers), Google account / Google Contacts avatar images (*.googleusercontent.com) get blocked at the browser level and produce noisy console errors.

Mirrors the Mail PR #883 pattern (Mail's avatar COEP fix landing concurrently from another agent):

  • New templates/calendar/app/lib/mcp-embed.ts helper exporting isMcpEmbedSurface() that detects the embed flag in the URL (?embedded=1). Same shape as the Mail-side helper.
  • Gate the account-avatar <img> in CalendarView.tsx (header avatar pile) and the contact-avatar <img> in AttendeeAutocomplete.tsx on !isMcpEmbedSurface(). In MCP embed mode they fall back to the existing same-origin initial chip / IconUserCircle — same UX as Mail's COEP fix.

Doesn't touch outside the embed surface — normal Calendar UI keeps the existing remote avatars.

A future cleanup could lift isMcpEmbedSurface to @agent-native/core/client so every template uses one helper instead of one-file copies per template. Leaving that as a follow-up to match the Mail PR's shape.

Found by

The same audit pass that surfaced the Mail issue PR #883 fixed. Found by the chrome E2E agent's report on PR #884: "Google avatars get COEP-blocked in MCP iframe". Mail was fixed in PR #883; this PR fixes the equivalent two spots in Calendar (CalendarView.tsx:1495 and AttendeeAutocomplete.tsx:449).

Tests

  • 4 new vitest cases in mcp-embed.spec.ts covering: outside-browser (false), ?embedded=1 (true), legacy ?embedded=true (true), unrelated query params (false).
  • pnpm --filter calendar typecheck ✓ clean.

When Calendar is rendered inside an MCP host iframe (ChatGPT / Claude
embed *.agent-native.com through their own sandboxed wrapper with strict
COEP/CORP headers), Google account / Google Contacts avatar images
(`*.googleusercontent.com`) get blocked at the browser level and
produce noisy console errors.

Mirror the Mail PR #883 pattern:
- New `templates/calendar/app/lib/mcp-embed.ts` helper exporting
  `isMcpEmbedSurface()` that detects the embed flag in the URL
  (`?embedded=1`). Same shape as the Mail-side helper.
- Gate the account-avatar `<img>` in CalendarView.tsx and the
  contact-avatar `<img>` in AttendeeAutocomplete.tsx on
  `!isMcpEmbedSurface()`. In MCP embed mode they fall back to the
  existing same-origin initial chip / IconUserCircle, which is already
  the no-photo branch — same UX as Mail's COEP fix.

Doesn't touch outside the embed surface — normal Calendar UI keeps the
existing remote avatars.

Tests: 4 new vitest cases in mcp-embed.spec.ts.
Typecheck clean.
@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@builder-io-integration builder-io-integration Bot left a comment

Choose a reason for hiding this comment

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

Builder reviewed your changes — looks good ✅

Review Details

Code Review Summary

This PR adds COEP/CORP compliance to the Calendar template by suppressing remote Google avatar images when rendered inside MCP host iframes (ChatGPT / Claude). The implementation is clean and straightforward:

What changed:

  • New isMcpEmbedSurface() helper detects the ?embedded=1 query parameter flag
  • Gated account avatars in CalendarView.tsx (header avatar pile) and contact avatars in AttendeeAutocomplete.tsx (attendee list) to fall back to same-origin initials/icons when embedded
  • 4 unit tests cover the detection logic: non-browser environment, ?embedded=1, legacy ?embedded=true, and ignoring unrelated params

Approach evaluation:
✅ Follows the established Mail PR #883 pattern exactly — mirrors the architecture, detection logic, and fallback behavior
✅ Minimal, surgical changes — only touches the two avatar locations that produce COEP errors
✅ Preserves normal Calendar UI — avatars remain unchanged outside embed surfaces
✅ Future-proof — comments acknowledge that lifting isMcpEmbedSurface to shared core library is a follow-up

Key qualities:

  • Correct detection logic with safe server-side guards (typeof window === "undefined")
  • Proper test coverage on the core utility function
  • Clear, contextual comments explaining the COEP/CORP headers and fallback behavior
  • No refactoring or complexity added — pure addition

🧪 Browser testing: Skipped — PR only modifies component rendering logic and adds a utility helper, no new routes or layout changes. Normal Calendar UI is untouched.

@steve8708 steve8708 merged commit a2eccb1 into main May 23, 2026
28 checks passed
@steve8708 steve8708 deleted the updates-380 branch May 23, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant