teamup-mcp
MCP server for the Teamup Calendar API, enabling event management, calendar listing, and available slot search.
README
teamup-mcp
MCP server for the Teamup Calendar API, built with the official @modelcontextprotocol/sdk.
Tools
| Tool | Description |
|---|---|
get_events |
Retrieve events in a date range — with optional title filters (title_contains, title_starts_with, title_regex) |
create_event |
Create a new event |
update_event |
Update an existing event |
delete_event |
Delete an event |
search_events |
Full-text search across title, notes, location and who fields |
get_subcalendars |
List all sub-calendars |
find_available_slots |
Find free court slots for a given day — returns all free windows per court that fit the requested game type |
Prerequisites
- Node.js 18+
- A Teamup API key — generate one at teamup.com under Account → API Keys
- Your calendar key — visible in the calendar URL:
https://teamup.com/<calendar-key>
Installation
git clone https://github.com/your-user/teamup-mcp
cd teamup-mcp
npm install
npm run build
Running
TEAMUP_API_KEY=your_api_key node dist/index.js
During development you can skip the build step with tsx:
TEAMUP_API_KEY=your_api_key npm run dev
Claude Code integration
MCP servers are configured in ~/.claude/.mcp.json (global, all projects) or .mcp.json in your project root (project-only). Add the teamup entry inside the mcpServers object:
{
"mcpServers": {
"teamup": {
"command": "node",
"args": ["/absolute/path/to/teamup-mcp/dist/index.js"],
"env": {
"TEAMUP_API_KEY": "your_api_key_here",
"TEAMUP_CALENDAR_KEY": "your_calendar_key_here"
}
}
}
}
Setting TEAMUP_CALENDAR_KEY as an env var means you never need to pass calendar_key in individual tool calls. Restart Claude Code after saving the file.
Usage examples
List sub-calendars
get_subcalendars(calendar_key="ks123abc456def")
Get events for a week
get_events(
calendar_key="ks123abc456def",
start_date="2024-06-01",
end_date="2024-06-07"
)
Create an event
create_event(
calendar_key="ks123abc456def",
title="Team standup",
start_dt="2024-06-03T09:00:00+02:00",
end_dt="2024-06-03T09:30:00+02:00",
subcalendar_id=12345678
)
Update an event
version_idcomes from theversionfield returned byget_eventsorcreate_event. It is required by Teamup to prevent lost-update conflicts.
update_event(
calendar_key="ks123abc456def",
event_id="987654321",
version_id="abc123...",
title="Team standup (moved)",
start_dt="2024-06-03T10:00:00+02:00",
end_dt="2024-06-03T10:30:00+02:00"
)
Delete an event
delete_event(
calendar_key="ks123abc456def",
event_id="987654321",
version_id="abc123..."
)
Filter events by title
get_events(
start_date="2026-01-01",
end_date="2026-12-31",
title_starts_with="U10"
)
Available title filters (applied client-side after API fetch):
| Parameter | Example | Matches |
|---|---|---|
title_contains |
"U10" |
Any title containing "U10" |
title_starts_with |
"U10" |
Titles that begin with "U10" |
title_regex |
"^U1[02]" |
Titles matching the regex (case-insensitive) |
Search events (full-text)
search_events(
query="Burgthann",
start_date="2026-01-01",
end_date="2026-12-31"
)
Searches across title, notes, location and who fields via the Teamup /search API endpoint.
Find available court slots
find_available_slots(
date="2026-07-05",
game_type="singles",
earliest_time="09:00",
latest_time="21:00"
)
| Parameter | Type | Description |
|---|---|---|
date |
YYYY-MM-DD |
Day to search |
game_type |
singles | doubles |
Determines required duration: singles = 90 min, doubles = 120 min |
earliest_time |
HH:MM |
Earliest acceptable start time |
latest_time |
HH:MM |
Latest end of window (default: 22:00) |
Returns all free time windows per court (Belegung > Platz 1–4) that are long enough for the requested game type:
[
{
"subcalendar_id": 8137510,
"subcalendar_name": "Belegung > Platz 1",
"free_windows": [
{ "from": "09:00", "to": "11:30" },
{ "from": "14:00", "to": "21:00" }
]
}
]
Testing — Funktionstest mit echten Kalender-Daten
Die folgenden Prompts decken alle Tools ab und basieren auf dem realen Kalender ks2zsf595tyfr4313t. Da TEAMUP_CALENDAR_KEY als Umgebungsvariable gesetzt ist, wird calendar_key in keinem Aufruf benötigt.
✅ get_subcalendars — alle 8 Sub-Kalender auflisten
Prompt:
Zeige mir alle Sub-Kalender im Teamup-Kalender.
Erwartetes Ergebnis: 8 Einträge:
| ID | Name |
|---|---|
| 7774417 | Medenspielplan |
| 8137510 | Belegung > Platz 1 |
| 8137714 | Belegung > Platz 2 |
| 8137813 | Belegung > Platz 3 |
| 8137814 | Belegung > Platz 4 |
| 8285738 | ASV-Halle Herren |
| 12586059 | ASV-Halle Damen |
| 13375969 | Belegung > Information |
✅ get_events — Einträge in einem Datumsbereich
Prompt:
Hole alle Einträge vom 01.07.2026 bis 31.07.2026.
Erwartetes Ergebnis: Mehrere Einträge, darunter:
U10 : TC Greding II(05.07.2026, Platz 1 + Platz 2)U10 : TeG Altmühlgrund II(12.07.2026, Platz 1 + Platz 2)
✅ get_events mit title_starts_with — Titelfilter
Prompt:
Zeige alle Einträge in 2026, deren Titel mit "U10" beginnt.
Erwartetes Ergebnis: Genau 9 Einträge (einige doppelt wegen Mehrfach-Platz-Belegung):
| Datum | Titel | Kalender |
|---|---|---|
| 03.05.2026 | U10 : 15:00 Uhr TSV Pyrbaum | Medenspielplan |
| 17.05.2026 | U10 : TV Hilpoltstein II | Belegung > Platz 3 |
| 17.05.2026 | U10 : TV Hilpoltstein II | Belegung > Platz 4 |
| 14.06.2026 | U10 : 14:00 Uhr TSV Freystadt | Medenspielplan |
| 28.06.2026 | U10 : 15:00 Uhr TSV Burgthann | Medenspielplan |
| 05.07.2026 | U10 : TC Greding II | Belegung > Platz 1 |
| 05.07.2026 | U10 : TC Greding II | Belegung > Platz 2 |
| 12.07.2026 | U10 : TeG Altmühlgrund II | Belegung > Platz 1 |
| 12.07.2026 | U10 : TeG Altmühlgrund II | Belegung > Platz 2 |
Hinweis: Die doppelten Einträge sind kein Fehler — das Heimspiel belegt jeweils zwei Plätze gleichzeitig.
✅ search_events — Volltextsuche
Prompt:
Suche nach "Burgthann" in 2026.
Erwartetes Ergebnis: 1 Eintrag:
U10 : 15:00 Uhr TSV Burgthannam 28.06.2026 (Medenspielplan)
✅ find_available_slots — freie Plätze finden
Prompt:
Wann ist am 05.07.2026 ein Platz frei für ein Einzel? Ab 09:00 Uhr.
Erwartetes Ergebnis: Platz 3 und Platz 4 ganztägig frei (Platz 1 + 2 sind durch das U10-Spiel belegt):
Belegung > Platz 3:
09:00 – 22:00
Belegung > Platz 4:
09:00 – 22:00
✅ create_event — neuen Eintrag anlegen
Prompt:
Lege ein Einzel-Training auf Platz 2 am 20.08.2026 von 10:00 bis 11:30 Uhr an. Titel: "Training Lars".
Erwartetes Ergebnis: Neues Event mit id und version-Feld in der Antwort — diese werden für Update und Delete benötigt.
✅ update_event — Eintrag bearbeiten
Prompt:
Verschiebe das Training vom 20.08.2026 auf 11:00–12:30 Uhr. (event_id und version_id aus dem vorherigen Schritt verwenden)
Erwartetes Ergebnis: Geändertes Event mit neuer version-ID zurück.
✅ delete_event — Eintrag löschen
Prompt:
Lösche das Training vom 20.08.2026 wieder. (event_id und version_id aus dem Update-Schritt verwenden)
Erwartetes Ergebnis: Bestätigung Event … deleted successfully.
Project structure
src/
index.ts # MCP server entrypoint & tool handlers
teamup-client.ts # Typed Teamup REST API client
dist/ # Compiled output (after npm run build)
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.