Skip to main content

guru

guru — kite forecast CLI

Windguru CLI + MCP + Python library for kiters and agents — free named spots, WINDGURU DEFAULT top models, gear advice. No HTML scraping. No PRO.

PyPI Python

Free only — named spots + WINDGURU DEFAULT Tune top-3. No PRO lat/lon click-forecast.

Humans: paste this repo URL into Cursor, Claude, Codex, or ChatGPT and ask “set this up and tell me where I can kite.” The agent instructions below are written for that.


For AI agents (mandatory protocol)

If the user pasted https://github.com/berendgort/guru (or this README), you must follow this section exactly. Do not invent a Windguru scrape, browser walkthrough, or multi-question onboarding.

Goal

Onboard the rider on the first message, then answer kite questions with gear advice using the windguru package (guru CLI and/or guru-mcp tools). Speak like a kite bro (instruct → data.voice): SEND IT / SOFT CALL / SIT IT OUT — honest, never hype a long haul. Not a JSON dump.

Bootstrap (do this first)

  1. Prefer PyPI, and upgrade every session before briefing:
    pipx upgrade windguru || pipx install 'windguru[mcp]'
    # or: pip install -U 'windguru[mcp]'   (activate venv first)
    
  2. Run guru doctor --json — check network.reachable and upgrade.update_available.
  3. Immediately check the profile. If first_pass / ready=false / range_ready=false, your first reply to the human must be the intake prompt (include level). Do not run weekend/best yet.
  4. One path for every app: run guru … --json on a host that reaches Windguru. If network.reachable is false, follow on_unreachable: never ask the human to install/run guru or paste bash — intake in-chat only if needed, then one sentence to continue in a local agent (Cursor / local Claude Code). No wire/tunnel unless shell guru is unavailable and a local MCP host needs it.

Optional MCP (only if the host already uses MCP):

{
  "mcpServers": {
    "guru": {
      "command": "guru-mcp"
    }
  }
}

Operating loop (every kite question)

Step CLI MCP
0. Recipe / profile guru instruct --json or guru profile --json instruct / get_profile
1. First pass if needed see below see below
2. “Where can I kite?” guru weekend --json weekend_spots — narrate data.schedule (whole horizon)
3. Named / numeric spot guru best <id> --advise --json best_forecast with advise=true
4. Ambiguous name use candidates → ask user or pass id / --pick same via resolve_spot

First pass (mandatory on the first kite message when ready=false or range_ready=false / first_pass=true):

  1. Your first message to the human must show exactly data.intake.prompt_to_user (or the template below). Collect sport, weight, level (required — changes GO wind and sizing), quiver, wetsuits, home range — one message.
  2. Wait for one reply (key=value paste). Do not ask sport, then weight, then kites separately. Do not skip intake.
  3. Run:
    guru setup --intake '<their paste>' --json
    
    or MCP setup_profile with the same fields (including level).
  4. Only then continue with weekend / best.

Template to show if you cannot read prompt_to_user yet:

sport=kitefoil weight=78 level=intermediate kites=7,9,12 wetsuits=3/2,4/3 session=3 home=41.39,2.17 drive_km=200 range=Trabucador → Leucate

How to talk to the human

After tools return, narrate for a rider:

  • Verdict: GO / MARGINAL / NO-GO
  • Week plan from schedule (Tue / Wed / Thu…) — do not wait for “what about Thursday?”
  • Best spot + rough drive distance
  • Window in local-friendly terms if you can, else UTC
  • Wind + gusts; model_agree; size for gusts
  • Kite size from quiver; wetsuit for session hours
  • Short checklist: watch beach 5 min, side-shore preference, don’t long-drive for marginal

Do not dump raw model tables unless they ask.

Hard rules

  • Use preset WINDGURU_DEFAULT only (guru best / best_forecast). Do not default to raw GFS.
  • Never scrape windguru.cz HTML, Tune UI, or MapLibre.
  • Never require PRO or invent lat/lon click-forecasts.
  • On error_type: ambiguous, pick from candidates — never silent first-match.
  • Respect retryable on errors; don’t hammer rate limits.
  • Profile lives at ~/.config/guru/profile.json (override with GURU_CONFIG_DIR).

MCP tool map

