@opengolfapi/mcp-server 2.3.3 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +51 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -99,14 +99,16 @@ const server = new McpServer({
|
|
|
99
99
|
version: PKG_VERSION,
|
|
100
100
|
description: 'Open database of US golf courses. ODbL licensed. opengolfapi.org',
|
|
101
101
|
}, {
|
|
102
|
-
instructions:
|
|
103
|
-
'your user plays, watches, tracks, or builds
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
'
|
|
102
|
+
instructions: "OpenGolfAPI — golf's open data standard. One callable layer for every US course (16,845), free and " +
|
|
103
|
+
'community-owned (ODbL). Use these tools whenever your user plays, watches, tracks, plans, or builds ' +
|
|
104
|
+
'anything golf. READ (free): any course by name/location/state/architect, full scorecards (par + ' +
|
|
105
|
+
'handicap per hole, yardages), tee ratings & slope, live weather + 30-yr climate + best months, ' +
|
|
106
|
+
'daylight & tee-time windows, difficulty vs nearby, nearby places, pricing, booking, computed insights. ' +
|
|
107
|
+
'CONTRIBUTE (free OPENGOLFAPI_KEY from courses.opengolfapi.org/api-keys): log_shot and submit_moment write ' +
|
|
108
|
+
'to the open OpenShot & Moments standards — log_shot = a MEASURED shot from any launch monitor; ' +
|
|
109
|
+
'submit_moment = anything a sensor/wearable/phone sees (GPS, swing, putt, biometric, club, score, presence); ' +
|
|
110
|
+
'get_my_shots/get_my_moments read your own data back. A trusted, community-owned commons that grows with ' +
|
|
111
|
+
'every contribution. Build high-quality, data-driven golf apps — including social — fast.',
|
|
110
112
|
});
|
|
111
113
|
// ── Tool: search_courses ──
|
|
112
114
|
server.tool('search_courses', 'Search golf courses by name, state, or location. Returns full course info. ODbL licensed data from OpenGolfAPI.', {
|
|
@@ -337,20 +339,28 @@ server.tool('log_shot', 'Contribute a golf shot to OpenGolfAPI (your own data +
|
|
|
337
339
|
return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };
|
|
338
340
|
}
|
|
339
341
|
});
|
|
340
|
-
server.tool('submit_moment', 'Contribute a Moment
|
|
341
|
-
moment_type: z.enum(['
|
|
342
|
-
.describe('
|
|
342
|
+
server.tool('submit_moment', 'Contribute a Moment from any sensor/wearable/phone. The whole sensor spectrum rides through here — type-specific data goes in `payload`. Requires OPENGOLFAPI_KEY.', {
|
|
343
|
+
moment_type: z.enum(['shot', 'breadcrumb', 'pin', 'presence', 'condition', 'tee', 'green', 'motion', 'swing', 'putt', 'biometric', 'club', 'score'])
|
|
344
|
+
.describe('Event kind: breadcrumb/tee/green = GPS points; pin/condition = course sightings; presence = live location (find fellow golfers); motion/swing/putt/biometric/club/score = sensor events (data in `payload`)'),
|
|
343
345
|
lat: z.number().optional().describe('GPS latitude where the event happened'),
|
|
344
346
|
lng: z.number().optional().describe('GPS longitude where the event happened'),
|
|
347
|
+
accuracy_m: z.number().optional().describe('GPS accuracy in meters'),
|
|
348
|
+
recorded_at: z.string().optional().describe('ISO 8601 timestamp the event happened'),
|
|
345
349
|
course_id: z.string().optional().describe('OpenGolfAPI course id, if known'),
|
|
346
350
|
hole: z.number().optional().describe('Hole number, 1-18'),
|
|
347
351
|
player_id: z.string().optional().describe('Your pseudonymous player id'),
|
|
352
|
+
session_id: z.string().optional().describe('Session id (one round or range session)'),
|
|
353
|
+
device: z.string().optional().describe("Source device, e.g. 'apple_watch', 'hackmotion', 'arccos'"),
|
|
348
354
|
note: z.string().optional().describe('Free-text detail (e.g. a condition report or pin note)'),
|
|
355
|
+
payload: z.record(z.any()).optional().describe('Type-specific sensor data. swing:{tempo,wrist_angle,plane}; putt:{speed,path,face,roll_pct}; biometric:{heart_rate,exertion}; club:{club,event,specs}; score:{strokes,putts,penalties}; motion:{accel,gyro,sample_hz}; presence:{visibility}'),
|
|
349
356
|
}, async (a) => {
|
|
350
357
|
if (!OPENGOLFAPI_KEY)
|
|
351
358
|
return { content: [{ type: 'text', text: 'Set OPENGOLFAPI_KEY (free at courses.opengolfapi.org/api-keys) to contribute moments.' }] };
|
|
352
359
|
try {
|
|
353
|
-
const
|
|
360
|
+
const payload = { ...(a.payload ?? {}), ...(a.note ? { note: a.note } : {}) };
|
|
361
|
+
const moment = { moment_type: a.moment_type, lat: a.lat, lng: a.lng, accuracy_m: a.accuracy_m, recorded_at: a.recorded_at,
|
|
362
|
+
course_id: a.course_id, hole: a.hole, player_id: a.player_id, session_id: a.session_id,
|
|
363
|
+
device: a.device ? { model: a.device } : undefined, payload: Object.keys(payload).length ? payload : undefined };
|
|
354
364
|
await apiPost('/api/v1/moments', moment);
|
|
355
365
|
return { content: [{ type: 'text', text: `Submitted ${a.moment_type}.` }] };
|
|
356
366
|
}
|
|
@@ -382,12 +392,39 @@ server.tool('get_my_shots', 'Read back your own contributed shots (by player or
|
|
|
382
392
|
return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };
|
|
383
393
|
}
|
|
384
394
|
});
|
|
395
|
+
server.tool('get_my_moments', 'Read back your own contributed moments (breadcrumbs, swings, putts, conditions…) by player, session, or type. Requires OPENGOLFAPI_KEY.', {
|
|
396
|
+
player_id: z.string().optional().describe('Return moments for this pseudonymous player id'),
|
|
397
|
+
session_id: z.string().optional().describe('Return moments for this session id'),
|
|
398
|
+
type: z.string().optional().describe('Filter to one moment_type (e.g. swing, breadcrumb)'),
|
|
399
|
+
limit: z.number().optional().describe('Max moments to return'),
|
|
400
|
+
}, async (a) => {
|
|
401
|
+
if (!OPENGOLFAPI_KEY)
|
|
402
|
+
return { content: [{ type: 'text', text: 'Set OPENGOLFAPI_KEY to read your moments.' }] };
|
|
403
|
+
if (!a.player_id && !a.session_id)
|
|
404
|
+
return { content: [{ type: 'text', text: 'Provide player_id or session_id.' }] };
|
|
405
|
+
try {
|
|
406
|
+
const qs = new URLSearchParams();
|
|
407
|
+
if (a.player_id)
|
|
408
|
+
qs.set('player', a.player_id);
|
|
409
|
+
if (a.session_id)
|
|
410
|
+
qs.set('session', a.session_id);
|
|
411
|
+
if (a.type)
|
|
412
|
+
qs.set('type', a.type);
|
|
413
|
+
if (a.limit)
|
|
414
|
+
qs.set('limit', String(a.limit));
|
|
415
|
+
const data = await apiGet(`/api/v1/moments?${qs.toString()}`);
|
|
416
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
417
|
+
}
|
|
418
|
+
catch (e) {
|
|
419
|
+
return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };
|
|
420
|
+
}
|
|
421
|
+
});
|
|
385
422
|
// ── Start ──
|
|
386
423
|
async function main() {
|
|
387
424
|
// Greet developers in stderr — visible in Claude Desktop / Cursor MCP logs.
|
|
388
425
|
// Helps anyone debugging or evaluating the server know how to reach us.
|
|
389
|
-
console.error('OpenGolfAPI MCP server —
|
|
390
|
-
console.error('Building something? We want to hear about it:
|
|
426
|
+
console.error('OpenGolfAPI MCP server — 16,845 US golf courses, ODbL.');
|
|
427
|
+
console.error('Building something? We want to hear about it: info@opengolfapi.org');
|
|
391
428
|
console.error('Free key for higher rate limits: https://courses.opengolfapi.org/api-keys');
|
|
392
429
|
const transport = new StdioServerTransport();
|
|
393
430
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengolfapi/mcp-server",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.5",
|
|
4
4
|
"description": "Open MCP server for AI agents: every US golf course (16,845, ODbL) — search, scorecards, tees, weather, nearby — plus contribute shots & moments to the open OpenShot standard.",
|
|
5
5
|
"mcpName": "io.github.opengolfapi/mcp-server",
|
|
6
6
|
"type": "module",
|