Koskamo

Zovo Group Calendar MCP

An MCP server that allows users to create and manage group calendars by defining events with weekly repeats, places, and notes. It generates a standard iCalendar feed and a public page for viewing upcoming events, enabling subscription via Apple Calendar, Outlook, or Google Calendar. Users can modify or cancel events through chat, with updates propagating to subscribed calendar apps.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Zovo Group Calendar MCP logo, by ZovoCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-08Published by Zovo
MCP endpoint (Streamable HTTP)
https://calendar-feed.zovo.one/mcp
Vendor documentation

What its tools do

3 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

Read-only (1)

3 of 3 have a description · 3 of 3 declare behavior hints · 3 of 3 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Create a subscribable calendar for recurring group events like soccer practice
  • Cancel or modify specific events in a group calendar via chat
  • View a public page listing upcoming events for a group

Source and maintenance

Community listingRegistry 1.0.0

Protocol and capabilities

Server
calendar-feed 1.0.0
MCP protocol negotiated in check
2025-11-25
Tools
3 advertised
Resources
1 advertised
Resource templates
1 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Zovo Group Calendar publishes a calendar a group can subscribe to (practice schedules, class timetables, club events). create_group_calendar returns a public page with subscribe buttons and a private organizer link. update_group_calendar adds, changes or cancels events; subscribers' calendar apps pick up changes on their own refresh schedule. show_group_calendar lists the events with their numbers.

Tools

3 advertised

create_group_calendar — Create group calendar
Advertised by the server during the last successful anonymous check.
Open-world

Use this when someone wants a shared calendar that a group subscribes to: a team practice schedule, class timetable, club or family events. Publishes a page with the upcoming events and subscribe links (webcal, Google Calendar add-by-URL) to a live iCalendar feed. Takes 1-200 events in one IANA time zone, with optional weekly repeats and skipped dates; events can run up to one year ahead. Returns the public link and a private organizer link. Does not send invitations, reminders or emails, and does not write into anyone's calendar directly.

