Software

How to Connect Claude to Your WebCalendar with MCP

Here’s something I’ve wanted for a long time: asking my calendar questions in plain English. As of WebCalendar 1.9.16, you can. WebCalendar now ships an MCP server — Model Context Protocol support — so you can connect an AI assistant like Claude directly to your self-hosted calendar and say things like “What’s on my calendar next week?” or “Add a 30-minute dentist appointment next Tuesday at 2pm.”

MCP is the emerging standard for connecting AI assistants to tools and data. WebCalendar’s MCP server (a single mcp.php endpoint) exposes your calendar operations as tools the assistant can call — reading events, searching, and creating new ones — all authenticated as you, running with your permissions. This post walks through enabling it and wiring up Claude Desktop.

Table of Contents

  • What You Can Do With It
  • What You’ll Need
  • Step 1: Enable the MCP Server
  • Step 2: Create Your API Token
  • Step 3: Connect Claude Desktop
  • Step 4: Try It
  • Connecting Over HTTP Instead
  • A Note on Security
  • Bonus: Inspect and Stress-Test It

What You Can Do With It

The MCP server exposes four tools that an AI assistant can call on your behalf:

ToolWhat it does
list_eventsLists events in a date range (start_date/end_date, YYYYMMDD)
search_eventsFinds events by keyword, with an optional result limit
get_user_infoReturns your login, name, and email (a quick way to confirm the connection)
add_eventCreates a non-repeating event (title, date, and optional description, location, and duration)

It’s intentionally a focused, safe set — read your calendar and add simple events. There’s no bulk deletion or recurring-event editing here, which is exactly what you want the first time you let an AI touch your schedule.

What You’ll Need

  • WebCalendar 1.9.13 or later (1.9.16 recommended — that’s where MCP support was finalized)
  • PHP 8.0+
  • Claude Desktop for the walkthrough below
  • Admin access to your WebCalendar install (to switch the feature on)

If you don’t have WebCalendar running yet, my guide to installing WebCalendar with Docker Compose will get you there in a few minutes.

Step 1: Enable the MCP Server

The MCP server is off by default. As an administrator, go to Admin > System Settings and set:

  • MCP_SERVER_ENABLEDY
  • MCP_RATE_LIMIT → the maximum requests per minute per user (a sensible throttle)
  • MCP_CORS_ORIGINS → optional, only needed for browser-based clients

You can sanity-check that it’s live by opening mcp.php in a browser — a plain GET request returns the server status.

Step 2: Create Your API Token

Each user authenticates with their own personal token. In Preferences, find the MCP API Token field, enter a long, unique string of your choosing, and save. WebCalendar stores it against your account (webcal_user.cal_api_token). Treat it like a password — anything holding this token can act as you.

Step 3: Connect Claude Desktop

Claude Desktop launches the MCP server locally over STDIO. Open Claude Desktop’s config file — on macOS that’s ~/Library/Application Support/Claude/claude_desktop_config.json — and add a webcalendar entry:

{
  "mcpServers": {
    "webcalendar": {
      "command": "php",
      "args": ["/path/to/webcalendar/mcp.php"],
      "env": {
        "MCP_TOKEN": "your-api-token"
      }
    }
  }
}

Point args at the mcp.php in your WebCalendar install and drop in the token from Step 2. Save and restart Claude Desktop. Because this runs php mcp.php directly, it assumes Claude Desktop is on the same machine as your WebCalendar install (with PHP and database access) — perfect for a local install. If your calendar lives on a remote server, use the HTTP method below instead.

Step 4: Try It

Restart Claude Desktop and you should see the WebCalendar tools available. Start simple to confirm the connection, then get more useful:

  • “Use webcalendar to show my user info.” (confirms auth via get_user_info)
  • “What’s on my calendar between July 14 and July 20?”
  • “Search my calendar for anything with ‘standup’ in it.”
  • “Add a 30-minute event titled ‘Dentist’ on 2026-07-21 at the downtown office.”

Claude figures out which tool to call and fills in the parameters. Remember that dates use YYYYMMDD under the hood, but you can talk to Claude in normal language and let it do the conversion.

Connecting Over HTTP Instead

If your WebCalendar runs on a remote server, connect to the mcp.php endpoint over HTTP and pass your token in a header:

{
  "mcpServers": {
    "webcalendar": {
      "url": "https://yourserver.com/webcalendar/mcp.php",
      "headers": {
        "X-MCP-Token": "your-api-token"
      }
    }
  }
}

One gotcha worth knowing: some Apache configurations strip the Authorization header, which is why WebCalendar also accepts the token via the X-MCP-Token header (used above). If you’d rather use Authorization: Bearer, add this to your .htaccess:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

A Note on Security

Every MCP operation runs as the authenticated user, with exactly that user’s permissions — nothing more. A few things worth keeping in mind:

  • Your token is a credential. Don’t paste it anywhere you wouldn’t paste a password.
  • To revoke access instantly, clear the MCP API Token field in Preferences.
  • Keep the feature off unless you’re using it (MCP_SERVER_ENABLED = N), and use MCP_RATE_LIMIT to cap request volume.

Bonus: Inspect and Stress-Test It

If you want to see exactly what’s going over the wire — the initialize handshake, the advertised tools, the raw JSON-RPC responses — register the WebCalendar MCP server in k5n-mcp-hub, my local hub for MCP servers. It’ll show the server’s health and capabilities, let you replay calls in a playground, and even let you inject faults to see how a client copes. It’s how I test this server myself.

Full details are in the MCP server documentation, and the code lives in the WebCalendar repository on GitHub. If you give it a try, I’d love to hear what you end up asking your calendar — and what you’d want it to do next.

Leave a Reply

Your email address will not be published. Required fields are marked *