marathon_countdown
Calculate the time remaining until a marathon event. Enter the marathon ID or slug to see the countdown.
Instructions
Get a countdown to a specific marathon event
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Marathon ID or slug, e.g. "tokyo", "boston", "kobe2026" |
Implementation Reference
- index.js:328-354 (handler)Tool handler for marathon_countdown: fetches marathon data from the API, calculates days/hours until race day, and returns formatted countdown text. Includes fallback logic to strip year from slug if initial fetch fails.
async ({ id }) => { let data; try { data = await fetchJSON(`${BASE_URL}/api/marathons/${id}.json`); } catch { const slug = id.replace(/\d{4}$/, ''); data = await fetchJSON(`${BASE_URL}/api/marathons/${slug}.json`); } const m = data.marathon; const raceDate = new Date(m.date); const now = new Date(); const diff = raceDate - now; if (diff <= 0) { return { content: [{ type: 'text', text: `${m.name.en} has already taken place on ${m.date}.` }] }; } const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); let text = `${m.name.en} Countdown\n\n`; text += `${days} days, ${hours} hours until race day\n`; text += `Date: ${m.date}\nCity: ${m.city}\n`; text += `\nLive countdown: ${m.links.countdown}`; return { content: [{ type: 'text', text }] }; } ); - index.js:327-327 (schema)Schema definition for marathon_countdown tool: expects a single string parameter 'id' which is a marathon ID or slug (e.g. 'tokyo', 'boston', 'kobe2026').
{ id: z.string().describe('Marathon ID or slug, e.g. "tokyo", "boston", "kobe2026"') }, - index.js:324-354 (registration)Registration of 'marathon_countdown' tool on the MCP server using server.tool() with description 'Get a countdown to a specific marathon event'.
server.tool( 'marathon_countdown', 'Get a countdown to a specific marathon event', { id: z.string().describe('Marathon ID or slug, e.g. "tokyo", "boston", "kobe2026"') }, async ({ id }) => { let data; try { data = await fetchJSON(`${BASE_URL}/api/marathons/${id}.json`); } catch { const slug = id.replace(/\d{4}$/, ''); data = await fetchJSON(`${BASE_URL}/api/marathons/${slug}.json`); } const m = data.marathon; const raceDate = new Date(m.date); const now = new Date(); const diff = raceDate - now; if (diff <= 0) { return { content: [{ type: 'text', text: `${m.name.en} has already taken place on ${m.date}.` }] }; } const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); let text = `${m.name.en} Countdown\n\n`; text += `${days} days, ${hours} hours until race day\n`; text += `Date: ${m.date}\nCity: ${m.city}\n`; text += `\nLive countdown: ${m.links.countdown}`; return { content: [{ type: 'text', text }] }; } );