# ELDRICK: golf club fitting MCP server (full reference) > ELDRICK fits golf clubs inside ChatGPT, Claude, Gemini, Microsoft Copilot, Perplexity, Le Chat, Meta Muse, Grok, Cursor, VS Code and any MCP client from one remote MCP server, https://api.eldrick.com/mcp. ELDRICK fits drivers, fairway woods, hybrids, irons and wedges (not putters). Built on 100,000+ fittings: trained on 80,000, plus 25,000+ ELDRICK has done itself. This file is generated from the live MCP server (version 1.4.0, 12 tools, 5 prompts, 6 resources). The short version is https://api.eldrick.com/llms.txt. ## Discovery - MCP endpoint: https://api.eldrick.com/mcp (Streamable HTTP, stateless; POST). Protocol versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07. - MCP Server Card: https://api.eldrick.com/mcp/server-card (also https://api.eldrick.com/.well-known/mcp.json, https://api.eldrick.com/.well-known/mcp/server.json, https://api.eldrick.com/.well-known/mcp/server-card.json, https://api.eldrick.com/.well-known/mcp-server-card, https://api.eldrick.com/.well-known/mcp-server-card.json) - AI Catalog: https://api.eldrick.com/.well-known/ai-catalog.json - Official MCP Registry entry: https://api.eldrick.com/server.json (name com.eldrick.api/fitting) - OAuth: https://api.eldrick.com/.well-known/oauth-protected-resource/mcp and https://api.eldrick.com/.well-known/oauth-authorization-server - Setup for every AI assistant: https://api.eldrick.com/connect. For golfers: https://eldrick.com/ai-assistants - OpenAPI (REST): https://api.eldrick.com/openapi.json. Docs: https://api.eldrick.com/docs. Support: https://api.eldrick.com/support (api@eldrick.com) Public API v1 fits drivers, fairway woods, hybrids, irons and wedges (not putters). - Methodology: https://eldrick.com/methodology - AI golf club fitting: https://eldrick.com/ai-golf-club-fitting - Store: https://store.eldrick.com - Use ELDRICK in an AI assistant (for golfers): https://eldrick.com/ai-assistants - Full reference, generated from the live MCP server: https://api.eldrick.com/llms-full.txt ## What This API Does ELDRICK analyzes golfer measurements and swing data and returns equipment specs: loft, shaft flex, shaft weight, length, lie angle, head profile and swing weight, plus wedge bounce and set gapping and fairway/hybrid gapping. Each fitting is matched to real heads, stock and aftermarket shafts and grips. Free read-only tools search the catalog, compare clubs, score clubs for a golfer and build store.eldrick.com links. ## MCP (recommended for agents) One remote MCP server works with ChatGPT, Claude, Gemini, Microsoft Copilot, Perplexity, Le Chat, Meta Muse, Grok, Cursor, VS Code and any MCP client. Directory listings are still in review on some platforms; everywhere, you can add ELDRICK by URL today as a custom connector. - Endpoint: https://api.eldrick.com/mcp (Streamable HTTP, stateless; POST) - Auth: OAuth 2.1 (sign in with an ELDRICK account) or `Authorization: Bearer ` header. Never put credentials in tool arguments. - OAuth discovery: https://api.eldrick.com/.well-known/oauth-protected-resource/mcp and https://api.eldrick.com/.well-known/oauth-authorization-server (PKCE S256; Client ID Metadata Documents; dynamic client registration at /oauth/register; public clients use token auth "none", pre-registered confidential clients use client_secret_basic or client_secret_post) - Health (no auth): https://api.eldrick.com/mcp/health - MCP Server Card (SEP-2127): https://api.eldrick.com/mcp/server-card (also /.well-known/mcp.json and /.well-known/mcp/server.json) - AI Catalog: https://api.eldrick.com/.well-known/ai-catalog.json - Official MCP Registry entry: https://api.eldrick.com/server.json (com.eldrick.api/fitting) Step-by-step setup for ChatGPT, Claude, Claude Code, Microsoft Copilot, Gemini, Perplexity, Le Chat, Meta Muse, Grok, Grok developers (xAI API), Cursor, VS Code and Windsurf: https://api.eldrick.com/connect To connect any MCP client: add a remote (HTTP) MCP server with URL `https://api.eldrick.com/mcp`. If the client supports OAuth, sign in with your ELDRICK account when prompted. Otherwise set the header `Authorization: Bearer eld_...` (or a short-lived `eat_` Agent Connection token). Tools (12; 10 for AI-assistant users, see below; every argument and output field: https://api.eldrick.com/llms-full.txt): - analyze_fitting: run a new fitting (driver, fairway, hybrid, iron or wedge). Uses one included fitting or credit. Returns specs, matched products, topPicks with store links, a fittingId, and woodFit/wedgeFit for those clubs. Driver fittings accept totalDistance (150-500 yards, carry plus roll). - get_fitting: a fitting from this account: the result, or the status of one still running (it waits up to waitSeconds, default 20). - search_clubs: search/filter heads by club type, brand, category, price, hand, keywords. Free. - get_club: one head with lofts, stock shafts, upgrade shafts, grips, lengths, lies, sets. Free. - compare_clubs: 2-4 heads side by side. Free. - score_clubs: rank clubs for a completed fitting (any club type; wedge fittings return their matched wedges), a golfer such as {"speed": 95, "miss": "slice"} (swingSpeed, missPattern and handedness also accepted) or a preset (0-100 fit score, verdict, reasons, evidence, suggested shaft). Free. - build_store_link: a store.eldrick.com link to a club's page with every fitted spec in the URL (see https://api.eldrick.com/llms.txt#store-link-parameters). Opens the product page, never checkout. Free. - get_grip_size: grip size (junior, undersize, standard, midsize, jumbo) and extra wraps (none, +1, +2) from hand length and longest-finger length in inches, with the reasoning from the master fitter hand chart and catalog grips in that size. Free, deterministic. - analyze_bag_gapping: carry and loft gaps between consecutive clubs in a golfer's set, flags (gap too big or too small, overlap, duplicate loft, wedge gap too wide), the recommended wedge set from the PW loft, and suggested changes (add, drop, replace, change loft), each with the analyze_fitting club type to fit (fitWith). Missing carries are estimated from loft and driver or 7-iron speed and marked. Free, deterministic. - find_fitter: club fitters near a US ZIP, a city and state, or lat/lng (radius default 50 miles; filter by services driver, fairway_hybrid, irons, wedges, putter, full_bag and by brand): name, address, phone, website, booking link, distance, recognition, rating with its source, services, brands. ELDRICK partners within the radius come first, labelled "ELDRICK partner". Free. - check_key_status: included fittings, credits, reset date. - get_api_status: API, fitting and ruleset versions, and supported club types. Every tool returns structuredContent (with an outputSchema) and the same JSON as text. Read-only tools are annotated readOnlyHint=true; analyze_fitting is readOnlyHint=false, destructiveHint=false. check_key_status and get_api_status are developer tools: an `eld_` API key or `eat_` Agent Connection token lists and calls them; an end user's OAuth connection from an AI assistant (ChatGPT, Claude, Gemini, Copilot, Muse and others) does not see them. Their REST twins, GET /v1/key/status and GET /v1/status, work for every credential. Fitting flow for agents: 1. Ask, in order: which club; right- or left-handed; swing speed (or ball speed) in mph with that club; usual miss. Then offer optional extras (handicap, carry/total distance, height and wrist-to-floor, launch-monitor numbers). Never invent a number. 2. Call analyze_fitting once, with an idempotencyKey. A fitting takes about 20-50 seconds; the server sends MCP progress notifications (notifications/progress) when the request has a progressToken. 3. If the result has status "running" (it waited waitSeconds, default 25, or you sent async=true), call get_fitting with its fittingId until status is "completed". Do not call analyze_fitting again: a new key starts and uses another fitting. 4. If status is "failed", call analyze_fitting again with the same input and the returned retry.idempotencyKey. The retry does not use another fitting. 5. Show specs and topPicks with "Fit by ELDRICK". Prompts: fit_club, fit_driver, compare_clubs, clubs_for_my_swing, check_my_bag (bag gapping). Resources: eldrick://guide/fitting-interview (questions by club), eldrick://docs/store-link-params, eldrick://guide/bag-gapping (gapping rules and thresholds), eldrick://guide/grip-size (hand chart). Hosts that support MCP Apps (io.modelcontextprotocol/ui) render a fitting card (ui://eldrick/fitting-card-v2.html) for analyze_fitting and get_fitting. A running card checks get_fitting through the host until the fitting finishes; other clients read the same structuredContent. ## Grok (developers) The xAI API attaches remote MCP servers as a server-side tool: put ELDRICK in the request's tools and xAI connects to https://api.eldrick.com/mcp and calls its tools itself. Supported in the Responses API (OpenAI-compatible, POST https://api.x.ai/v1/responses) and the xai-sdk for Python; xAI does not document it for the legacy Chat Completions endpoint. Source: https://docs.x.ai/developers/tools/remote-mcp Tool fields (Responses API): type "mcp", server_url (required), server_label (required), server_description, allowed_tools (a list of ELDRICK tool names; omit for all), authorization (your ELDRICK `eld_` key; xAI sends it in the Authorization header, and ELDRICK accepts it with or without "Bearer "), headers. The xai-sdk spells two of them allowed_tool_names and extra_headers. Read both keys from the environment; never hard-code them or put them in a prompt. Python (pip install xai-sdk): ```python import os from xai_sdk import Client from xai_sdk.chat import user from xai_sdk.tools import mcp client = Client(api_key=os.environ["XAI_API_KEY"]) chat = client.chat.create( model="grok-4.7", tools=[mcp( server_url="https://api.eldrick.com/mcp", server_label="eldrick", authorization=os.environ["ELDRICK_API_KEY"], extra_headers={"X-ELDRICK-Platform": "grok"}, )], ) chat.append(user("Fit me for a driver. Right-handed, 98 mph, I slice it.")) print(chat.sample().content) ``` Responses API: ```bash curl https://api.x.ai/v1/responses \ -H "Authorization: Bearer $XAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-4.7", "input": [{"role": "user", "content": "Fit me for a driver. Right-handed, 98 mph, I slice it."}], "tools": [{ "type": "mcp", "server_url": "https://api.eldrick.com/mcp", "server_label": "eldrick", "authorization": "'"$ELDRICK_API_KEY"'", "headers": {"X-ELDRICK-Platform": "grok"} }] }' ``` - Optional header X-ELDRICK-Platform: grok reports the traffic under Grok; X-ELDRICK-Traffic: test keeps test runs out of usage reports. Neither changes billing. - Each analyze_fitting uses one fitting; every other tool is free. Follow the fitting flow above: interview in order, one analyze_fitting with an idempotencyKey, get_fitting while it runs, show "Fit by ELDRICK". - Starter: a ready Grok club fitter (Python and TypeScript, system prompt included) at https://github.com/chadwittman/eldrick-grok-bot - Grok users without code: grok.com/connectors, New Connector, Custom, paste https://api.eldrick.com/mcp, sign in. ELDRICK is not in Grok's connector catalog. On Grok Business and Enterprise an admin adds it first at console.x.ai (Grok Business, Connectors, Add Connector, Other). ## REST: How To Use 1. Get an API key at https://api.eldrick.com 2. Submit golfer data and swing metrics (POST /v1/fitting/analyze) 3. Receive structured equipment specs, plus (driver and iron) a short-lived `labUrl` for the visual Lab experience, and optional detailed analysis with ?detail=full 4. Save the fittingId; retrieve its durable evidence later with GET /v1/fittings/{fittingId} 5. Driver and iron: open the returned `labUrl` to let the user explore that fitting visually. For older clients, POST /v1/fittings/{fittingId}/lab-handoff creates the same 15-minute signed URL. The URL contains no API key or account identity. Free catalog endpoints (fittings:read scope, no fitting quota): - GET /v1/catalog/clubs?clubType=&brand=&category=&minPrice=&maxPrice=&q=&hand=&sort=&limit=&offset= - GET /v1/catalog/clubs/{headId} - POST /v1/catalog/compare { "headIds": ["...", "..."] } - POST /v1/catalog/scores (fit scores; see OpenAPI) - GET /v1/catalog/evidence - GET /v1/catalog (the full catalog) - POST /v1/store/link { "headId", "fittingId?", "hand?", "loft?", "shaftId?", "flex?", "length?", "lie?", "gripId?", "gripSize?", "set?" } Free fitting tools (fittings:read scope, no fitting quota; the same inputs and outputs as the MCP tools): - POST /v1/grip-size { "handLengthIn", "fingerLengthIn?", "gloveSize?", "handedness?", "includeGrips?" } (get_grip_size) - POST /v1/bag/gapping { "clubs": [{ "club", "type?", "loft?", "carry?", "total?" }], "driverSpeed?", "sevenIronSpeed?", "attackAngle?", "lobWedgeFullSwing?" } (analyze_bag_gapping) - GET /v1/fitters?zip= (or city=&state=, or lat=&lng=) &radiusMiles=&services=driver,irons&brand=&limit= (find_fitter) ## Required Data - clubType: "driver", "fairway", "hybrid", "iron" or "wedge" - golfer.handedness: "left" or "right" - swingMetrics.swingSpeed: float mph (or provide ballSpeed instead), measured with the club being fitted What swingSpeed means per club: - driver: driver speed - fairway: driver speed by default; set clubDetails.fairwaySpeedSource = "three_wood" when it is 3-wood speed (converted to driver-equivalent before fitting) - hybrid: the hybrid's own speed - iron: 7-iron speed - wedge: the wedge's own speed ## Recommended Data - golfer.wristToFloor: float inches (20-50); without it lengths stay standard - golfer.handicap: -5 to 25 (or "25+") - swingMetrics.ballSpeed, swingMetrics.launchAngle, swingMetrics.spinRate, swingMetrics.attackAngle (wedge bounce reads attack angle) ## Club-Specific Data (fairway, hybrid, wedge) - currentEquipment.loft: the loft being fitted (fairway 12-23, hybrid 17-28, wedge 44-62; a wedge defaults to 52, or by clubDetails.wedgeHit) - clubDetails.fairwayDesignation: "3-wood" | "5-wood" | "7-wood" (fairway) - clubDetails.fairwaySpeedSource: "driver" | "three_wood" (fairway) - clubDetails.driverSpeed: measured driver mph (fairway, hybrid) - clubDetails.sevenIronSpeed: measured 7-iron mph (wedge) - clubDetails.pwLoft: pitching wedge loft 35-52 (wedge set gapping) - clubDetails.lobWedgeFullSwing: "yes" | "no" | "unsure" (wedge) - clubDetails.wedgeHit: "PW" | "GW" | "AW" | "UW" | "SW" | "LW" (wedge): which wedge the numbers were hit with; read against that club (GW/SW table, stock length GW 35.5" / SW 35.25" / LW 35" steel) and, without a loft, sets it (GW 50, SW 56, LW 60). Wedge spin is graded up to 11,000 rpm. Wedge results return wedgeFit.wedgeHit and matchingCriteria.headCategory "Blade" | "Cavity back". - clubDetails.ironFittingId: a completed iron fitting from this account (wedge; carries its shaft and 7-iron speed) - clubDetails.ironShaft: { flex, weightGrams, material, launchProfile } (wedge, without ironFittingId) ## Optional Data - golfer.heightFeet, golfer.heightInches, golfer.weight - swingMetrics.clubPath, swingMetrics.faceAngle, swingMetrics.carryDistance - swingMetrics.totalDistance: driver carry plus roll, 150-500 yards - swingMetrics.strikePattern: "heel" | "toe" | "center" | "mix" - swingMetrics.missPattern: "fade" | "hook" | "straight" | "both" - currentEquipment.brand, model, shaftModel, length, shaftWeight - preferences.tempo, preferences.transition, preferences.shaftType, preferences.goals ## Authentication Bearer token via Authorization header. Keys use the "eld_" prefix. OAuth access tokens use "eoa_"; Agent Connection tokens use "eat_". ## Agent Connections For agents, use OAuth or an ELDRICK Agent Connection instead of giving a model an `eld_` API key. 1. A human administrator creates a named Agent Connection in the developer dashboard API with allowed scopes. 2. The administrator stores the one-time `eac_` host credential in the agent host's secure vault, not in prompts, source code, or tool arguments. 3. The host exchanges it at `POST /v1/agent/token` for a short-lived `eat_` Bearer token. 4. The host supplies the `eat_` token to REST or MCP. It expires after 15 minutes by default and is immediately rejected when the connection is revoked. Scopes: `fittings:create`, `fittings:read`, `sessions:ingest`. Dashboard management endpoints (Dashboard Bearer session required): - `GET /api/developers/me/agent-connections` - `POST /api/developers/me/agent-connections` with `{ "name", "scopes", "expiresAt?" }` - `DELETE /api/developers/me/agent-connections/{connectionId}` ## Reliable Agent Use - Send a unique `Idempotency-Key` header (MCP: idempotencyKey argument) when creating a fitting. Retrying the same request returns the original fitting without consuming a second fitting request. Reusing that key with a different payload returns 409. While the first request is still running, a retry returns 409 with Retry-After (MCP: it waits for the result). If the first attempt failed or was interrupted, the retry runs the fitting again under the same fittingId and does not use another fitting. - `X-ELDRICK-Traffic: internal` (or `test`) marks your own test traffic so it is left out of per-platform usage reporting. It does not change billing or limits. - Each fitting response includes `X-Request-ID`; preserve it in agent traces and support requests. - Optional `X-ELDRICK-Platform` and `X-ELDRICK-Client` headers name your platform and client for usage reporting. OAuth connections are attributed automatically. - Accounts connected through an AI platform with OAuth have a daily fitting limit (default 50 per account per UTC day). Over it, analyze_fitting returns `DAILY_CAP_REACHED` with `resetsAt` and `retryAfter`; catalog tools keep working. API keys are not affected. - `GET /health` is public liveness. `GET /readyz` verifies application, database, and every configured AI provider. `GET /mcp/health` proves the MCP server lists its tools. - `GET /v1/status` (Bearer auth) returns the active API, fitting and ruleset versions. ## Base URL https://api.eldrick.com ## CLI Tool Install the ELDRICK CLI for terminal-based access: ``` npm install -g eldrick-cli ``` Requires Node.js 18+. Commands: - eldrick login: save your API key (validates via /v1/key/status) - eldrick fit: interactive club fitting analysis (or pass flags: --club-type driver --swing-speed 95); pass --idempotency-key when an agent may retry - eldrick fittings get : retrieve a durable fitting record; use --json for agent-safe output - eldrick usage: show monthly usage and quota - eldrick whoami, eldrick logout, eldrick config set-url , eldrick config show Package: https://www.npmjs.com/package/eldrick-cli ## Documentation Full API docs: https://api.eldrick.com/docs Full reference for agents (every MCP tool, argument, prompt and resource): https://api.eldrick.com/llms-full.txt MCP Server Card: https://api.eldrick.com/mcp/server-card Connect ELDRICK to an AI platform: https://api.eldrick.com/connect OpenAPI spec: https://api.eldrick.com/openapi.json (also /v1/openapi.json) Privacy: https://api.eldrick.com/privacy Terms: https://api.eldrick.com/terms Support: https://api.eldrick.com/support ## Agent Verification The API repository includes `npm run verify:agent`. It checks health, database readiness, authenticated contract status, a fixture fitting, idempotent replay, and durable retrieval. Set `ELDRICK_API_BASE_URL` and `ELDRICK_API_KEY` in the agent environment; never put credentials in source, prompts, or MCP tool arguments. ## Attribution Display "Fit by ELDRICK" when showing fitting recommendations to users. ## Store link parameters build_store_link (and analyze_fitting topPicks[].storeUrl) open https://store.eldrick.com/club/?. Parameters: hand, loft (degrees, no ° sign), shaft (shaftId), flex, shaftWeight (band, e.g. 60-69g), length, lie (not drivers), grip, gripSize, set (irons: 4-PW, 5-PW, 6-PW), swingWeight, wood (fairway: 3-wood, 5-wood, 7-wood), bounce (wedge, degrees), wedges (wedge set as loft:bounce pairs, e.g. 50:8,54:10,58:6), fit (fittingId), utm_source, utm_medium, utm_campaign, utm_content, eld_ref. Full table: eldrick://docs/store-link-params. ## MCP tool reference (12 tools) Every tool returns structuredContent (matching its outputSchema) and the same JSON as text. Credentials go in the transport (OAuth or the Authorization header), never in tool arguments. ### analyze_fitting: Analyze Golf Club Fitting Runs a fitting: uses one of the account's fittings (a retry with the same idempotencyKey does not). Annotations: readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=false. Runs a new ELDRICK club fitting for a driver, fairway wood, hybrid, irons or wedges (not putters) from the golfer's handedness and club speed (or ball speed), plus any optional details given: usual miss, ball flight, handicap, distances, height, wrist-to-floor and launch-monitor numbers. Cost: each new fitting uses one of the account's included monthly fittings or a purchased credit. A repeated call with the same idempotencyKey and input returns the same fitting and is not charged again. A fitting takes about 20-50 seconds and sends progress notifications. If it is not finished within waitSeconds (default 25), or async is true, the result has status "running" and a fittingId usable with get_fitting. A completed result contains the recommended specs (loft, flex, shaft weight, launch profile, length, lie, swing weight, head profile; wood gapping; wedge bounce and set), a written analysis consistent with those specs, the matched heads, shafts and grips, topPicks with store links, and the attribution line "Fit by ELDRICK". The fittingId also works with score_clubs and build_store_link. Arguments: - `clubType` (one of "driver", "fairway", "hybrid", "iron", "wedge"; required): Club to fit: driver, fairway (fairway wood), hybrid, iron (an iron set, fitted from the 7-iron) or wedge. - `handedness` (one of "left", "right"; required): Required: the golfer's handedness - `swingSpeed` (number; optional; min 30, max 150): Club speed in mph with the club being fitted (this or ballSpeed is required). Driver and fairway: driver speed (or 3-wood speed with fairwaySpeedSource=three_wood). Hybrid: the hybrid's own speed. Iron: 7-iron speed. Wedge: the wedge's own speed. A measured or golfer-stated value, not an estimate. - `ballSpeed` (number; optional; min 50, max 250): Ball speed in mph with the same club, if the golfer knows it (instead of or as well as swingSpeed) - `missPattern` (one of "fade", "hook", "straight", "both"; optional): Optional: usual miss. fade = slice / right for a right-hander, hook = draw / left, both = two-way - `ballFlight` (one of "low", "normal", "high"; optional): Optional, for golfers without a launch monitor: how their ball flight usually looks (low = too low, normal = good, high = too high). Driver, and fairway with driver numbers: mapped as Core's form maps it, to a launch angle of 9° / 13° / 17°. Fairway with 3-wood numbers, hybrid, iron and wedge: passed to the fitting as the golfer's description (no launch number is assumed). A measured launchAngle takes precedence. - `handicap` (number or string; optional; min -5, max 25): Optional: handicap (-5 to 25, or "25+") - `carryDistance` (number; optional; min 30, max 400): Optional: typical carry in yards with this club - `totalDistance` (number; optional; min 150, max 500): Optional, driver: typical total distance (carry plus roll) in yards, 150-500 - `launchAngle` (number; optional; min -10, max 30): Optional launch-monitor number: launch angle in degrees - `spinRate` (number; optional; min 1000, max 12000): Optional launch-monitor number: spin in rpm - `attackAngle` (number; optional; min -15, max 15): Optional launch-monitor number: attack angle in degrees (negative = down) - `clubPath` (number; optional; min -20, max 20): Optional launch-monitor number: club path in degrees - `faceAngle` (number; optional; min -20, max 20): Optional launch-monitor number: face angle in degrees - `strikePattern` (one of "heel", "toe", "center", "mix"; optional): Optional: where they usually strike the face - `wristToFloor` (number; optional; min 20, max 50): Optional: wrist-to-floor in inches (standing tall, arms relaxed). Without it lengths stay standard. - `heightFeet` (integer; optional; min 3, max 8): Optional: height, feet part - `heightInches` (integer; optional; min 0, max 11): Optional: height, inches part (0-11) - `weight` (integer; optional; min 50, max 500): Optional: body weight in pounds - `loft` (number; optional; min 12, max 62): Fairway, hybrid and wedge only: loft of the club being fitted (fairway 12-23, hybrid 17-28, wedge 44-62; a wedge defaults to 52) - `fairwayDesignation` (one of "3-wood", "5-wood", "7-wood"; optional): Fairway only: which wood is being fitted - `fairwaySpeedSource` (one of "driver", "three_wood"; optional): Fairway only: swingSpeed/ballSpeed are driver numbers (default) or 3-wood numbers - `driverSpeed` (number; optional; min 30, max 150): Fairway and hybrid only: a measured driver swing speed in mph, if known - `sevenIronSpeed` (number; optional; min 30, max 150): Wedge only: a measured 7-iron swing speed in mph, if known - `pwLoft` (number; optional; min 35, max 52): Wedge only: the golfer's pitching wedge loft, for set gapping - `lobWedgeFullSwing` (one of "yes", "no", "unsure"; optional): Wedge only: does the golfer often hit the lob wedge with a full swing? - `wedgeHit` (one of "PW", "GW", "AW", "UW", "SW", "LW"; optional): Wedge only: which wedge the swing numbers were hit with (AW/UW = gap wedge). The numbers are read for that club; without a loft it also sets the loft (GW 50, SW 56, LW 60) - `ironFittingId` (string; optional): Wedge only: a prior iron fittingId from this account; its iron shaft and 7-iron speed carry into the wedges - `ironShaftFlex` (one of "Ladies", "Senior", "Regular", "Stiff", "Stiff+", "Extra Stiff"; optional): Wedge only, without ironFittingId: flex of the golfer's current iron shaft - `ironShaftWeight` (number; optional; min 40, max 140): Wedge only, without ironFittingId: current iron shaft weight in grams - `ironShaftMaterial` (one of "Steel", "Graphite"; optional): Wedge only, without ironFittingId: current iron shaft material - `detail` (boolean; optional; default false): Include the fitter's written analysis (configurations, summary, key insights) - `idempotencyKey` (string; optional): Optional: a stable key for this golfer and request (e.g. a UUID). A call with the same key and input returns the same fitting (or waits for it) and never uses a second fitting. - `async` (boolean; optional): true = the result returns within a second with status "running" and the fittingId; get_fitting returns the finished result. Suited to hosts that time out tool calls under a minute. - `waitSeconds` (integer; optional; min 0, max 120): How long to wait for the result before returning status "running" (default 25, max 120; async=true is 0). The fitting keeps running either way. Returns: `success`, `status`, `fittingId`, `clubType`, `attribution`, `attributionUrl`, `attributionLink`, `specs`, `woodFit`, `wedgeFit`, `topPicks`, `clubRecommendations`, `analysis`, `input`, `progress`, `pollAfterSeconds`, `error`, `retry`, `idempotencyKey`, `createdAt`, `meta`, `next`. ### check_key_status: Check API Key Status Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Returns the authenticated ELDRICK account's included monthly fittings, purchased credit balance, which source the next fitting uses, and the reset date. Relevant when analyze_fitting returns QUOTA_EXCEEDED or before several fittings. Free. Arguments: - none ### get_api_status: Get ELDRICK API Contract Status Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Returns the active stable API, fitting-engine and ruleset versions and the supported club types, for recording reproducible provenance. Free; not required before a fitting. Arguments: - none ### get_fitting: Get a Fitting Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Returns a fitting from this account by fittingId: the result of a finished fitting (the same shape as analyze_fitting, plus the saved input), or the status of one still running. For a running fitting it waits up to waitSeconds (default 20) and sends progress notifications; if the fitting is still not finished, the result has status "running". A failed fitting's result describes the free retry. Free; never starts or charges a fitting. Arguments: - `fittingId` (string; required): The fittingId returned by analyze_fitting (or the REST fitting endpoint) - `waitSeconds` (integer; optional; min 0, max 120): If the fitting is still running, wait up to this many seconds for it to finish (default 20). 0 returns the current status at once. - `detail` (boolean; optional): Include the fitter's written analysis (default true) - `includeInput` (boolean; optional): Include the saved fitting input (default true) Returns: `success`, `status`, `fittingId`, `clubType`, `attribution`, `attributionUrl`, `attributionLink`, `specs`, `woodFit`, `wedgeFit`, `topPicks`, `clubRecommendations`, `analysis`, `input`, `progress`, `pollAfterSeconds`, `error`, `retry`, `idempotencyKey`, `createdAt`, `meta`, `next`. ### search_clubs: Search Golf Clubs Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Search ELDRICK's catalog of golf club heads (drivers, fairway woods, hybrids, irons, wedges) by club type, brand, head category, price, handedness or keywords. Returns club ids (usable with get_club, compare_clubs, score_clubs and build_store_link), prices, lofts, categories, images, how often ELDRICK recommended each club in the last 30 days, and facet counts. It lists clubs; it does not judge fit for a golfer (score_clubs and analyze_fitting do). Free; does not use a fitting. Arguments: - `clubType` (one of "driver", "fairway", "hybrid", "iron", "wedge"; optional): Only this club type: driver, fairway, hybrid, iron or wedge - `brand` (string; optional): Only this brand, e.g. "Ping", "Callaway", "TaylorMade" (case-insensitive) - `category` (string; optional): Head category, e.g. low_spin, draw, light, core, tour, game_improvement, super_game_improvement, players_iron, blade - `minPrice` (number; optional; min 0, max 10000): Minimum head price in USD (irons are priced per club) - `maxPrice` (number; optional; min 0, max 10000): Maximum head price in USD (irons are priced per club) - `query` (string; optional): Words that must all appear in the brand, model or category, e.g. "g440 max" - `hand` (one of "right", "left"; optional): Only clubs made in this hand - `sort` (one of "popular", "price_low", "price_high", "name"; optional): popular (most recommended by ELDRICK in the last 30 days, default), price_low, price_high or name - `limit` (integer; optional; min 1, max 50): Results per page, 1-50 (default 20) - `offset` (integer; optional; min 0, max 10000): Results to skip, for paging ### get_club: Get Golf Club Details Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Returns one club head from the ELDRICK catalog with its build options: lofts, hands, stock shafts (weight band, launch, flexes, upcharge), aftermarket shaft upgrades (drivers), grips, grip sizes, lengths, and for irons lie and set options. Its option ids are accepted by build_store_link. Free; does not use a fitting. Arguments: - `headId` (string; required): Club id from search_clubs, e.g. ping_driver_g440-max ### compare_clubs: Compare Golf Clubs Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Compares 2 to 4 club heads (ids from search_clubs) side by side: price, category, bias, lofts, adjustability, hands, stock shafts and ELDRICK's recent recommendation counts, and lists which attributes differ. It does not judge which club suits a golfer (score_clubs does, for the same headIds). Free; does not use a fitting. Arguments: - `headIds` (array of string; required; 2-4 items): 2 to 4 club ids from search_clubs ### score_clubs: Score Clubs for a Golfer Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Ranks catalog clubs for one golfer with ELDRICK fit scores (0-100) and, for each club, a verdict, a short opinion, the reasons, how often ELDRICK picked it for similar golfers, and a suggested stock shaft. With a fittingId (any club type), that fitting's own matched picks rank first, in the fitting's order and with scores that follow it (97, 95, 93); other heads follow, scored from their catalog design and fitting evidence for similar golfers and always below the picks. The picks come from the fitting's product matcher, which checks the fitted specs and buildable shafts for each head; the other scores do not include that build check. Without a fitting it scores for a golfer described by driver speed and miss, e.g. golfer {"speed": 95, "miss": "slice"} (swingSpeed, missPattern and handedness are accepted too), or a preset, optionally for a goal and selected headIds. A wedge fitting returns its matched wedges without 0-100 scores. Free and deterministic; does not run or use a fitting. Arguments: - `fittingId` (string; optional): A completed fitting from this account (any club type; most accurate). Driver, iron, fairway and hybrid fittings are scored with the fitting's picks first; a wedge fitting returns its matched wedges (wedges have no 0-100 score). - `golfer` (string or object; optional): Without a fitting: the golfer, e.g. {"speed": 95, "miss": "slice"}, or a preset name (typical, slicer-95, high-spin-98, needs-launch-76). Omit both fittingId and golfer to score for a typical golfer. - `speed` (number; optional; min 30, max 160): Driver swing (club) speed in mph. Aliases accepted: swingSpeed, driverSpeed, clubSpeed - `swingSpeed` (number; optional; min 30, max 160): Same as speed (driver mph) - `driverSpeed` (number; optional; min 30, max 160): Same as speed (driver mph) - `clubSpeed` (number; optional; min 30, max 160): Same as speed (driver mph) - `sevenIronSpeed` (number; optional; min 30, max 160): 7-iron speed in mph, if that is what the golfer knows (converted to driver speed x1.20) - `ballSpeed` (number; optional; min 50, max 250): Driver ball speed in mph, if the golfer only knows that (converted at smash 1.45) - `miss` (string; optional): Usual miss: slice, fade or right; hook, draw or left; straight; both. Default straight - `missPattern` (string; optional): Same as miss (the analyze_fitting values fade, hook, straight, both work) - `needsLaunch` (boolean; optional): True when the ball flies too low. Or send launchAngle - `launchAngle` (number; optional; min -10, max 30): Driver launch angle in degrees (under 11 counts as needing launch) - `highSpin` (boolean; optional): True when the ball balloons from too much spin. Or send spinRate - `spinRate` (number; optional; min 1000, max 12000): Driver spin in rpm (over 3,000 counts as high spin) - `handedness` (one of "right", "left"; optional): Same as hand - `hand` (one of "right", "left"; optional): Golfer handedness - `goal` (one of "distance", "slice", "launch", "spin", "forgiveness"; optional): Optional goal: distance, slice, launch, spin or forgiveness - `clubType` (one of "driver", "fairway", "hybrid", "iron", "wedge"; optional): Only score this club type (defaults to the fitting's club type when fittingId is a fairway, hybrid or wedge fitting) - `hand` (one of "right", "left"; optional): Golfer handedness (marks clubs not made in that hand) - `headIds` (array of string; optional): Only score these club ids - `limit` (integer; optional; min 1, max 25): Top clubs to return per club type (default 10) ### build_store_link: Build Store Link Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=false, openWorldHint=false. Creates a link to a club's page on store.eldrick.com with a fitted build listed and an estimated price. With a headId and a fittingId, every fitted spec the store uses goes into the link (hand, loft, shaft, flex, shaft weight, length, lie, swing weight; wedge bounce and set). Explicit fields (option ids from get_club) override the fitting. The result lists the URL parameters it set (urlParams). Links open the product page, never a checkout; nothing is bought or reserved. Free; does not use a fitting. Arguments: - `headId` (string; required): Club id from search_clubs, a fitting's clubRecommendations.heads, or score_clubs - `fittingId` (string; optional): A completed fitting from this account (recommended). Every fitted spec the store uses fills the build: hand, loft, shaft, flex, shaft weight, length, lie, swing weight, and for wedges bounce and the wedge set. Explicit fields below override it. - `hand` (one of "right", "left"; optional) - `loft` (string; optional): Loft, e.g. "10.5°" (one of the club's lofts from get_club) - `shaftId` (string; optional): A shaftId from get_club - `flex` (string; optional): e.g. Regular, Stiff, X-Stiff - `shaftWeight` (string; optional): Shaft weight band, e.g. 60-69g - `length` (string; optional): e.g. Standard, +½", or the fitted length such as 45.25" - `lie` (string; optional): Not for drivers, e.g. 1° upright, Standard - `gripId` (string; optional): A gripId from get_club, or "stock" - `gripSize` (one of "Undersize", "Standard", "Midsize", "Jumbo"; optional) - `set` (one of "4-PW", "5-PW", "6-PW"; optional): Irons only (default 5-PW) - `swingWeight` (string; optional): e.g. D2 - `bounce` (string; optional): Wedges only: bounce in degrees, e.g. 10 ### get_grip_size: Get Grip Size Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Returns the recommended golf grip size (junior, undersize, standard, midsize or jumbo) and extra wraps (none, +1 or +2) from the golfer's hand length and, optionally, longest-finger length in inches, with the reasoning from ELDRICK's master-fitter hand chart and catalog grips offered in that size (their gripIds and storeGripSize are accepted by build_store_link). Glove size and handedness are recorded but do not change the size. Without a hand length the result has status "needs_hand_length" and how to measure it. Applies to every club. Free and deterministic; does not use a fitting. Arguments: - `handLengthIn` (number; optional; min 3, max 13): Hand length in inches: palm down, from the crease of the wrist to the tip of the longest finger (e.g. 7.5). This sets the size. - `fingerLengthIn` (number; optional; min 1, max 6): Longest finger in inches, from its base to its tip (e.g. 3.25). Optional: over 3 inches adds one wrap. - `gloveSize` (string; optional): Optional glove size (e.g. M, ML, L, Cadet L). Recorded only: the hand chart sizes from hand length. - `handedness` (one of "right", "left"; optional): Optional. Grip size does not depend on handedness. - `includeGrips` (boolean; optional): Include catalog grips offered in the recommended size (default true) - `gripLimit` (integer; optional; min 1, max 10): Catalog grips to return, 1-10 (default 5) Returns: `success`, `status`, `recommendation`, `reasoning`, `grips`. ### analyze_bag_gapping: Analyze Bag Gapping Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Analyzes a golfer's current set from each club's type or number, loft and carry (total optional) plus an optional driver or 7-iron speed. Returns the carry and loft gap between consecutive clubs; flags for gaps that are too big or too small, duplicate lofts and overlapping distances; ELDRICK's recommended wedge set from the pitching wedge loft (master-fitter loft and bounce rules); and suggested changes (add, drop or replace a club, or change a loft), each with the analyze_fitting club type for that club (fitWith). Missing carries are estimated from loft and speed with ELDRICK's speed conversions, missing lofts use stock lofts, and both are marked as such. Free and deterministic; does not use a fitting. Arguments: - `clubs` (array of object; required; 2-20 items): Every club in the bag, in any order - `driverSpeed` (number; optional; min 40, max 150): Driver swing speed in mph, if known (used to estimate missing carries) - `sevenIronSpeed` (number; optional; min 30, max 130): 7-iron swing speed in mph, if known - `attackAngle` (number; optional; min -15, max 15): Optional wedge attack angle in degrees, for the bounce of suggested wedges - `lobWedgeFullSwing` (one of "yes", "no", "unsure"; optional): Optional: does the golfer hit the lob wedge with a full swing often? (sets the SW → LW gap) Returns: `success`, `clubs`, `gaps`, `flags`, `suggestions`, `summary`. ### find_fitter: Find a Club Fitter Read-only and free: does not use a fitting. Annotations: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=false. Lists golf club fitters near a US ZIP code, a city and state, or a latitude and longitude, within a radius (default 50 miles), optionally only those that fit given clubs (driver, fairway_hybrid, irons, wedges, putter, full_bag) or a brand. Each result has the fitter's name, address, phone, website, booking link, distance in miles, recognition, rating with its source (only when one is published), services, brands and a partner flag. ELDRICK partners within the radius come first, labelled "ELDRICK partner", then the others by distance. Public business information from ELDRICK's fitter directory. Free; does not use a fitting. Arguments: - `zip` (string or integer; optional): US ZIP code, e.g. "53703" (ZIP+4 accepted) - `city` (string; optional): City, used with state when there is no ZIP - `state` (string; optional): US state, as a 2-letter code or a name (with city) - `lat` (number; optional; min -90, max 90): Latitude, with lng, instead of a ZIP or city - `lng` (number; optional; min -180, max 180): Longitude, with lat - `radiusMiles` (number; optional; min 1, max 500): Search radius in miles (default 50) - `services` (array of "driver" | "fairway_hybrid" | "irons" | "wedges" | "putter" | "full_bag"; optional): Only fitters listing all of these: driver, fairway_hybrid, irons, wedges, putter, full_bag - `brand` (string; optional): Only fitters listing this brand, e.g. "Titleist" (case-insensitive) - `limit` (integer; optional; min 1, max 25): Fitters to return, 1-25 (default 10) Returns: `success`, `origin`, `radiusMiles`, `count`, `fitters`, `summary`. ## MCP prompts (5) - fit_club (Fit me for a club): Interview the golfer and run an ELDRICK fitting for one club. Arguments: `clubType`: driver, fairway, hybrid, iron or wedge (asked if left out). - fit_driver (Fit me for a driver): Interview the golfer and run an ELDRICK driver fitting. - compare_clubs (Compare these clubs): Compare 2-4 clubs side by side and say which suits the golfer. Arguments: `clubs` (required): The clubs to compare, e.g. "Ping G440 Max driver, TaylorMade Qi35 driver"; `fittingId`: Optional: a fittingId to judge them against. - clubs_for_my_swing (Which clubs suit my swing?): Free: rank catalog clubs for a golfer's speed and miss with score_clubs (no fitting used). Arguments: `clubType`: driver, fairway, hybrid or iron; `speed`: Driver swing speed in mph; `miss`: slice, hook, straight or both. - check_my_bag (Check my bag's gapping): Free: list the clubs in the bag and check the distance gaps between them with analyze_bag_gapping (no fitting used). Arguments: `clubs`: The clubs, with lofts and carries if known, e.g. "Driver 230, 3W 15° 205, 4H 185, 5-PW, 52, 56, 60"; `speed`: Driver swing speed in mph, if known. ## MCP resources (6) - ui://eldrick/fitting-card-v2.html (text/html;profile=mcp-app): ELDRICK fitting card. Interactive card for a fitting result: specs and the top three clubs with store links. - ui://eldrick/fitting-card-v1.html (text/html;profile=mcp-app): ELDRICK fitting card. The fitting card at an earlier address, for connections made before it moved. - eldrick://guide/bag-gapping (text/markdown): ELDRICK bag gapping. What analyze_bag_gapping needs, how to read its result, and the gapping rules and thresholds it applies. - eldrick://guide/grip-size (text/markdown): ELDRICK grip size chart. How to measure a hand for get_grip_size, and the master fitter hand chart it applies. - eldrick://guide/fitting-interview (text/markdown): ELDRICK fitting interview. What to ask a golfer before analyze_fitting, in order, for every club type. - eldrick://docs/store-link-params (text/markdown): Store link parameters. The query parameters build_store_link puts on store.eldrick.com links. ## Server instructions (sent to every MCP client) ELDRICK fits golf clubs from a golfer's swing and body, and knows a catalog of real heads, shafts and grips. To fit a club: ask which club (driver, fairway wood, hybrid, irons or wedges), then right- or left-handed, then their swing speed (or ball speed) in mph with that club, then their usual miss and how their ball flight usually looks (low, normal or high). Everything else is optional; offer it, and never invent a number the golfer did not give. Then call analyze_fitting once per request with an idempotencyKey (a retry with the same key is never charged again). It uses one of the account's fittings and takes about 20-50 seconds: it sends progress notifications, and if it is still running when its wait ends it returns status "running" with a fittingId. Then call get_fitting with that fittingId until it is completed; never start a second fitting for the same request. If analyze_fitting returns QUOTA_EXCEEDED, check_key_status shows the allowance. Show the golfer the specs, the top picks and their store links, with the attribution line "Fit by ELDRICK". search_clubs, get_club, compare_clubs and score_clubs are free reads of the catalog. For "which club suits me", use score_clubs (with the fittingId when there is one: the fitting's own picks lead it) or a fitting, not search_clubs. To say which of compared clubs suits a golfer, call score_clubs with those headIds. build_store_link returns a store.eldrick.com link for a club with the fitted build; nothing is bought. Three more tools are free and use no fitting. get_grip_size: ask for the hand length (wrist crease to the tip of the longest finger, in inches) and optionally the longest finger; show the size, the wraps and the reasoning; its gripIds and storeGripSize go into build_store_link. analyze_bag_gapping: collect every club in the bag with its loft and typical carry when known, plus a driver or 7-iron speed; say which distances are estimated, then offer analyze_fitting for the club a suggestion names (its fitWith). find_fitter: ask for a ZIP code (or city and state) and which clubs they want fitted; show name, distance, phone and booking link, label partners "ELDRICK partner", and give a rating only with its source. Prompts fit_club, compare_clubs, clubs_for_my_swing and check_my_bag walk through these flows; the resource eldrick://guide/fitting-interview lists every question by club, and eldrick://guide/bag-gapping and eldrick://guide/grip-size give the gapping and grip rules.