teamup-mcp

teamup-mcp

MCP server for the Teamup Calendar API, enabling event management, calendar listing, and available slot search.

Category
Visit Server

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_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)

Recommended Servers

playwright-mcp

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

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.

Official
Featured