The Day I Fought My Calendar (and Won)

I just wanted one simple thing: ask my AI what day it is, and have it answer without tripping over itself. The reason is because self hosted models are weak at telling what the day is, when not provided with such information. And the google calendar tool only provides the date and not the day.

Act I — When Two Clocks Collide

  • Mission: expose two MCP tools through mcpo and Open WebUI.
  • Existing heavyweight: Google Calendar MCP (the Node-based jack-of-all-calendar-trades).
  • New kid: a bespoke clock tool that should confidently say “It’s Tuesday” without rummaging through my calendar.
  • Outcome? Chaos. Both exposed a get_current_time-ish endpoint. The model got confused, fumbled tool choices, and I started muttering at my monitor.

Act II — “Just Disable the Endpoint,” They Said…

  • mcpo global config looked promising. Add "disabledTools": ["get_current_time"] for google-calendar, right?
  • Wrong. mcpo cheerfully ignored me. /get-current-time kept popping up in the OpenAPI spec like an undead endpoint with work to do.
  • Frustration level: high enough to consider a bonfire for server racks.

Act III — The Proxy Stan

  • Accepted defeat on the mcpo toggle. Built a workaround to firewall off the calendar’s time endpoint. Requirements:
  • Don’t rewrite the calendar server or maintain my own remote time logic.
  • Keep everything Docker’d with existing network.
  • Hello, tiny FastAPI proxy:
  • Sits in front of google-calendar routes.
  • Fetches /google-calendar/openapi.json, strips /get-current-time.
  • Blocks requests to /google-calendar/get-current-time outright.
  • Passes everything else through untouched.
  • Runs on the same network; exposed externally on port 8002.

Act IV — Tuning the Proxy Mini-Boss

  • FastAPI tried to helpfully publish its own swagger endpoints. Thanks but no thanks.
  • Disabled auto docs (docs_url=None, openapi_url=None).
  • Marked all proxy routes include_in_schema=False.
  • Manually set info.title and info.version to match upstream.
  • Rebuilding later, http://localhost:8002/google-calendar/openapi.json became identical to the original—minus the problematic path—and Open WebUI stopped whining.

Act V — But Another Connection Error

I thought “done!” until Open WebUI still refused to connect. Cue facepalm. The UI runs inside Docker; localhost for the UI is inside that container. The correct internal address is http://google-calendar-proxy:8000/google-calendar.Once I pointed the UI at that internal hostname:

  • Clock tool: http://mcpo:8001/clock (still returns ISO/time/day with gusto).
  • Calendar tool (now de-conflicted): http://google-calendar-proxy:8000/google-calendar.
  • Result: the LLM no longer second-guesses which tool handles “What day is it?”

Lessons Learned (AKA, Future Me, Please Read This)

  • mcpo can run multiple MCP servers under separate subpaths. Their routes don’t collide, but the model might if endpoint names clash semantically.
  • disabledTools doesn’t apply to every MCP server—test before trusting.
  • Small proxy shims are cheap insurance. FastAPI + httpx kept this fix under 100 lines.
  • Container hostnames matter. localhost from a container is the container itself. Use the service name + port, or expose ports to the host deliberately.

Now the setup properly answers, “Today is Tuesday,” without rummaging through my calendar first. Future timestamp requests go to /clock/get_current_time, and Google Calendar stays focused on, well, calendars. My sanity is restored—for now.