Troubleshooting
Fix common FullCalendar WebMCP issues: missing tools, lost changes after refresh, TypeScript refs, relative dates, and metadata.
Symptom-oriented fixes. For each issue: cause, fix, then verify.
The agent cannot see calendar tools
Cause: Chrome WebMCP is not enabled, document.modelContext is unavailable, or registration failed.
Fix:
- Enable local WebMCP:
chrome://flags/#enable-webmcp-testing→ Enabled → relaunch Chrome (Chrome WebMCP docs). - Load the calendar on
http://localhost(secure, origin-isolated context). - Open DevTools → Application → WebMCP and check Available Tools (panel docs).
- In the console,
document.modelContextshould be defined. Optionally run:
(await document.modelContext.getTools()).map((t) => t.name)
- Pass
onRegistrationErrorto surface duplicate-name or registration failures:
useFullCalendarWebMCP({
calendarRef,
events: repository,
onEventsChanged: refreshEvents,
onRegistrationError: (error) => console.error(error),
});
The hook retries registration every 250 ms if the runtime appears after mount.
Verify: All six calendar_* tools appear under Application → WebMCP → Available Tools.
Events appear but changes disappear after refresh
Cause: Your repository writes only to React state or another in-memory store.
Fix: Implement create / update / delete against your real API or database. FullCalendar WebMCP does not store events. See Repository.
Verify: Create an event via the agent, hard-reload, and confirm it is still listed.
The calendar updates but my database does not
Cause: onEventsChanged refreshes UI from a cache or local copy that does not match what you persisted—or create/update returned success without writing.
Fix: Make repository methods await the durable write, then have onEventsChanged reload from that same source of truth.
Verify: After an agent mutation, query your database (or API) directly and confirm the row changed.
Agent mutations succeed, but the calendar does not refresh
Cause: onEventsChanged is missing or does not update the events prop passed to <FullCalendar />.
Fix:
const refreshEvents = useCallback(async () => {
setEvents(await repository.list());
}, []);
useFullCalendarWebMCP({
calendarRef,
events: repository,
onEventsChanged: refreshEvents,
});
Verify: Create an event via the agent and confirm it appears without a manual page reload.
Relative dates resolve incorrectly
Cause: The agent scheduled “tomorrow at 2pm” without calling calendar_get_context or without using ISO-8601 timestamps that include a timezone offset.
Fix: Prefer agents that call calendar_get_context first, then emit offsets such as 2026-09-02T14:00:00-06:00 or Z.
Verify: calendar_get_context returns browserTimeZone, fullCalendarTimeZone, now, and visibleRange that match the on-screen view.
Metadata does not appear
Cause: The repository omits metadata on CalendarEvent, or you expected FullCalendar extendedProps to be exposed automatically.
Fix: Project only the fields you want agents to see when mapping to CalendarEvent. Protocol Tooling never copies extendedProps for you. Metadata is read-only on writes. See Custom event models.
Verify: calendar_get_event / calendar_list_events include your metadata object; create/update tool inputs reject metadata.
WebMCP tools register twice
Cause: Multiple mounted calendars each call useFullCalendarWebMCP, or a previous registration did not clean up (less common with the built-in abort cleanup).
Fix: Register once per page (or scope to a single calendar instance). Avoid mounting two hooked calendars that both register the same tool names. Use onRegistrationError to log conflicts.
Verify: Only one set of calendar_* tools is listed; remounting the component does not leave duplicates.
FullCalendar ref or plugin import TypeScript error
Cause: FullCalendar React v6 and v7 use different ref types and plugin import paths.
Fix:
v7 (default in Quickstart)
import FullCalendar, { type CalendarRef } from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/react/daygrid";
const calendarRef = useRef<CalendarRef>(null);
v6
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
const calendarRef = useRef<FullCalendar>(null);
FullCalendarHandle is structurally compatible with both ref shapes.
Verify: Typecheck passes and calendar_get_context returns the active view.
Event end: null vs end: undefined
Cause: CalendarEvent.end is string | null for JSON/DB clarity; FullCalendar’s prop types often prefer undefined.
Fix:
events={events.map((event) => ({
...event,
end: event.end ?? undefined,
}))}
Verify: Typecheck succeeds with strict null checks enabled.