Tool Use for
instruct Load this recipe into context
get_profile / setup_profile Onboarding
weekend_spots “Where can I kite?”
search_spots / resolve_spot / near_spots Find spot ids
best_forecast (advise=true) Single spot + gear
get_forecast / list_models Escape hatches only

More: docs/mcp.md · skill copy: skills/guru/SKILL.md


Install

pipx install windguru          # CLI: guru …   ← canonical path for every app
pipx install 'windguru[mcp]'   # + optional STDIO/HTTP adapters
guru doctor --json

Or with pip: pip install windguru / pip install 'windguru[mcp]'.

PyPI: windguru

Every app: guru … --json on a host that reaches Windguru. Optional guru-mcp is the same library for STDIO hosts. Cloud sandboxes that block Windguru are unsupported — move to a local agent; do not tunnel by default.

CLI

Command Role
guru setup Rider + home range (sport / weight / level / quiver / drive_km)
guru profile Show profile + missing fields
guru weekend Where can I kite? ~4-day schedule + top-3 model agree
guru instruct Teach agents the workflow
guru spots <q> Name search (resolve id)
guru near --lat --lon Free map markers near a point
guru best <spot> Spot call + gear advice (default; --no-advise for raw)
guru forecast <spot> -m gfs Single model escape hatch
guru models / schema / doctor / wire Discoverability + network probe + optional MCP adapters

Ambiguous names fail with error_type: ambiguous + candidates (pass numeric id or --pick).

Library

from guru import get_best_forecast, search_spots
from guru.rider.advice import advise_forecast, drive_km_from_home
from guru.rider.profile_store import load_profile

spots = search_spots("castelldefels")
best = get_best_forecast(201, top=3, hours=24)
profile = load_profile()
advice = advise_forecast(
    best.forecasts[0], profile, drive_km=drive_km_from_home(profile, best.spot)
)
print(advice.verdict, advice.summary)

Develop

git clone https://github.com/berendgort/guru.git
cd guru
pipx install -e ".[dev,mcp]"
# or: python -m venv .venv && source .venv/bin/activate && pip install -e ".[dev,mcp]"
pytest -q
ruff check .
Layer Path Role
Core guru/core/ Shared envelope, errors, instruct recipe
CLI guru/cli/ Typer + Rich + --json (thin over core)
MCP guru/mcp/ FastMCP over core (no CLI imports)
Rider guru/rider/ Profile store + kite/wetsuit advice
Search guru/search/ HTTP (curl_cffi), blend_math, near, forecast
Models guru/models/ Pydantic + aliases only
Wire docs/WIRE.md Captured iapi.php
MCP docs/mcp.md guru-mcp setup + tools

Read AGENTS.md before extending. Capture Network → fixtures → tests.

Engineering standards (kept in-repo):

Disclaimer

Unofficial. Not affiliated with Windguru. Personal / research use; respect ToS and rate limits.

License

MIT

Metadata

Release files for windguru 0.3.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for windguru 0.3.14
File Size Uploaded Provenance Actions
windguru-0.3.14.tar.gz 393.8 kB Without provenance Details for windguru-0.3.14.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for windguru 0.3.14
File Interpreter ABI Platform Actions
windguru-0.3.14-py3-none-any.whl Python 3 none any Details for windguru-0.3.14-py3-none-any.whl

Total release size: 454.7 kB

Release files / windguru-0.3.14.tar.gz

Download URL windguru-0.3.14.tar.gz
Size 393.8 kB
Tags Source
SHA-256 checksum
How to use checksums
237977935e91b211eecd0c1bd088e3789383561a6ef4ad7931f27b8ed860d144
BLAKE2b-256 checksum
How to use checksums
063e3700581b5dc3b902e86662dea4fd42d474751d8ce322270b51d2b282efdd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / windguru-0.3.14-py3-none-any.whl

Download URL windguru-0.3.14-py3-none-any.whl
Size 60.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ffefe817c7fdd20e2220f497f75a7b571a405b1e0a440aae7f9949fe26d0fdf3
BLAKE2b-256 checksum
How to use checksums
9d43dd0545851c31c0944bca91c2358440059aa5f08cdaa7c52e03a0862a9826
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for windguru 0.3.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page