surf-mcp-server
Click on "Deploy 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., "@surf-mcp-serverWhat are the best spots in Uluwatu for intermediate surfers?"
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.
Surf MCP Server
Ein MCP Server fuer Surfspot-Daten, Spot-Suche, Marine Forecasts und Tide-Daten.
Die Spot-Daten liegen als JSON-Dateien unter src/data/. Forecasts kommen ueber
Open-Meteo Marine, Tide-Daten ueber WorldTides.
Der Server laeuft lokal per Python oder als Container in Kubernetes ueber das mitgelieferte Helm Chart.
Architektur
flowchart LR
Client[MCP Client] -->|streamable-http| Server[Surf MCP Server]
Server --> Tools[MCP Tools]
Tools --> Spots[src/data/*.json]
Tools --> Forecast[Forecast Orchestrierung]
Forecast --> OpenMeteo[Open-Meteo Marine API]
Forecast --> WorldTides[WorldTides API]
WorldTides --> Secret[WORLDTIDES_API_KEY]Related MCP server: Surf Forecast MCP
Voraussetzungen
Python
>=3.10Zugriff auf dieses Repo
Installation der Python-Abhaengigkeiten aus
pyproject.tomlOptional:
uvFuer Tide-Daten: WorldTides API Key als
WORLDTIDES_API_KEY
Abhaengigkeiten:
mcp[cli]requests
Lokales Setup
Vom Repo-Root aus:
cd surf-mcp-server
python -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .Alternativ mit uv:
cd surf-mcp-server
uv syncKonfiguration
Open-Meteo braucht keinen API Key. Fuer WorldTides muss ein API Key gesetzt sein,
wenn get_tides oder get_conditions genutzt werden:
export WORLDTIDES_API_KEY="..."Server starten
python src/server.pyDer Server startet mit streamable-http auf 0.0.0.0:8000:
mcp.run(transport="streamable-http")Wenn du ihn auf einem anderen System testest, reicht normalerweise:
Repo kopieren oder klonen
Python-Umgebung erstellen
Dependencies installieren
WORLDTIDES_API_KEYsetzen, falls Tide-Daten genutzt werdenpython src/server.pyaus dem Repo-Root ausfuehren
Projektstruktur
surf-mcp-server/
|-- .github/workflows/build.yml # GitHub Actions Build Pipeline
|-- charts/surf-mcp/ # Helm Chart
|-- src/
| |-- server.py # MCP Tools und Server-Start
| |-- spots.py # Laden der Spot-Dateien
| |-- forecast.py # Forecast- und Tide-Orchestrierung
| |-- data/ # Surfspot JSON-Dateien
| `-- providers/
| |-- open_meteo.py # Open-Meteo Marine API
| |-- worldtides.py # WorldTides API
| `-- stormglass.py # Vorbereiteter Provider
|-- tests/ # Unit Tests
|-- Dockerfile
|-- pyproject.toml
|-- uv.lock
`-- README.mdForecast Flow
sequenceDiagram
participant User as MCP Client
participant Server as Surf MCP Server
participant Data as Spot JSON
participant OM as Open-Meteo
participant WT as WorldTides
User->>Server: get_conditions(spot_id)
Server->>Data: get_spot(spot_id)
Data-->>Server: coordinates
Server->>OM: wave_height, wave_period, wave_direction
OM-->>Server: hourly marine forecast
Server->>WT: tide heights with WORLDTIDES_API_KEY
WT-->>Server: tide heights
Server-->>User: combined forecast + tide_stateVerfuegbare MCP Tools
list_regions()
Gibt alle verfuegbaren Regionen zurueck.
Beispiel-Resultat:
["Airport Reefs", "Lakey", "Uluwatu", "Ungasan", "West Sumbawa"]list_spots(region: string | null = null)
Listet Spots. Optional kann nach Region gefiltert werden.
Beispiel:
{
"region": "Uluwatu"
}Resultat enthaelt:
{
"id": "uluwatu_the_peak",
"name": "Uluwatu - The Peak",
"country": "Indonesia",
"island": "Bali",
"region": "Uluwatu"
}get_spot_info(spot_id: string)
Gibt alle Details fuer einen Spot zurueck.
Beispiel:
{
"spot_id": "lakey_peak"
}find_spots(...)
Findet Spots anhand mehrerer Kriterien.
Parameter:
skill: z.B.intermediate,advanced,expertcountry: z.B.Indonesiaisland: z.B.BalioderSumbawaregion: z.B.Uluwatu,Lakey,West Sumbawatide: z.B.low,mid,highwind: z.B.SE,N,NWswell_direction: z.B.S,SW,Wswell_height_ft: z.B.4
Beispiel:
{
"skill": "intermediate",
"island": "Bali",
"region": "Uluwatu",
"tide": "mid",
"wind": "SE",
"swell_direction": "SW",
"swell_height_ft": 4
}count_spots()
Gibt die Anzahl der Spot-Dateien zurueck.
search_spots(query: string)
Sucht Spots nach Name.
Beispiel:
{
"query": "uluwatu"
}get_forecast(spot_id: string)
Gibt den normalisierten Marine Forecast fuer einen Spot zurueck.
Die Daten kommen aus Open-Meteo Marine:
wave_height_ftwave_period_sswell_directionswell_direction_deg
Beispiel-Resultat:
[
{
"time": "2026-06-11T00:00",
"wave_height_ft": 4.6,
"wave_period_s": 12.1,
"swell_direction": "SW",
"swell_direction_deg": 225
}
]get_tides(spot_id: string)
Gibt Tide-Daten fuer einen Spot zurueck.
Die Daten kommen aus WorldTides. Dafuer muss WORLDTIDES_API_KEY gesetzt sein.
Beispiel-Resultat:
[
{
"time": "2026-06-11T00:00+0000",
"tide_height_ft": 3.2,
"tide_state": "mid"
}
]get_conditions(spot_id: string)
Kombiniert Marine Forecast und Tide-Daten. Pro Forecast-Zeitpunkt wird die
naechste Tide gesucht und als tide_height_ft und tide_state ergaenzt.
Beispiel-Resultat:
[
{
"time": "2026-06-11T00:00",
"wave_height_ft": 4.6,
"wave_period_s": 12.1,
"swell_direction": "SW",
"swell_direction_deg": 225,
"tide_height_ft": 3.2,
"tide_state": "mid"
}
]Docker
Image lokal bauen:
docker build -t surf-mcp-server .Container starten:
docker run --rm \
-p 8000:8000 \
-e WORLDTIDES_API_KEY="$WORLDTIDES_API_KEY" \
surf-mcp-serverGitHub Build Pipeline
Die Pipeline liegt unter .github/workflows/build.yml.
flowchart TD
PushMain[Push auf main] --> Checkout[Checkout]
Checkout --> Login[Login bei GHCR]
Login --> Metadata[Docker Metadata]
Metadata --> Build[Docker Build]
Build --> PushGhcr[Push nach GHCR]
PushGhcr --> Tags[latest + Git SHA]Bei jedem Push auf main wird ein Container Image gebaut und nach GHCR
gepusht:
ghcr.io/steph76k/surf-mcp-server:latestghcr.io/steph76k/surf-mcp-server:<git-sha>
Die Pipeline nutzt GITHUB_TOKEN mit packages: write.
Kubernetes Deployment mit Helm
Das Helm Chart liegt unter charts/surf-mcp/.
flowchart LR
Helm[helm upgrade --install] --> Deployment[Deployment]
Helm --> Service[Service]
Helm --> Ingress[Ingress]
Secret[Kubernetes Secret surf-mcp] --> Deployment
Deployment --> Pod[surf-mcp Pod]
Pod --> GHCR[GHCR Image]
Pod --> WorldTides[WorldTides API]WorldTides Secret erstellen
Vor dem Helm Deployment muss der WorldTides API Key als Kubernetes Secret angelegt werden:
kubectl create secret generic surf-mcp \
--from-literal=worldtides-api-key="$WORLDTIDES_API_KEY"Das Chart liest den Key standardmaessig aus diesem Secret:
env:
- name: WORLDTIDES_API_KEY
valueFrom:
secretKeyRef:
name: surf-mcp
key: worldtides-api-keyInstallieren oder aktualisieren
helm upgrade --install surf-mcp charts/surf-mcp \
--namespace surf-mcp \
--create-namespaceStandardwerte aus charts/surf-mcp/values.yaml:
Image:
ghcr.io/steph76k/surf-mcp-server:latestService:
ClusterIPauf Port8000Ingress: Traefik
Host:
surf-mcp.rke2-cluster1.berger.phSecret:
surf-mcpmit Keyworldtides-api-key
Image Tag ueberschreiben
helm upgrade --install surf-mcp charts/surf-mcp \
--namespace surf-mcp \
--create-namespace \
--set image.tag="<git-sha>"Manifest lokal pruefen
helm template surf-mcp charts/surf-mcpSpot JSON Schema
Jeder Spot ist eine eigene JSON-Datei in src/data/. Der Dateiname sollte zur
spot_id passen.
Beispiel:
{
"spot_id": "uluwatu_the_peak",
"name": "Uluwatu - The Peak",
"country": "Indonesia",
"island": "Bali",
"region": "Uluwatu",
"coordinates": {
"lat": -8.816633,
"lon": 115.08625
},
"conditions": {
"swell": {
"directions": ["S", "SW"],
"min_ft": 1,
"max_ft": 6
},
"wind": {
"offshore": ["SE"]
},
"tide": ["mid", "high"]
},
"wave": {
"direction": "left",
"type": "reef"
},
"ratings": {
"crowd": 10,
"localism": 9,
"risk": 6,
"fun": 9
},
"surfer_level": ["intermediate", "advanced"],
"notes": "At high tide, aim south of the cave when coming in.",
"description": "Short description of the spot.",
"hazards": [
"sharp coral reef",
"strong currents"
]
}Wichtige Daten-Konventionen
surfer_level
surfer_level ist immer ein Array, damit die Suche einzelne Levels sauber
matchen kann:
{
"surfer_level": ["intermediate", "advanced"]
}Nicht mehr verwenden:
{
"surfer_level": "intermediate / advanced"
}Empfohlene Werte:
beginnerintermediateadvancedexpert
Location Felder
country, island und region sind getrennte Felder:
{
"country": "Indonesia",
"island": "Bali",
"region": "Uluwatu"
}Nicht mehr verwenden:
{
"region": "Bali - Uluwatu Area"
}Aktuelle Regionen
Airport ReefsLakeyUluwatuUngasanWest Sumbawa
Neue Spots hinzufuegen
Neue Datei in
src/data/erstellen, z.B.my_spot.jsonspot_idpassend zum Dateinamen setzen, z.B.my_spotSchema wie oben verwenden
JSON validieren:
jq empty src/data/my_spot.jsonAlle Spot-Dateien validieren:
for f in src/data/*.json; do jq empty "$f" || exit 1; doneTests und Checks
python -m compileall src
python -m unittest discover -s tests
helm template surf-mcp charts/surf-mcpHinweise
Spot-Daten werden bei jedem Tool-Aufruf direkt aus
src/data/*.jsongelesen.get_forecastnutzt Open-Meteo Marine und braucht keinen API Key.get_tidesundget_conditionsnutzen WorldTides und brauchenWORLDTIDES_API_KEY.src/providers/stormglass.pyist als optionaler Provider vorbereitet.Das Helm Chart nutzt standardmaessig die im Docker Image enthaltenen Spot-Daten.
Ein externer ConfigMap-Mount fuer Spot-Daten kann ueber
spotData.configMap.enabled=trueaktiviert werden.
This server cannot be deployed
Maintenance
Related MCP Connectors
7 day surf forecasts (wave, wind, period) for any coordinate or named surf spot.
Surf trip planner: live 0-100 Strike Scores, 10-day forecasts, and trip picks for 1,100+ spots.
Geospatial MCP server for earthquake, tsunami, volcano, disaster, and FX data queries.
AI-native mock API server with MCP. Create REST/SOAP mocks from Claude, Cursor, or Windsurf.
Related MCP Servers
- FlicenseBqualityDmaintenanceA minimal Python MCP server that provides surf forecasts for a single Surfline spot. It fetches both conditions and rating data through the get_surf_forecast tool.1-
- FlicenseNot gradedqualityCmaintenanceProvides surf forecast data including swell height, period, direction, and wind conditions for any location worldwide using the Open-Meteo Marine API. It also includes tools to find the best day to surf and integrates with MCP clients via a Python server.20-
- AlicenseAqualityDmaintenanceMCP server for wind forecasts, live measurements, wave forecasts, and tides, enabling kite and surf spot checks via AI assistants.56 npmMIT
- FlicenseNot gradedqualityDmaintenanceMinimal MCP server exposing tools for kitesurfing forecasts (wind and waves via Open-Meteo) and tide predictions (via NOAA CO-OPS).-