Skip to main content
Glama

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

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 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_id comes from the version field returned by get_events or create_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 Burgthann am 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)
F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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