teamup-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@teamup-mcpFind available singles slots for this Saturday."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
teamup-mcp
MCP server for the Teamup Calendar API, built with the official @modelcontextprotocol/sdk.
Tools
Tool | Description |
| Retrieve events in a date range — with optional title filters ( |
| Create a new event |
| Update an existing event |
| Delete an event |
| Full-text search across title, notes, location and who fields |
| List all sub-calendars |
| Find free court slots for a given day — returns all free windows per court that fit the requested game type |
Related MCP server: Google-Workspace-MCP-Server
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 buildRunning
TEAMUP_API_KEY=your_api_key node dist/index.jsDuring development you can skip the build step with tsx:
TEAMUP_API_KEY=your_api_key npm run devClaude 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 |
|
| Any title containing "U10" |
|
| Titles that begin with "U10" |
|
| 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 |
|
| Day to search |
|
| Determines required duration: singles = 90 min, doubles = 120 min |
|
| Earliest acceptable start time |
|
| Latest end of window (default: |
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)This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/LarsZilch/teamup-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server