{
  "schemaVersion": "1.0",
  "item": {
    "slug": "windsensei",
    "name": "Windsensei",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/jumptrnr/windsensei",
    "canonicalUrl": "https://clawhub.ai/jumptrnr/windsensei",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/windsensei",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=windsensei",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/windsensei"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/windsensei",
    "agentPageUrl": "https://openagent3.xyz/skills/windsensei/agent",
    "manifestUrl": "https://openagent3.xyz/skills/windsensei/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/windsensei/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "WindSensei - Wind Forecast Assistant",
        "body": "Check wind conditions at your favorite spots and take action on good forecasts."
      },
      {
        "title": "When to Use This Skill",
        "body": "Activate when the user asks about:\n\nWind conditions, wind forecast, or weather for wind sports\n\"How's the wind?\", \"Should I go kiting?\", \"Any good wind this weekend?\"\n\"What's it looking like at [spot name]?\", \"Wind report\"\nKiting, kitesurfing, wingfoiling, windsurfing, surfing conditions\nBlocking off time or adding sessions to their calendar based on wind\nFinding spots near a location or exploring new spots\nSession history, stats, or activity logs\nWhat friends are riding right now (live sessions)"
      },
      {
        "title": "Credentials",
        "body": "WINDSENSEI_API_KEY: An API key starting with ss_. Optional — the skill works fully without it. Without it, you can still query any public spot by name, search for spots, and find spots nearby. With it, you get personalized forecasts, dashboard overview, session history, and social features.\nNo other credentials are required. This skill only makes HTTPS requests to the WindSensei API. Calendar features (if requested by the user) use the host agent's own calendar tools — this skill does not request or store any calendar credentials."
      },
      {
        "title": "Getting an API Key",
        "body": "If the user wants personalized forecasts, guide them:\n\nSign up at windsensei.com\nAdd their favorite spots and set activity preferences\nGo to their Profile page at windsensei.com/dashboard/profile — the API key manager is at the bottom of that page\nClick \"Create API Key\", give it a name (e.g., \"Claude\" or \"OpenClaw\"), and copy the key\nThe key starts with ss_ — set it as WINDSENSEI_API_KEY in the agent's environment config\n\nDirect link: https://windsensei.com/dashboard/profile (scroll to \"API Keys\" section)"
      },
      {
        "title": "Public Mode (no API key)",
        "body": "Query any public spot by name using the spot parameter\nSearch for spots by name\nFind spots near a latitude/longitude\nUses default kiting preferences (12-40kt, 8am-8pm)\nResponse includes a hint field suggesting signup for personalized results"
      },
      {
        "title": "Authenticated Mode (with API key)",
        "body": "Everything in public mode, plus:\nDashboard overview of all favorite spots in one call\nPersonalized forecasts using the user's activity preferences, wind speed ranges, time windows\nSession history and stats\nLive session feed from followed users\nFavorites list\nNo signup hint in response"
      },
      {
        "title": "Authentication",
        "body": "For all authenticated endpoints, include the API key as a Bearer token:\n\nAuthorization: Bearer {WINDSENSEI_API_KEY}\n\nThe API also accepts X-API-Key: {key} header or ?api_key={key} query param."
      },
      {
        "title": "1. Wind Report (Quick Summary)",
        "body": "The simplest way to check conditions. Returns a natural language summary plus structured data.\n\nGET https://windsensei.com/api/v1/wind-report?when={when}\n\nParamValuesDefaultDescriptionwhentoday, tomorrow, weekend, weektodayTime windowspotstring (e.g., Cherry Beach)—Search public spots by name. Not needed with API key.locationIdstring—Specific spot by IDformattext, fullfulltext returns just the summary string\n\nAuth: Optional. With API key, returns forecasts for all the user's favorite spots automatically.\n\nResponse:\n\n{\n  \"success\": true,\n  \"text\": \"Cherry Beach: Great conditions 2-6pm — 18-22kt SW, 24°C, water 19°C. Good for Kitefoil, Twintip.\",\n  \"when\": \"today\",\n  \"authenticated\": false,\n  \"hint\": \"Personalize your forecast with your own spots and activity preferences at windsensei.com\",\n  \"locations\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"timezone\": \"America/Toronto\",\n      \"blocks\": [\n        {\n          \"date\": \"2026-02-21\",\n          \"dateLabel\": \"Saturday, Feb 21\",\n          \"start\": \"14:00\",\n          \"end\": \"18:00\",\n          \"quality\": \"good\",\n          \"windSpeed\": { \"avg\": 20, \"gust\": 25 },\n          \"windDirection\": \"SW\",\n          \"windQuality\": \"good\",\n          \"temperature\": 24,\n          \"waterTemp\": 19,\n          \"activities\": [\"Kitefoil\", \"Twintip\"]\n        }\n      ]\n    }\n  ]\n}\n\nWhen no spot specified and no API key:\n\n{\n  \"success\": true,\n  \"text\": \"Provide a spot name to check conditions. Example: ?spot=Cherry Beach\",\n  \"locations\": [],\n  \"hint\": \"Personalize your forecast with your own spots and activity preferences at windsensei.com\"\n}"
      },
      {
        "title": "2. Dashboard (All Spots Overview)",
        "body": "Auth: Required. Single call to get current conditions for all the user's favorite spots, sorted best-first. The most efficient way to answer \"how's the wind?\" for authenticated users.\n\nGET https://windsensei.com/api/v1/dashboard\n\nResponse:\n\n{\n  \"success\": true,\n  \"spots\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"current\": {\n        \"windSpeed\": 18,\n        \"windGust\": 24,\n        \"windDirection\": 225,\n        \"temperature\": 22,\n        \"quality\": \"good\"\n      },\n      \"observed\": {\n        \"stationName\": \"Toronto Island\",\n        \"observationTime\": \"2026-02-21T14:00:00Z\",\n        \"windSpeed\": 20,\n        \"windDirection\": 210,\n        \"windGust\": 26,\n        \"temperature\": 21,\n        \"waterTemp\": { \"temperature\": 18.5, \"units\": \"C\" }\n      },\n      \"nextGoodWindow\": {\n        \"start\": \"2026-02-21T14:00\",\n        \"end\": \"2026-02-21T18:00\",\n        \"quality\": \"good\",\n        \"activities\": [\"Kitefoil\", \"Twintip\"]\n      },\n      \"modelConsensus\": {\n        \"agreement\": \"high\",\n        \"models\": [\"GFS\", \"ICON\", \"GEM\"]\n      }\n    }\n  ],\n  \"generatedAt\": \"2026-02-21T12:00:00Z\"\n}\n\nKey fields:\n\ncurrent: Forecast-based current conditions\nobserved: Real weather station data (if available for the spot) — more accurate than forecast\nnextGoodWindow: Next rideable time window based on the user's activity preferences. Times are in the spot's local timezone.\nmodelConsensus: Whether forecast models agree on conditions\nSpots are sorted by quality (best first), then by wind speed\n\nWhen to use dashboard vs wind-report:\n\nUse dashboard when the user has an API key and asks a general \"how's the wind?\" — it covers all their spots in one call\nUse wind-report when querying a specific spot by name, or when there's no API key"
      },
      {
        "title": "3. Best Conditions (Ranked Spots)",
        "body": "Find the best spots right now. Works with or without auth.\n\nGET https://windsensei.com/api/v1/best-conditions\n\nParamValuesDefaultDescriptionwhennow, today, tomorrow, weekendnowTime window. now = current hour onward.latnumber—Latitude (required if no API key)lngnumber—Longitude (required if no API key)radiusnumber100Search radius in km (max 500). Only used with lat/lng.limitnumber5Max results (max 20)\n\nAuth: Optional.\n\nWith API key: Evaluates the user's favorite spots using their activity preferences. No lat/lng needed.\nWithout API key: Requires lat/lng. Finds nearby public spots and evaluates with default kiting preferences.\nIf authenticated but no favorites, falls back to lat/lng nearby search.\n\nResponse:\n\n{\n  \"success\": true,\n  \"when\": \"now\",\n  \"spots\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"timezone\": \"America/Toronto\",\n      \"distance\": 4.2,\n      \"current\": {\n        \"windSpeed\": 20,\n        \"windGust\": 26,\n        \"windDirection\": \"SW\",\n        \"windQuality\": \"good\",\n        \"temperature\": 22,\n        \"quality\": \"good\"\n      },\n      \"waterTemp\": 18.5,\n      \"bestBlock\": {\n        \"date\": \"2026-02-21\",\n        \"dateLabel\": \"Saturday, Feb 21\",\n        \"start\": \"14:00\",\n        \"end\": \"18:00\",\n        \"quality\": \"good\",\n        \"windSpeed\": { \"avg\": 20, \"gust\": 26 },\n        \"windDirection\": \"SW\",\n        \"activities\": [\"Kitefoil\", \"Twintip\"]\n      },\n      \"activities\": [\"Kitefoil\", \"Twintip\"]\n    }\n  ],\n  \"total\": 1,\n  \"authenticated\": false,\n  \"hint\": \"Get personalized results with your own spots and preferences at windsensei.com\",\n  \"generatedAt\": \"2026-02-21T12:00:00Z\"\n}\n\nKey fields:\n\ndistance: Distance from the provided lat/lng in km (only present for nearby queries)\ncurrent: Conditions right now (or first hour in the time window)\nbestBlock: The best consecutive window of rideable conditions in the time range\nOnly spots with medium or better conditions are returned — bad spots are excluded\nSpots are sorted best-first by quality, then wind speed\n\nWhen to use: \"What's the best spot right now?\", \"Where should I go kiting near Toronto?\", \"Best conditions this weekend?\""
      },
      {
        "title": "4. Search Spots",
        "body": "Find spots by name. Works without auth.\n\nGET https://windsensei.com/api/v1/locations/search?q={query}\n\nParamValuesDefaultDescriptionqstring—Search query (required)limitnumber10Max results (max 50)\n\nAuth: Optional. Authenticated users also see their private spots.\n\nResponse:\n\n{\n  \"success\": true,\n  \"query\": \"cherry\",\n  \"locations\": [\n    {\n      \"_id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": [\"SW\", \"S\", \"W\"],\n      \"isFavorite\": false\n    }\n  ],\n  \"total\": 1\n}\n\nWhen to use: To resolve a spot name to a locationId for use with other endpoints, or when the user wants to browse available spots."
      },
      {
        "title": "5. Nearby Spots",
        "body": "Find spots near a location. Works without auth.\n\nGET https://windsensei.com/api/v1/locations/nearby?lat={lat}&lng={lng}\n\nParamValuesDefaultDescriptionlatnumber—Latitude (required)lngnumber—Longitude (required)radiusnumber50Radius in km (max 500)limitnumber10Max results (max 50)\n\nAuth: Optional. Authenticated users also see private spots.\n\nResponse:\n\n{\n  \"success\": true,\n  \"center\": { \"lat\": 43.65, \"lng\": -79.38 },\n  \"radiusKm\": 50,\n  \"locations\": [\n    {\n      \"id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"distance\": 4.2,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": { \"SW\": \"good\", \"S\": \"medium\", \"W\": \"good\" },\n      \"isFavorite\": false\n    }\n  ],\n  \"total\": 3\n}\n\nWhen to use: When the user says \"what spots are near me?\", \"spots near Toronto\", or \"find kite spots in [city]\". You'll need to geocode the city/location to lat/lng first (use the agent's geocoding capability or a known coordinate)."
      },
      {
        "title": "6. Detailed Forecast",
        "body": "Full hourly forecast for a specific spot. More detailed than wind-report.\n\nGET https://windsensei.com/api/v1/forecast/{locationId}/full\n\nAuth: Required. Returns personalized quality ratings based on the user's activity preferences.\n\nResponse includes:\n\nHourly wind speed, direction, gusts, temperature, precipitation\nTime blocks with quality ratings (excellent/good/medium)\nTide predictions (high/low times)\nWater temperature\nModel consensus data\nUp to 16 days of forecast\n\nWhen to use: When the user wants hour-by-hour detail, or asks \"when exactly is the best window?\" after seeing a summary."
      },
      {
        "title": "7. Favorites List",
        "body": "Get the user's favorite spots in their saved order.\n\nGET https://windsensei.com/api/v1/favorites\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"locations\": [\n    {\n      \"_id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": [\"SW\", \"S\", \"W\"],\n      \"isFavorite\": true\n    }\n  ]\n}\n\nWhen to use: When the user asks \"what are my spots?\" or \"list my favorites.\""
      },
      {
        "title": "8. Session History",
        "body": "Get the user's logged wind sport sessions.\n\nGET https://windsensei.com/api/v1/sessions\n\nParamValuesDefaultDescriptionlimitnumber20Max results (max 100)offsetnumber0Pagination offsetactivityTypestring—Filter by activity (e.g., \"Kitefoil\", \"Wingfoil\")locationIdstring—Filter by spot\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"sessions\": [\n    {\n      \"id\": \"sess123\",\n      \"activityType\": \"Kitefoil\",\n      \"locationName\": \"Cherry Beach\",\n      \"startTime\": \"2026-02-15T14:00:00Z\",\n      \"endTime\": \"2026-02-15T17:30:00Z\",\n      \"duration\": 12600,\n      \"rating\": 4,\n      \"notes\": \"Great session, consistent SW wind\",\n      \"stats\": {\n        \"distance\": 15.2,\n        \"maxSpeed\": 32.5\n      }\n    }\n  ],\n  \"pagination\": {\n    \"total\": 47,\n    \"limit\": 20,\n    \"offset\": 0,\n    \"hasMore\": true\n  }\n}\n\nWhen to use: When the user asks \"how many sessions have I had?\", \"show my recent sessions\", \"what was my last kite session?\", or \"how much have I ridden this month?\""
      },
      {
        "title": "9. Live Sessions (Friends Activity)",
        "body": "See which followed users are currently out riding.\n\nGET https://windsensei.com/api/v1/live-sessions\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"data\": {\n    \"sessions\": [\n      {\n        \"id\": \"live123\",\n        \"user\": {\n          \"name\": \"Mike\",\n          \"nickname\": \"windmike\"\n        },\n        \"activityType\": \"Wingfoil\",\n        \"spotName\": \"Cherry Beach\",\n        \"startTime\": \"2026-02-21T14:00:00Z\",\n        \"lastUpdateTime\": \"2026-02-21T14:30:00Z\",\n        \"stats\": {\n          \"elapsedTime\": 1800,\n          \"distance\": 3.2,\n          \"maxSpeed\": 22.1\n        },\n        \"conditions\": {\n          \"windSpeed\": 18,\n          \"windDirection\": \"SW\"\n        }\n      }\n    ]\n  }\n}\n\nWhen to use: When the user asks \"is anyone out right now?\", \"who's riding?\", or \"are any of my friends on the water?\""
      },
      {
        "title": "10. Public Profile",
        "body": "Look up any WindSensei user's public stats by their handle. No auth needed.\n\nGET https://windsensei.com/api/public/profile/{nickname}\n\nAuth: None.\n\nResponse includes: nickname, avatar, total session count, total duration, total distance, recent public sessions, activity types.\n\nWhen to use: When the user asks about a specific rider's profile or stats."
      },
      {
        "title": "11. Request a New Spot",
        "body": "Submit a request to add a spot that isn't in the system yet.\n\nPOST https://windsensei.com/api/v1/spot-request\nContent-Type: application/json\n\n{\n  \"spotName\": \"Spot Name Here\"\n}\n\nAuth: Optional. If API key is included, the request is attributed to the user.\n\nResponse:\n\n{\n  \"success\": true,\n  \"message\": \"Spot request for \\\"Spot Name\\\" submitted. We'll review it soon.\"\n}\n\nDuplicate requests are handled automatically — just returns success."
      },
      {
        "title": "Interpreting the Data",
        "body": "CRITICAL: Only report what the API data says. Do NOT:\n\nMake up or guess whether conditions are good if the API didn't say so\nAdd your own assessment of wind speeds, directions, or quality beyond what the quality and windQuality fields state\nSpeculate about conditions outside the blocks returned (e.g., \"morning might be OK too\")\nEditorialize about whether the user should or shouldn't go — the blocks and quality ratings ARE the answer\nInfer activities beyond what the activities array lists for each block\n\nIf blocks is empty for a location, there are NO good conditions. Period. Don't soften this or suggest the user check anyway.\n\nIf blocks exist, they represent the API's definitive assessment — the quality, wind speed, direction, and activities are computed from the user's preferences and the spot's characteristics. Trust them exactly as returned.\n\ntimezone: Each location includes a timezone field (e.g., \"America/Toronto\"). All times in start, end, and date fields are in this timezone — not UTC, not the user's local time. When presenting times to the user, always clarify the timezone if it differs from the user's location (e.g., \"2-6pm EST\").\nquality: \"excellent\" > \"good\" > \"medium\". Only these appear — bad hours are excluded. Use these exact ratings when describing conditions.\nwindQuality: How good the wind direction is for that spot (\"good\", \"medium\", \"bad\"). This is computed from the spot's known best directions — don't override it.\nblocks: Each block is a continuous window of rideable conditions. Multiple blocks per location/day are possible. If no blocks exist, there are no rideable conditions.\nactivities: Which wind sports suit the conditions (e.g., \"Kitefoil\", \"Twintip\", \"Wingfoil\"). Only mention activities listed in the block.\nobserved vs current: observed comes from real weather stations and is more accurate. current is forecast-based. Prefer observed data when available.\nmodelConsensus: When agreement is \"high\", the forecast is more reliable.\nauthenticated: Whether the response used personalized preferences. If false, mention the user can get better results by setting up an API key.\nhint: Present only for unauthenticated queries. Relay this to the user naturally (e.g., at the end of the first response, not every time)."
      },
      {
        "title": "Responding to the User",
        "body": "Relay the text field first (when using wind-report) — it's already a concise, factual summary.\nIf the user wants more detail, use the structured blocks data to elaborate — but stick to what the data says.\nFor \"no good conditions\" results (empty blocks), be straightforward: \"Nothing rideable today at Cherry Beach.\" Don't add speculation about what might work.\nIf hint is present in the response, casually mention it the first time: \"By the way, you can get personalized forecasts for your spots at windsensei.com\"\nWhen using dashboard data, lead with the best spot and summarize the rest.\nDon't pad with filler. Be direct, like a friend at the beach.\nNever contradict the API's quality assessment. If the API says \"medium\" quality, don't upgrade it to \"great conditions.\" If the API says no blocks, don't say \"it might still be worth checking.\""
      },
      {
        "title": "Choosing the Right Endpoint",
        "body": "User intentEndpointAuth needed?\"How's the wind?\" (has API key)DashboardYes\"How's the wind at Cherry Beach?\"Wind Report with spot=No\"How's the wind this weekend?\"Wind Report with when=weekendNo\"What's the best spot right now?\"Best ConditionsNo (lat/lng) or Yes\"Where should I kite near Miami?\"Best Conditions with lat/lngNo\"What spots are near Toronto?\"Nearby (geocode city first)No\"Find spots called 'cherry'\"Search with q=cherryNo\"Give me hour-by-hour for Cherry Beach\"Forecast FullYes\"What are my spots?\"FavoritesYes\"How many sessions have I had?\"SessionsYes\"Is anyone riding right now?\"Live SessionsYes\"Show me @windmike's profile\"Public ProfileNo\"Add Wasaga Beach\" (spot not found)Spot RequestNo"
      },
      {
        "title": "Handling Spot Names",
        "body": "When the user says \"how's the wind at Cherry Beach\":\n\nExtract the spot name (\"Cherry Beach\")\nURL-encode it and pass as ?spot=Cherry+Beach to wind-report\nThe API does fuzzy matching — partial names work (e.g., \"cherry\" matches \"Cherry Beach\")\nIf multiple spots match, the API returns up to 3. Present all of them.\n\nFor more control, use the Search endpoint first to resolve the name to a locationId, then use that ID with other endpoints."
      },
      {
        "title": "Handling Missing Spots",
        "body": "When a spot isn't found:\n\nTell the user: \"WindSensei doesn't have data for that spot yet.\"\nAsk: \"Want me to submit a request to add it?\"\nIf they say yes, POST to /api/v1/spot-request with the spot name.\nRelay the confirmation message."
      },
      {
        "title": "Calendar Integration",
        "body": "This skill does not provide or require any calendar credentials. It relies on the host agent's existing calendar tools (e.g., Google Calendar MCP, Apple Calendar, etc.). If the agent has no calendar tool available, skip calendar actions and just present the forecast data.\n\nWhen the user asks to \"block off\", \"add to calendar\", or \"schedule\" a session based on a wind block:\n\nUse the block data to create a calendar event via the agent's calendar tool:\n\nTitle: Kite @ {location name} (or the relevant activity from the block)\nStart: The block's date + start time\nEnd: The block's date + end time\nDescription: {windSpeed.avg}kt {windDirection} (gusts {windSpeed.gust}kt), {temperature}°C{waterTemp ? ', water ' + waterTemp + '°C' : ''}. Quality: {quality}.\nLocation: The spot name\n\n\n\nConfirm to the user what was added.\n\n\nIf no calendar tool is available, offer the event details so the user can add it manually.\n\nIf there are multiple good blocks, ask which one(s) to add unless the user said \"all\"."
      },
      {
        "title": "Example Conversations",
        "body": "First-time user, no API key:\n\nUser: \"How's the wind at Cherry Beach?\"\n→ Call GET /api/v1/wind-report?spot=Cherry+Beach&when=today\n→ Relay the text field\n→ Mention: \"For personalized forecasts with your own spots, check out windsensei.com\"\n\nAuthenticated user, quick check:\n\nUser: \"How's the wind?\"\n→ Call GET /api/v1/dashboard (with Bearer token)\n→ Summarize: lead with the best spot, mention the rest\n\nBest spot right now (unauthenticated):\n\nUser: \"Where should I go kiting near Miami?\"\n→ Geocode Miami to lat=25.76, lng=-80.19\n→ Call GET /api/v1/best-conditions?lat=25.76&lng=-80.19&when=now\n→ \"Crandon Park has the best conditions right now — 18kt SE, good direction, 28°C. Best window is 2-6pm.\"\n\nBest spot right now (authenticated):\n\nUser: \"What's my best spot today?\"\n→ Call GET /api/v1/best-conditions?when=today (with Bearer token)\n→ \"Cherry Beach looks best today — good conditions 2-6pm with 20kt SW. Hanlan's has medium conditions 1-4pm.\"\n\nFinding new spots:\n\nUser: \"What kite spots are near Miami?\"\n→ Geocode Miami to lat=25.76, lng=-80.19\n→ Call GET /api/v1/locations/nearby?lat=25.76&lng=-80.19&radius=100\n→ Present the spots with distances\n\nSession stats:\n\nUser: \"How many sessions have I logged this year?\"\n→ Call GET /api/v1/sessions?limit=100\n→ Count and summarize by activity type\n\nLive check:\n\nUser: \"Is anyone out riding right now?\"\n→ Call GET /api/v1/live-sessions\n→ \"Your friend Mike is wingfoiling at Cherry Beach — been out for 30 minutes in 18kt SW wind\"\n\nCalendar action:\n\nUser: \"Block off the good times this weekend\"\n→ Call GET /api/v1/wind-report?when=weekend\n→ For each block, create a calendar event\n→ \"Added 2 sessions to your calendar: Kite @ Cherry Beach Sat 2-6pm, Wing @ Hanlan's Sun 10am-1pm\"\n\nSpecific day:\n\nUser: \"What about Saturday?\"\n→ Call GET /api/v1/wind-report?when=weekend\n→ Relay the relevant day from the response\n\nNo conditions:\n\nUser: \"Should I go kiting tomorrow?\"\n→ Call GET /api/v1/wind-report?when=tomorrow\n→ If no blocks: \"No rideable conditions tomorrow at [spot name].\"\n\nMissing spot:\n\nUser: \"How's the wind at Wasaga Beach?\"\n→ Call GET /api/v1/wind-report?spot=Wasaga+Beach\n→ Response: not found\n→ Reply: \"WindSensei doesn't have data for Wasaga Beach yet. Want me to submit a request to add it?\"\nUser: \"Yeah, do it\"\n→ Call POST /api/v1/spot-request with {\"spotName\": \"Wasaga Beach\"}\n→ Reply: \"Done — submitted a request to add Wasaga Beach. The WindSensei team will review it.\""
      }
    ],
    "body": "WindSensei - Wind Forecast Assistant\n\nCheck wind conditions at your favorite spots and take action on good forecasts.\n\nWhen to Use This Skill\n\nActivate when the user asks about:\n\nWind conditions, wind forecast, or weather for wind sports\n\"How's the wind?\", \"Should I go kiting?\", \"Any good wind this weekend?\"\n\"What's it looking like at [spot name]?\", \"Wind report\"\nKiting, kitesurfing, wingfoiling, windsurfing, surfing conditions\nBlocking off time or adding sessions to their calendar based on wind\nFinding spots near a location or exploring new spots\nSession history, stats, or activity logs\nWhat friends are riding right now (live sessions)\nConfiguration\nCredentials\nWINDSENSEI_API_KEY: An API key starting with ss_. Optional — the skill works fully without it. Without it, you can still query any public spot by name, search for spots, and find spots nearby. With it, you get personalized forecasts, dashboard overview, session history, and social features.\nNo other credentials are required. This skill only makes HTTPS requests to the WindSensei API. Calendar features (if requested by the user) use the host agent's own calendar tools — this skill does not request or store any calendar credentials.\nGetting an API Key\n\nIf the user wants personalized forecasts, guide them:\n\nSign up at windsensei.com\nAdd their favorite spots and set activity preferences\nGo to their Profile page at windsensei.com/dashboard/profile — the API key manager is at the bottom of that page\nClick \"Create API Key\", give it a name (e.g., \"Claude\" or \"OpenClaw\"), and copy the key\nThe key starts with ss_ — set it as WINDSENSEI_API_KEY in the agent's environment config\n\nDirect link: https://windsensei.com/dashboard/profile (scroll to \"API Keys\" section)\n\nTwo Modes\nPublic Mode (no API key)\nQuery any public spot by name using the spot parameter\nSearch for spots by name\nFind spots near a latitude/longitude\nUses default kiting preferences (12-40kt, 8am-8pm)\nResponse includes a hint field suggesting signup for personalized results\nAuthenticated Mode (with API key)\nEverything in public mode, plus:\nDashboard overview of all favorite spots in one call\nPersonalized forecasts using the user's activity preferences, wind speed ranges, time windows\nSession history and stats\nLive session feed from followed users\nFavorites list\nNo signup hint in response\nAuthentication\n\nFor all authenticated endpoints, include the API key as a Bearer token:\n\nAuthorization: Bearer {WINDSENSEI_API_KEY}\n\n\nThe API also accepts X-API-Key: {key} header or ?api_key={key} query param.\n\nAPI Endpoints\n1. Wind Report (Quick Summary)\n\nThe simplest way to check conditions. Returns a natural language summary plus structured data.\n\nGET https://windsensei.com/api/v1/wind-report?when={when}\n\nParam\tValues\tDefault\tDescription\nwhen\ttoday, tomorrow, weekend, week\ttoday\tTime window\nspot\tstring (e.g., Cherry Beach)\t—\tSearch public spots by name. Not needed with API key.\nlocationId\tstring\t—\tSpecific spot by ID\nformat\ttext, full\tfull\ttext returns just the summary string\n\nAuth: Optional. With API key, returns forecasts for all the user's favorite spots automatically.\n\nResponse:\n\n{\n  \"success\": true,\n  \"text\": \"Cherry Beach: Great conditions 2-6pm — 18-22kt SW, 24°C, water 19°C. Good for Kitefoil, Twintip.\",\n  \"when\": \"today\",\n  \"authenticated\": false,\n  \"hint\": \"Personalize your forecast with your own spots and activity preferences at windsensei.com\",\n  \"locations\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"timezone\": \"America/Toronto\",\n      \"blocks\": [\n        {\n          \"date\": \"2026-02-21\",\n          \"dateLabel\": \"Saturday, Feb 21\",\n          \"start\": \"14:00\",\n          \"end\": \"18:00\",\n          \"quality\": \"good\",\n          \"windSpeed\": { \"avg\": 20, \"gust\": 25 },\n          \"windDirection\": \"SW\",\n          \"windQuality\": \"good\",\n          \"temperature\": 24,\n          \"waterTemp\": 19,\n          \"activities\": [\"Kitefoil\", \"Twintip\"]\n        }\n      ]\n    }\n  ]\n}\n\n\nWhen no spot specified and no API key:\n\n{\n  \"success\": true,\n  \"text\": \"Provide a spot name to check conditions. Example: ?spot=Cherry Beach\",\n  \"locations\": [],\n  \"hint\": \"Personalize your forecast with your own spots and activity preferences at windsensei.com\"\n}\n\n2. Dashboard (All Spots Overview)\n\nAuth: Required. Single call to get current conditions for all the user's favorite spots, sorted best-first. The most efficient way to answer \"how's the wind?\" for authenticated users.\n\nGET https://windsensei.com/api/v1/dashboard\n\n\nResponse:\n\n{\n  \"success\": true,\n  \"spots\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"current\": {\n        \"windSpeed\": 18,\n        \"windGust\": 24,\n        \"windDirection\": 225,\n        \"temperature\": 22,\n        \"quality\": \"good\"\n      },\n      \"observed\": {\n        \"stationName\": \"Toronto Island\",\n        \"observationTime\": \"2026-02-21T14:00:00Z\",\n        \"windSpeed\": 20,\n        \"windDirection\": 210,\n        \"windGust\": 26,\n        \"temperature\": 21,\n        \"waterTemp\": { \"temperature\": 18.5, \"units\": \"C\" }\n      },\n      \"nextGoodWindow\": {\n        \"start\": \"2026-02-21T14:00\",\n        \"end\": \"2026-02-21T18:00\",\n        \"quality\": \"good\",\n        \"activities\": [\"Kitefoil\", \"Twintip\"]\n      },\n      \"modelConsensus\": {\n        \"agreement\": \"high\",\n        \"models\": [\"GFS\", \"ICON\", \"GEM\"]\n      }\n    }\n  ],\n  \"generatedAt\": \"2026-02-21T12:00:00Z\"\n}\n\n\nKey fields:\n\ncurrent: Forecast-based current conditions\nobserved: Real weather station data (if available for the spot) — more accurate than forecast\nnextGoodWindow: Next rideable time window based on the user's activity preferences. Times are in the spot's local timezone.\nmodelConsensus: Whether forecast models agree on conditions\nSpots are sorted by quality (best first), then by wind speed\n\nWhen to use dashboard vs wind-report:\n\nUse dashboard when the user has an API key and asks a general \"how's the wind?\" — it covers all their spots in one call\nUse wind-report when querying a specific spot by name, or when there's no API key\n3. Best Conditions (Ranked Spots)\n\nFind the best spots right now. Works with or without auth.\n\nGET https://windsensei.com/api/v1/best-conditions\n\nParam\tValues\tDefault\tDescription\nwhen\tnow, today, tomorrow, weekend\tnow\tTime window. now = current hour onward.\nlat\tnumber\t—\tLatitude (required if no API key)\nlng\tnumber\t—\tLongitude (required if no API key)\nradius\tnumber\t100\tSearch radius in km (max 500). Only used with lat/lng.\nlimit\tnumber\t5\tMax results (max 20)\n\nAuth: Optional.\n\nWith API key: Evaluates the user's favorite spots using their activity preferences. No lat/lng needed.\nWithout API key: Requires lat/lng. Finds nearby public spots and evaluates with default kiting preferences.\nIf authenticated but no favorites, falls back to lat/lng nearby search.\n\nResponse:\n\n{\n  \"success\": true,\n  \"when\": \"now\",\n  \"spots\": [\n    {\n      \"locationId\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"timezone\": \"America/Toronto\",\n      \"distance\": 4.2,\n      \"current\": {\n        \"windSpeed\": 20,\n        \"windGust\": 26,\n        \"windDirection\": \"SW\",\n        \"windQuality\": \"good\",\n        \"temperature\": 22,\n        \"quality\": \"good\"\n      },\n      \"waterTemp\": 18.5,\n      \"bestBlock\": {\n        \"date\": \"2026-02-21\",\n        \"dateLabel\": \"Saturday, Feb 21\",\n        \"start\": \"14:00\",\n        \"end\": \"18:00\",\n        \"quality\": \"good\",\n        \"windSpeed\": { \"avg\": 20, \"gust\": 26 },\n        \"windDirection\": \"SW\",\n        \"activities\": [\"Kitefoil\", \"Twintip\"]\n      },\n      \"activities\": [\"Kitefoil\", \"Twintip\"]\n    }\n  ],\n  \"total\": 1,\n  \"authenticated\": false,\n  \"hint\": \"Get personalized results with your own spots and preferences at windsensei.com\",\n  \"generatedAt\": \"2026-02-21T12:00:00Z\"\n}\n\n\nKey fields:\n\ndistance: Distance from the provided lat/lng in km (only present for nearby queries)\ncurrent: Conditions right now (or first hour in the time window)\nbestBlock: The best consecutive window of rideable conditions in the time range\nOnly spots with medium or better conditions are returned — bad spots are excluded\nSpots are sorted best-first by quality, then wind speed\n\nWhen to use: \"What's the best spot right now?\", \"Where should I go kiting near Toronto?\", \"Best conditions this weekend?\"\n\n4. Search Spots\n\nFind spots by name. Works without auth.\n\nGET https://windsensei.com/api/v1/locations/search?q={query}\n\nParam\tValues\tDefault\tDescription\nq\tstring\t—\tSearch query (required)\nlimit\tnumber\t10\tMax results (max 50)\n\nAuth: Optional. Authenticated users also see their private spots.\n\nResponse:\n\n{\n  \"success\": true,\n  \"query\": \"cherry\",\n  \"locations\": [\n    {\n      \"_id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": [\"SW\", \"S\", \"W\"],\n      \"isFavorite\": false\n    }\n  ],\n  \"total\": 1\n}\n\n\nWhen to use: To resolve a spot name to a locationId for use with other endpoints, or when the user wants to browse available spots.\n\n5. Nearby Spots\n\nFind spots near a location. Works without auth.\n\nGET https://windsensei.com/api/v1/locations/nearby?lat={lat}&lng={lng}\n\nParam\tValues\tDefault\tDescription\nlat\tnumber\t—\tLatitude (required)\nlng\tnumber\t—\tLongitude (required)\nradius\tnumber\t50\tRadius in km (max 500)\nlimit\tnumber\t10\tMax results (max 50)\n\nAuth: Optional. Authenticated users also see private spots.\n\nResponse:\n\n{\n  \"success\": true,\n  \"center\": { \"lat\": 43.65, \"lng\": -79.38 },\n  \"radiusKm\": 50,\n  \"locations\": [\n    {\n      \"id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"distance\": 4.2,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": { \"SW\": \"good\", \"S\": \"medium\", \"W\": \"good\" },\n      \"isFavorite\": false\n    }\n  ],\n  \"total\": 3\n}\n\n\nWhen to use: When the user says \"what spots are near me?\", \"spots near Toronto\", or \"find kite spots in [city]\". You'll need to geocode the city/location to lat/lng first (use the agent's geocoding capability or a known coordinate).\n\n6. Detailed Forecast\n\nFull hourly forecast for a specific spot. More detailed than wind-report.\n\nGET https://windsensei.com/api/v1/forecast/{locationId}/full\n\n\nAuth: Required. Returns personalized quality ratings based on the user's activity preferences.\n\nResponse includes:\n\nHourly wind speed, direction, gusts, temperature, precipitation\nTime blocks with quality ratings (excellent/good/medium)\nTide predictions (high/low times)\nWater temperature\nModel consensus data\nUp to 16 days of forecast\n\nWhen to use: When the user wants hour-by-hour detail, or asks \"when exactly is the best window?\" after seeing a summary.\n\n7. Favorites List\n\nGet the user's favorite spots in their saved order.\n\nGET https://windsensei.com/api/v1/favorites\n\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"locations\": [\n    {\n      \"_id\": \"abc123\",\n      \"name\": \"Cherry Beach\",\n      \"latitude\": 43.63,\n      \"longitude\": -79.34,\n      \"activityTypes\": [\"kite\"],\n      \"windDirections\": [\"SW\", \"S\", \"W\"],\n      \"isFavorite\": true\n    }\n  ]\n}\n\n\nWhen to use: When the user asks \"what are my spots?\" or \"list my favorites.\"\n\n8. Session History\n\nGet the user's logged wind sport sessions.\n\nGET https://windsensei.com/api/v1/sessions\n\nParam\tValues\tDefault\tDescription\nlimit\tnumber\t20\tMax results (max 100)\noffset\tnumber\t0\tPagination offset\nactivityType\tstring\t—\tFilter by activity (e.g., \"Kitefoil\", \"Wingfoil\")\nlocationId\tstring\t—\tFilter by spot\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"sessions\": [\n    {\n      \"id\": \"sess123\",\n      \"activityType\": \"Kitefoil\",\n      \"locationName\": \"Cherry Beach\",\n      \"startTime\": \"2026-02-15T14:00:00Z\",\n      \"endTime\": \"2026-02-15T17:30:00Z\",\n      \"duration\": 12600,\n      \"rating\": 4,\n      \"notes\": \"Great session, consistent SW wind\",\n      \"stats\": {\n        \"distance\": 15.2,\n        \"maxSpeed\": 32.5\n      }\n    }\n  ],\n  \"pagination\": {\n    \"total\": 47,\n    \"limit\": 20,\n    \"offset\": 0,\n    \"hasMore\": true\n  }\n}\n\n\nWhen to use: When the user asks \"how many sessions have I had?\", \"show my recent sessions\", \"what was my last kite session?\", or \"how much have I ridden this month?\"\n\n9. Live Sessions (Friends Activity)\n\nSee which followed users are currently out riding.\n\nGET https://windsensei.com/api/v1/live-sessions\n\n\nAuth: Required.\n\nResponse:\n\n{\n  \"success\": true,\n  \"data\": {\n    \"sessions\": [\n      {\n        \"id\": \"live123\",\n        \"user\": {\n          \"name\": \"Mike\",\n          \"nickname\": \"windmike\"\n        },\n        \"activityType\": \"Wingfoil\",\n        \"spotName\": \"Cherry Beach\",\n        \"startTime\": \"2026-02-21T14:00:00Z\",\n        \"lastUpdateTime\": \"2026-02-21T14:30:00Z\",\n        \"stats\": {\n          \"elapsedTime\": 1800,\n          \"distance\": 3.2,\n          \"maxSpeed\": 22.1\n        },\n        \"conditions\": {\n          \"windSpeed\": 18,\n          \"windDirection\": \"SW\"\n        }\n      }\n    ]\n  }\n}\n\n\nWhen to use: When the user asks \"is anyone out right now?\", \"who's riding?\", or \"are any of my friends on the water?\"\n\n10. Public Profile\n\nLook up any WindSensei user's public stats by their handle. No auth needed.\n\nGET https://windsensei.com/api/public/profile/{nickname}\n\n\nAuth: None.\n\nResponse includes: nickname, avatar, total session count, total duration, total distance, recent public sessions, activity types.\n\nWhen to use: When the user asks about a specific rider's profile or stats.\n\n11. Request a New Spot\n\nSubmit a request to add a spot that isn't in the system yet.\n\nPOST https://windsensei.com/api/v1/spot-request\nContent-Type: application/json\n\n{\n  \"spotName\": \"Spot Name Here\"\n}\n\n\nAuth: Optional. If API key is included, the request is attributed to the user.\n\nResponse:\n\n{\n  \"success\": true,\n  \"message\": \"Spot request for \\\"Spot Name\\\" submitted. We'll review it soon.\"\n}\n\n\nDuplicate requests are handled automatically — just returns success.\n\nInterpreting the Data\n\nCRITICAL: Only report what the API data says. Do NOT:\n\nMake up or guess whether conditions are good if the API didn't say so\nAdd your own assessment of wind speeds, directions, or quality beyond what the quality and windQuality fields state\nSpeculate about conditions outside the blocks returned (e.g., \"morning might be OK too\")\nEditorialize about whether the user should or shouldn't go — the blocks and quality ratings ARE the answer\nInfer activities beyond what the activities array lists for each block\n\nIf blocks is empty for a location, there are NO good conditions. Period. Don't soften this or suggest the user check anyway.\n\nIf blocks exist, they represent the API's definitive assessment — the quality, wind speed, direction, and activities are computed from the user's preferences and the spot's characteristics. Trust them exactly as returned.\n\ntimezone: Each location includes a timezone field (e.g., \"America/Toronto\"). All times in start, end, and date fields are in this timezone — not UTC, not the user's local time. When presenting times to the user, always clarify the timezone if it differs from the user's location (e.g., \"2-6pm EST\").\nquality: \"excellent\" > \"good\" > \"medium\". Only these appear — bad hours are excluded. Use these exact ratings when describing conditions.\nwindQuality: How good the wind direction is for that spot (\"good\", \"medium\", \"bad\"). This is computed from the spot's known best directions — don't override it.\nblocks: Each block is a continuous window of rideable conditions. Multiple blocks per location/day are possible. If no blocks exist, there are no rideable conditions.\nactivities: Which wind sports suit the conditions (e.g., \"Kitefoil\", \"Twintip\", \"Wingfoil\"). Only mention activities listed in the block.\nobserved vs current: observed comes from real weather stations and is more accurate. current is forecast-based. Prefer observed data when available.\nmodelConsensus: When agreement is \"high\", the forecast is more reliable.\nauthenticated: Whether the response used personalized preferences. If false, mention the user can get better results by setting up an API key.\nhint: Present only for unauthenticated queries. Relay this to the user naturally (e.g., at the end of the first response, not every time).\nResponding to the User\nRelay the text field first (when using wind-report) — it's already a concise, factual summary.\nIf the user wants more detail, use the structured blocks data to elaborate — but stick to what the data says.\nFor \"no good conditions\" results (empty blocks), be straightforward: \"Nothing rideable today at Cherry Beach.\" Don't add speculation about what might work.\nIf hint is present in the response, casually mention it the first time: \"By the way, you can get personalized forecasts for your spots at windsensei.com\"\nWhen using dashboard data, lead with the best spot and summarize the rest.\nDon't pad with filler. Be direct, like a friend at the beach.\nNever contradict the API's quality assessment. If the API says \"medium\" quality, don't upgrade it to \"great conditions.\" If the API says no blocks, don't say \"it might still be worth checking.\"\nChoosing the Right Endpoint\nUser intent\tEndpoint\tAuth needed?\n\"How's the wind?\" (has API key)\tDashboard\tYes\n\"How's the wind at Cherry Beach?\"\tWind Report with spot=\tNo\n\"How's the wind this weekend?\"\tWind Report with when=weekend\tNo\n\"What's the best spot right now?\"\tBest Conditions\tNo (lat/lng) or Yes\n\"Where should I kite near Miami?\"\tBest Conditions with lat/lng\tNo\n\"What spots are near Toronto?\"\tNearby (geocode city first)\tNo\n\"Find spots called 'cherry'\"\tSearch with q=cherry\tNo\n\"Give me hour-by-hour for Cherry Beach\"\tForecast Full\tYes\n\"What are my spots?\"\tFavorites\tYes\n\"How many sessions have I had?\"\tSessions\tYes\n\"Is anyone riding right now?\"\tLive Sessions\tYes\n\"Show me @windmike's profile\"\tPublic Profile\tNo\n\"Add Wasaga Beach\" (spot not found)\tSpot Request\tNo\nHandling Spot Names\n\nWhen the user says \"how's the wind at Cherry Beach\":\n\nExtract the spot name (\"Cherry Beach\")\nURL-encode it and pass as ?spot=Cherry+Beach to wind-report\nThe API does fuzzy matching — partial names work (e.g., \"cherry\" matches \"Cherry Beach\")\nIf multiple spots match, the API returns up to 3. Present all of them.\n\nFor more control, use the Search endpoint first to resolve the name to a locationId, then use that ID with other endpoints.\n\nHandling Missing Spots\n\nWhen a spot isn't found:\n\nTell the user: \"WindSensei doesn't have data for that spot yet.\"\nAsk: \"Want me to submit a request to add it?\"\nIf they say yes, POST to /api/v1/spot-request with the spot name.\nRelay the confirmation message.\nCalendar Integration\n\nThis skill does not provide or require any calendar credentials. It relies on the host agent's existing calendar tools (e.g., Google Calendar MCP, Apple Calendar, etc.). If the agent has no calendar tool available, skip calendar actions and just present the forecast data.\n\nWhen the user asks to \"block off\", \"add to calendar\", or \"schedule\" a session based on a wind block:\n\nUse the block data to create a calendar event via the agent's calendar tool:\n\nTitle: Kite @ {location name} (or the relevant activity from the block)\nStart: The block's date + start time\nEnd: The block's date + end time\nDescription: {windSpeed.avg}kt {windDirection} (gusts {windSpeed.gust}kt), {temperature}°C{waterTemp ? ', water ' + waterTemp + '°C' : ''}. Quality: {quality}.\nLocation: The spot name\n\nConfirm to the user what was added.\n\nIf no calendar tool is available, offer the event details so the user can add it manually.\n\nIf there are multiple good blocks, ask which one(s) to add unless the user said \"all\".\n\nExample Conversations\n\nFirst-time user, no API key:\n\nUser: \"How's the wind at Cherry Beach?\" → Call GET /api/v1/wind-report?spot=Cherry+Beach&when=today → Relay the text field → Mention: \"For personalized forecasts with your own spots, check out windsensei.com\"\n\nAuthenticated user, quick check:\n\nUser: \"How's the wind?\" → Call GET /api/v1/dashboard (with Bearer token) → Summarize: lead with the best spot, mention the rest\n\nBest spot right now (unauthenticated):\n\nUser: \"Where should I go kiting near Miami?\" → Geocode Miami to lat=25.76, lng=-80.19 → Call GET /api/v1/best-conditions?lat=25.76&lng=-80.19&when=now → \"Crandon Park has the best conditions right now — 18kt SE, good direction, 28°C. Best window is 2-6pm.\"\n\nBest spot right now (authenticated):\n\nUser: \"What's my best spot today?\" → Call GET /api/v1/best-conditions?when=today (with Bearer token) → \"Cherry Beach looks best today — good conditions 2-6pm with 20kt SW. Hanlan's has medium conditions 1-4pm.\"\n\nFinding new spots:\n\nUser: \"What kite spots are near Miami?\" → Geocode Miami to lat=25.76, lng=-80.19 → Call GET /api/v1/locations/nearby?lat=25.76&lng=-80.19&radius=100 → Present the spots with distances\n\nSession stats:\n\nUser: \"How many sessions have I logged this year?\" → Call GET /api/v1/sessions?limit=100 → Count and summarize by activity type\n\nLive check:\n\nUser: \"Is anyone out riding right now?\" → Call GET /api/v1/live-sessions → \"Your friend Mike is wingfoiling at Cherry Beach — been out for 30 minutes in 18kt SW wind\"\n\nCalendar action:\n\nUser: \"Block off the good times this weekend\" → Call GET /api/v1/wind-report?when=weekend → For each block, create a calendar event → \"Added 2 sessions to your calendar: Kite @ Cherry Beach Sat 2-6pm, Wing @ Hanlan's Sun 10am-1pm\"\n\nSpecific day:\n\nUser: \"What about Saturday?\" → Call GET /api/v1/wind-report?when=weekend → Relay the relevant day from the response\n\nNo conditions:\n\nUser: \"Should I go kiting tomorrow?\" → Call GET /api/v1/wind-report?when=tomorrow → If no blocks: \"No rideable conditions tomorrow at [spot name].\"\n\nMissing spot:\n\nUser: \"How's the wind at Wasaga Beach?\" → Call GET /api/v1/wind-report?spot=Wasaga+Beach → Response: not found → Reply: \"WindSensei doesn't have data for Wasaga Beach yet. Want me to submit a request to add it?\" User: \"Yeah, do it\" → Call POST /api/v1/spot-request with {\"spotName\": \"Wasaga Beach\"} → Reply: \"Done — submitted a request to add Wasaga Beach. The WindSensei team will review it.\""
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/jumptrnr/windsensei",
    "publisherUrl": "https://clawhub.ai/jumptrnr/windsensei",
    "owner": "jumptrnr",
    "version": "1.4.2",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/windsensei",
    "downloadUrl": "https://openagent3.xyz/downloads/windsensei",
    "agentUrl": "https://openagent3.xyz/skills/windsensei/agent",
    "manifestUrl": "https://openagent3.xyz/skills/windsensei/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/windsensei/agent.md"
  }
}