---
title: Troubleshooting
description: "Fix common FullCalendar WebMCP issues: missing tools, lost changes after refresh, TypeScript refs, relative dates, and metadata."
sidebar:
  order: 5
---

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:**

1. Enable local WebMCP: `chrome://flags/#enable-webmcp-testing` → **Enabled** → relaunch Chrome ([Chrome WebMCP docs](https://developer.chrome.com/docs/ai/webmcp)).
2. Load the calendar on `http://localhost` (secure, origin-isolated context).
3. Open **DevTools → Application → WebMCP** and check **Available Tools** ([panel docs](https://developer.chrome.com/docs/devtools/application/webmcp)).
4. In the console, `document.modelContext` should be defined. Optionally run:

```js
(await document.modelContext.getTools()).map((t) => t.name)
```

5. Pass `onRegistrationError` to surface duplicate-name or registration failures:

```tsx
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](/integrations/fullcalendar/concepts/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:**

```tsx
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](/integrations/fullcalendar/guides/custom-event-model#metadata).

**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)**

```tsx
import FullCalendar, { type CalendarRef } from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/react/daygrid";
const calendarRef = useRef<CalendarRef>(null);
```

**v6**

```tsx
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
const calendarRef = useRef<FullCalendar>(null);
```

[`FullCalendarHandle`](/integrations/fullcalendar/reference/types#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:**

```tsx
events={events.map((event) => ({
  ...event,
  end: event.end ?? undefined,
}))}
```

**Verify:** Typecheck succeeds with strict null checks enabled.