create_group_calendar input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "time_zone",
    "events"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 200,
      "description": "Calendar name people will see in their calendar app, e.g. U12 soccer practice."
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "title",
          "date"
        ],
        "properties": {
          "end": {
            "type": "string",
            "maxLength": 20,
            "description": "Local end time HH:MM, e.g. 19:00. An end earlier than the start means the next day. Or use duration_minutes."
          },
          "date": {
            "type": "string",
            "maxLength": 40,
            "description": "First (or only) date, YYYY-MM-DD, e.g. 2026-11-10."
          },
          "note": {
            "type": "string",
            "maxLength": 1200,
            "description": "Short note, e.g. Bring shin guards."
          },
          "start": {
            "type": "string",
            "maxLength": 20,
            "description": "Local start time HH:MM in the calendar's time zone, e.g. 17:30. Omit for an all-day event."
          },
          "title": {
            "type": "string",
            "maxLength": 400,
            "description": "Event title, e.g. Practice."
          },
          "all_day": {
            "type": "boolean",
            "description": "true for an all-day event (no times), e.g. true."
          },
          "end_date": {
            "type": "string",
            "maxLength": 40,
            "description": "For an all-day event over several days, the last day YYYY-MM-DD (inclusive), e.g. 2026-11-22."
          },
          "location": {
            "type": "string",
            "maxLength": 400,
            "description": "Place in words, e.g. Field 2, Riverside Park. No links."
          },
          "skip_dates": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 40
            },
            "maxItems": 40,
            "description": "Dates of a weekly series to leave out, e.g. [\"2026-12-22\"]."
          },
          "duration_minutes": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "description": "Length in minutes instead of an end time, e.g. 90. Default 60."
          },
          "repeat_weekly_until": {
            "type": "string",
            "maxLength": 40,
            "description": "Repeat every week on the same weekday until this date YYYY-MM-DD (inclusive), e.g. 2027-01-26."
          }
        }
      },
      "maxItems": 220,
      "description": "The events, e.g. [{\"title\":\"Practice\",\"date\":\"2026-11-10\",\"start\":\"17:30\",\"end\":\"19:00\",\"repeat_weekly_until\":\"2027-02-23\"}]."
    },
    "time_zone": {
      "type": "string",
      "maxLength": 64,
      "description": "IANA time zone of the event times, e.g. Europe/Berlin or America/Chicago."
    },
    "description": {
      "type": "string",
      "maxLength": 1000,
      "description": "Short description shown on the page and in calendar apps, e.g. Practice schedule for the U12 team."
    },
    "organizer_name": {
      "type": "string",
      "maxLength": 100,
      "description": "Organizer's first name shown on the page, e.g. Coach Sam."
    }
  }
}
create_group_calendar output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "time_zone",
    "publicUrl",
    "manageUrl",
    "feed_url",
    "webcal_url",
    "google_add_url",
    "expires_at",
    "events_total",
    "events_active",
    "upcoming_occurrences",
    "past_occurrences",
    "closed",
    "refresh_note",
    "next",
    "events",
    "changes",
    "warnings"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "next": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "cancelled"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "cancelled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "closed": {
      "type": "boolean"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "location",
          "status",
          "occurrences",
          "revision"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "revision": {
            "type": "number"
          },
          "occurrences": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "feed_url": {
      "type": "string"
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "manageUrl": {
      "type": "string"
    },
    "publicUrl": {
      "type": "string"
    },
    "time_zone": {
      "type": "string"
    },
    "expires_at": {
      "type": "string"
    },
    "webcal_url": {
      "type": "string"
    },
    "events_count": {
      "type": "object",
      "required": [
        "shown",
        "total"
      ],
      "properties": {
        "shown": {
          "type": "number"
        },
        "total": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "events_total": {
      "type": "number"
    },
    "refresh_note": {
      "type": "string"
    },
    "events_active": {
      "type": "number"
    },
    "google_add_url": {
      "type": "string"
    },
    "past_occurrences": {
      "type": "number"
    },
    "upcoming_occurrences": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
create_group_calendar annotations
{
  "title": "Create group calendar",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
show_group_calendar — Show group calendar
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the organizer wants to see a group calendar they made: its events with their numbers, the next dates and the subscribe links. Needs the private organizer link (contains /m/). Does not change the calendar.

show_group_calendar input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "manage_link"
  ],
  "properties": {
    "manage_link": {
      "type": "string",
      "maxLength": 400,
      "description": "The private organizer link returned when the calendar was made, e.g. https://calendar-feed.zovo.one/m/<id>/<key>."
    }
  }
}
show_group_calendar output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "time_zone",
    "publicUrl",
    "manageUrl",
    "feed_url",
    "webcal_url",
    "google_add_url",
    "expires_at",
    "events_total",
    "events_active",
    "upcoming_occurrences",
    "past_occurrences",
    "closed",
    "refresh_note",
    "next",
    "events",
    "changes",
    "warnings"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "next": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "cancelled"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "cancelled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "closed": {
      "type": "boolean"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "location",
          "status",
          "occurrences",
          "revision"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "revision": {
            "type": "number"
          },
          "occurrences": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "feed_url": {
      "type": "string"
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "manageUrl": {
      "type": "string"
    },
    "publicUrl": {
      "type": "string"
    },
    "time_zone": {
      "type": "string"
    },
    "expires_at": {
      "type": "string"
    },
    "webcal_url": {
      "type": "string"
    },
    "events_count": {
      "type": "object",
      "required": [
        "shown",
        "total"
      ],
      "properties": {
        "shown": {
          "type": "number"
        },
        "total": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "events_total": {
      "type": "number"
    },
    "refresh_note": {
      "type": "string"
    },
    "events_active": {
      "type": "number"
    },
    "google_add_url": {
      "type": "string"
    },
    "past_occurrences": {
      "type": "number"
    },
    "upcoming_occurrences": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
show_group_calendar annotations
{
  "title": "Show group calendar",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
update_group_calendar — Update group calendar
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Use this when the organizer wants to add events to a group calendar, change an event (time, date, place, note, repeat, skipped dates), cancel or restore an event, or rename the calendar. Needs the private organizer link and the event numbers from show_group_calendar. Changed events keep their identity and get a higher revision, so calendar apps update them on their next refresh; cancelled events stay marked as cancelled. Does not notify anyone and does not delete events.

update_group_calendar input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "manage_link"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 200,
      "description": "New calendar name, e.g. U12 practice (winter)."
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "event"
        ],
        "properties": {
          "end": {
            "type": "string",
            "maxLength": 20,
            "description": "Local end time HH:MM, e.g. 19:00. An end earlier than the start means the next day. Or use duration_minutes."
          },
          "date": {
            "type": "string",
            "maxLength": 40,
            "description": "First (or only) date, YYYY-MM-DD, e.g. 2026-11-10."
          },
          "note": {
            "type": "string",
            "maxLength": 1200,
            "description": "Short note, e.g. Bring shin guards."
          },
          "event": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "description": "The event number shown in the calendar results, e.g. 3."
          },
          "start": {
            "type": "string",
            "maxLength": 20,
            "description": "Local start time HH:MM in the calendar's time zone, e.g. 17:30. Omit for an all-day event."
          },
          "title": {
            "type": "string",
            "maxLength": 400,
            "description": "Event title, e.g. Practice."
          },
          "cancel": {
            "type": "boolean",
            "description": "true to cancel the event; it stays in subscribers' calendars marked cancelled, e.g. true."
          },
          "all_day": {
            "type": "boolean",
            "description": "true for an all-day event (no times), e.g. true."
          },
          "restore": {
            "type": "boolean",
            "description": "true to undo a cancellation, e.g. false."
          },
          "end_date": {
            "type": "string",
            "maxLength": 40,
            "description": "For an all-day event over several days, the last day YYYY-MM-DD (inclusive), e.g. 2026-11-22."
          },
          "location": {
            "type": "string",
            "maxLength": 400,
            "description": "Place in words, e.g. Field 2, Riverside Park. No links."
          },
          "skip_dates": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 40
            },
            "maxItems": 40,
            "description": "Dates to ADD to the dates this weekly series already skips (earlier skips stay), e.g. [\"2026-12-22\"]."
          },
          "unskip_dates": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 40
            },
            "maxItems": 40,
            "description": "Skipped dates of a weekly series to put back, e.g. [\"2026-12-22\"]."
          },
          "duration_minutes": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "description": "Length in minutes instead of an end time, e.g. 90. Default 60."
          },
          "repeat_weekly_until": {
            "type": "string",
            "maxLength": 40,
            "description": "Repeat every week on the same weekday until this date YYYY-MM-DD (inclusive), e.g. 2027-01-26."
          }
        }
      },
      "maxItems": 50,
      "description": "Changes to existing events by number, e.g. [{\"event\":1,\"skip_dates\":[\"2026-12-22\"]},{\"event\":3,\"cancel\":true}]."
    },
    "add_events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "title",
          "date"
        ],
        "properties": {
          "end": {
            "type": "string",
            "maxLength": 20,
            "description": "Local end time HH:MM, e.g. 19:00. An end earlier than the start means the next day. Or use duration_minutes."
          },
          "date": {
            "type": "string",
            "maxLength": 40,
            "description": "First (or only) date, YYYY-MM-DD, e.g. 2026-11-10."
          },
          "note": {
            "type": "string",
            "maxLength": 1200,
            "description": "Short note, e.g. Bring shin guards."
          },
          "start": {
            "type": "string",
            "maxLength": 20,
            "description": "Local start time HH:MM in the calendar's time zone, e.g. 17:30. Omit for an all-day event."
          },
          "title": {
            "type": "string",
            "maxLength": 400,
            "description": "Event title, e.g. Practice."
          },
          "all_day": {
            "type": "boolean",
            "description": "true for an all-day event (no times), e.g. true."
          },
          "end_date": {
            "type": "string",
            "maxLength": 40,
            "description": "For an all-day event over several days, the last day YYYY-MM-DD (inclusive), e.g. 2026-11-22."
          },
          "location": {
            "type": "string",
            "maxLength": 400,
            "description": "Place in words, e.g. Field 2, Riverside Park. No links."
          },
          "skip_dates": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 40
            },
            "maxItems": 40,
            "description": "Dates of a weekly series to leave out, e.g. [\"2026-12-22\"]."
          },
          "duration_minutes": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "description": "Length in minutes instead of an end time, e.g. 90. Default 60."
          },
          "repeat_weekly_until": {
            "type": "string",
            "maxLength": 40,
            "description": "Repeat every week on the same weekday until this date YYYY-MM-DD (inclusive), e.g. 2027-01-26."
          }
        }
      },
      "maxItems": 200,
      "description": "New events to add, same shape as when creating, e.g. [{\"title\":\"Tournament\",\"date\":\"2026-12-12\",\"all_day\":true}]."
    },
    "description": {
      "type": "string",
      "maxLength": 1000,
      "description": "New description, e.g. Winter indoor schedule."
    },
    "manage_link": {
      "type": "string",
      "maxLength": 400,
      "description": "The private organizer link returned when the calendar was made, e.g. https://calendar-feed.zovo.one/m/<id>/<key>."
    }
  }
}
update_group_calendar output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "time_zone",
    "publicUrl",
    "manageUrl",
    "feed_url",
    "webcal_url",
    "google_add_url",
    "expires_at",
    "events_total",
    "events_active",
    "upcoming_occurrences",
    "past_occurrences",
    "closed",
    "refresh_note",
    "next",
    "events",
    "changes",
    "warnings"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "next": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "cancelled"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "cancelled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "closed": {
      "type": "boolean"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "number",
          "title",
          "when",
          "location",
          "status",
          "occurrences",
          "revision"
        ],
        "properties": {
          "when": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "number": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "revision": {
            "type": "number"
          },
          "occurrences": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "feed_url": {
      "type": "string"
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "manageUrl": {
      "type": "string"
    },
    "publicUrl": {
      "type": "string"
    },
    "time_zone": {
      "type": "string"
    },
    "expires_at": {
      "type": "string"
    },
    "webcal_url": {
      "type": "string"
    },
    "events_count": {
      "type": "object",
      "required": [
        "shown",
        "total"
      ],
      "properties": {
        "shown": {
          "type": "number"
        },
        "total": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "events_total": {
      "type": "number"
    },
    "refresh_note": {
      "type": "string"
    },
    "events_active": {
      "type": "number"
    },
    "google_add_url": {
      "type": "string"
    },
    "past_occurrences": {
      "type": "number"
    },
    "upcoming_occurrences": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
update_group_calendar annotations
{
  "title": "Update group calendar",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

calendar-feed-widget — Zovo Group Calendar view

Advertised by the server during the last successful anonymous check.

Interactive view for Zovo Group Calendar.

calendar-feed-widget URI
ui://widget/calendar-feed-v1-1.0.0-e0f948db64068bd0c9ac29f662be73f8d3d1d75523fde0f018da3752909b5e58.html

MIME type: text/html;profile=mcp-app

calendar-feed-widget-legacy — Zovo Group Calendar view (previous versions)

Advertised by the server during the last successful anonymous check.

calendar-feed-widget-legacy URI template
ui://widget/calendar-feed-{version}.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
657 ms
95th percentile latency
657 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 657 ms · metadata changed · 3 tool(s), 1 resource(s), 1 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http zovo-group-calendar-mcp https://calendar-feed.zovo.one/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add zovo-group-calendar-mcp --url https://calendar-feed.zovo.one/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable zovo-group-calendar-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "zovo-group-calendar-mcp": {
      "url": "https://calendar-feed.zovo.one/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "zovo-group-calendar-mcp": {
      "type": "streamableHttp",
      "url": "https://calendar-feed.zovo.one/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start zovo-group-calendar-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "zovo-group-calendar-mcp": {
      "type": "http",
      "url": "https://calendar-feed.zovo.one/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http zovo-group-calendar-mcp https://calendar-feed.zovo.one/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://calendar-feed.zovo.one/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "zovo-group-calendar-mcp": {
      "serverUrl": "https://calendar-feed.zovo.one/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Zovo Group Calendar MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.