{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
  "name": "online.golfdata/golf-clubs",
  "title": "golfdata.online",
  "description": "Verified directory of golf clubs and courses across Europe (17 countries, Spain first), for people and AI agents: facts (each linked to its sources with a last_verified date), booking links, and booking requests where the club enabled them. Not related to golfdata.co, a golf-equipment price catalogue. No key required.",
  "version": "1.3.1",
  "websiteUrl": "https://golfdata.online",
  "protocolVersion": "2025-06-18",
  "remotes": [
    {
      "type": "streamable-http",
      "url": "https://golfdata.online/mcp",
      "authentication": {
        "type": "none"
      }
    }
  ],
  "capabilities": {
    "tools": {
      "listChanged": false
    }
  },
  "tools": [
    {
      "name": "search_clubs",
      "description": "Search approved golf clubs and courses across Europe by a free-text fragment (matches name, island, municipality or region), and/or ISO country code, island, region and municipality filters. Returns summary records (with last_verified) only; fetch provenance with get_club or list_sources_for before citing.",
      "readOnly": true,
      "arguments": [
        {
          "name": "query",
          "type": "string",
          "required": false,
          "description": "Name, island, municipality or region fragment."
        },
        {
          "name": "country",
          "type": "string",
          "required": false,
          "description": "ISO 3166-1 alpha-2 country code, e.g. ES."
        },
        {
          "name": "island",
          "type": "string",
          "required": false,
          "description": "Island name, e.g. Tenerife."
        },
        {
          "name": "region",
          "type": "string",
          "required": false,
          "description": "Region or province name."
        },
        {
          "name": "municipality",
          "type": "string",
          "required": false,
          "description": "Municipality or town."
        },
        {
          "name": "question",
          "type": "string",
          "required": false,
          "description": "The golfer's question, as asked (stored without personal data; does not change the answer)."
        },
        {
          "name": "limit",
          "type": "integer",
          "required": false,
          "description": "Max results, 1..10 (default 10); a larger limit is refused with JSON-RPC error -32011."
        }
      ]
    },
    {
      "name": "get_club",
      "description": "Get one approved club by UUID or slug, with all facts, sources[] and club_facts (what the club itself published from its verified account), or found: false.",
      "readOnly": true,
      "arguments": [
        {
          "name": "id_or_slug",
          "type": "string",
          "required": true,
          "description": "Club UUID or slug."
        },
        {
          "name": "question",
          "type": "string",
          "required": false,
          "description": "The golfer's question, as asked (stored without personal data; does not change the answer)."
        },
        {
          "name": "topic",
          "type": "string",
          "required": false,
          "description": "What the golfer wants to know (e.g. green_fee, booking, hours, visitors)."
        }
      ]
    },
    {
      "name": "list_sources_for",
      "description": "List provenance (source URL, publisher, trust level, field, retrieved_at) for a club.",
      "readOnly": true,
      "arguments": [
        {
          "name": "entity_type",
          "type": "string",
          "required": true,
          "description": "Entity type (currently \"club\")."
        },
        {
          "name": "entity_id",
          "type": "string",
          "required": true,
          "description": "Entity UUID."
        }
      ]
    },
    {
      "name": "request_booking",
      "description": "Send a booking request to a club whose card says booking.requests_enabled is true. golfdata only forwards the request to the club (by email or a WhatsApp link); it does not confirm the booking. Returns a request id and, for the WhatsApp channel, a tracked link. Only works for enabled clubs; get the golfer's consent before sending their personal data. The golfer's details are forwarded to the club and kept for 24 months, then anonymized; a golfer can ask to erase them sooner via hello@golfdata.online.",
      "readOnly": false,
      "arguments": [
        {
          "name": "club_id",
          "type": "string",
          "required": true,
          "description": "Club UUID (from get_club or the card)."
        },
        {
          "name": "date",
          "type": "string",
          "required": true,
          "description": "Requested play date, YYYY-MM-DD (today..+365)."
        },
        {
          "name": "time",
          "type": "string",
          "required": false,
          "description": "Preferred tee time, HH:MM (24h)."
        },
        {
          "name": "players",
          "type": "integer",
          "required": true,
          "description": "Number of players, 1..8."
        },
        {
          "name": "holes",
          "type": "integer",
          "required": false,
          "description": "9 or 18."
        },
        {
          "name": "name",
          "type": "string",
          "required": true,
          "description": "The golfer's name (with their consent)."
        },
        {
          "name": "email",
          "type": "string",
          "required": true,
          "description": "The golfer's email (with their consent); used as reply-to, never shared beyond the club."
        },
        {
          "name": "phone",
          "type": "string",
          "required": false,
          "description": "The golfer's phone in E.164 (with their consent)."
        },
        {
          "name": "message",
          "type": "string",
          "required": false,
          "description": "Optional message to the club (max 500 chars)."
        },
        {
          "name": "channel",
          "type": "string",
          "required": false,
          "description": "email (default) or whatsapp."
        }
      ]
    }
  ],
  "rateLimits": {
    "unitsPerMinute": 20,
    "per": "client IP",
    "costs": {
      "get_club": 4,
      "other": 1
    },
    "searchMaxLimit": 10,
    "searchLimitExceededError": -32011,
    "overBudget": {
      "httpStatus": 429,
      "header": "Retry-After"
    },
    "note": "Strict limits the server runs until its shared limiter is switched on; they may rise."
  },
  "links": {
    "llmsTxt": "https://golfdata.online/llms.txt",
    "feed": "https://golfdata.online/api/clubs/{slug}",
    "ai": "https://golfdata.online/ai",
    "sitemap": "https://golfdata.online/sitemap.xml",
    "cardSchema": "https://golfdata.online/schema/card-v1.json"
  },
  "card": {
    "version": "1.2",
    "schema": "https://golfdata.online/schema/card-v1.json",
    "where": [
      "get_club.structuredContent.card",
      "feed.card"
    ]
  },
  "trackedLinks": {
    "pathPrefix": "https://golfdata.online/go/l",
    "where": [
      "get_club.structuredContent.links",
      "search_clubs.results[].links",
      "feed.links",
      "club page CTAs"
    ],
    "note": "Give users links.* (booking/website/phone) so the club sees demand; the raw values are unchanged."
  }
}
