intervals-icu-mcp-server 0.1.9 → 0.2.0
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/client.d.ts +28 -0
- package/dist/client.js +16 -0
- package/dist/format.d.ts +2 -1
- package/dist/format.js +4 -0
- package/dist/index.js +45 -2
- package/package.json +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -343,6 +343,34 @@ export declare function getActivities(config: ClientConfig, params: {
|
|
|
343
343
|
}): Promise<Activity[]>;
|
|
344
344
|
export declare function getActivityDetails(config: ClientConfig, activityId: string): Promise<Activity>;
|
|
345
345
|
export declare function getActivityIntervals(config: ClientConfig, activityId: string): Promise<z.infer<typeof IntervalSchema>>;
|
|
346
|
+
export declare const MessageSchema: z.ZodObject<{
|
|
347
|
+
id: z.ZodOptional<z.ZodNumber>;
|
|
348
|
+
athlete_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
349
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
350
|
+
created: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
351
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
352
|
+
content: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
353
|
+
attachment_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
354
|
+
}, "strip", z.ZodTypeAny, {
|
|
355
|
+
id?: number | undefined;
|
|
356
|
+
name?: string | null | undefined;
|
|
357
|
+
type?: string | null | undefined;
|
|
358
|
+
athlete_id?: string | null | undefined;
|
|
359
|
+
created?: string | null | undefined;
|
|
360
|
+
content?: string | null | undefined;
|
|
361
|
+
attachment_url?: string | null | undefined;
|
|
362
|
+
}, {
|
|
363
|
+
id?: number | undefined;
|
|
364
|
+
name?: string | null | undefined;
|
|
365
|
+
type?: string | null | undefined;
|
|
366
|
+
athlete_id?: string | null | undefined;
|
|
367
|
+
created?: string | null | undefined;
|
|
368
|
+
content?: string | null | undefined;
|
|
369
|
+
attachment_url?: string | null | undefined;
|
|
370
|
+
}>;
|
|
371
|
+
export type Message = z.infer<typeof MessageSchema>;
|
|
372
|
+
export declare function getActivityMessages(config: ClientConfig, activityId: string): Promise<Message[]>;
|
|
373
|
+
export declare function addActivityMessage(config: ClientConfig, activityId: string, content: string): Promise<void>;
|
|
346
374
|
export declare function getWellness(config: ClientConfig, params: {
|
|
347
375
|
startDate: string;
|
|
348
376
|
endDate: string;
|
package/dist/client.js
CHANGED
|
@@ -138,6 +138,22 @@ export async function getActivityIntervals(config, activityId) {
|
|
|
138
138
|
const data = await request(`/activity/${activityId}/intervals`, config);
|
|
139
139
|
return IntervalSchema.parse(data);
|
|
140
140
|
}
|
|
141
|
+
export const MessageSchema = z.object({
|
|
142
|
+
id: z.number().optional(),
|
|
143
|
+
athlete_id: z.string().nullable().optional(),
|
|
144
|
+
name: z.string().nullable().optional(),
|
|
145
|
+
created: z.string().nullable().optional(),
|
|
146
|
+
type: z.string().nullable().optional(),
|
|
147
|
+
content: z.string().nullable().optional(),
|
|
148
|
+
attachment_url: z.string().nullable().optional(),
|
|
149
|
+
});
|
|
150
|
+
export async function getActivityMessages(config, activityId) {
|
|
151
|
+
const data = await request(`/activity/${activityId}/messages`, config);
|
|
152
|
+
return z.array(MessageSchema).parse(data);
|
|
153
|
+
}
|
|
154
|
+
export async function addActivityMessage(config, activityId, content) {
|
|
155
|
+
await mutate("POST", `/activity/${activityId}/messages`, config, { content });
|
|
156
|
+
}
|
|
141
157
|
export async function getWellness(config, params) {
|
|
142
158
|
const data = await request(`/athlete/${config.athleteId}/wellness`, config, { oldest: params.startDate, newest: params.endDate });
|
|
143
159
|
if (Array.isArray(data)) {
|
package/dist/format.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { Activity, Wellness, Event, SportSettings } from "./client.js";
|
|
1
|
+
import type { Activity, Wellness, Event, SportSettings, Message } from "./client.js";
|
|
2
2
|
export declare function formatActivity(a: Activity): string;
|
|
3
3
|
export declare function formatWellness(date: string, w: Wellness): string;
|
|
4
4
|
export declare function formatEvent(e: Event): string;
|
|
5
|
+
export declare function formatMessage(m: Message): string;
|
|
5
6
|
export declare function formatSportZones(s: SportSettings): string;
|
|
6
7
|
export declare function formatIntervalRow(interval: Record<string, unknown>, idx: number): string;
|
package/dist/format.js
CHANGED
|
@@ -83,6 +83,10 @@ export function formatEvent(e) {
|
|
|
83
83
|
.filter(Boolean)
|
|
84
84
|
.join("\n");
|
|
85
85
|
}
|
|
86
|
+
export function formatMessage(m) {
|
|
87
|
+
const when = m.created ? new Date(m.created).toLocaleString() : "Unknown time";
|
|
88
|
+
return `**${m.name ?? "Unknown"}** (${when}): ${m.content ?? ""}`;
|
|
89
|
+
}
|
|
86
90
|
function zoneRanges(breakpoints, names) {
|
|
87
91
|
const count = names?.length ?? (breakpoints?.length ?? 0) + 1;
|
|
88
92
|
const ranges = [];
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { getActivities, getActivityDetails, getActivityIntervals, getWellness, getEvents, getEventById, getNotesByDate, createEvent, updateEvent, deleteEvent, getAthleteProfile, getAthleteZones, getAthleteSummary, getWellnessDay, updateWellness, getActivityStreams, getActivityPowerCurves, listWorkouts, createWorkout, bulkCreateEvents, bulkDeleteEvents, getAthleteFitness, } from "./client.js";
|
|
8
|
-
import { formatActivity, formatWellness, formatEvent, formatIntervalRow, formatSportZones, } from "./format.js";
|
|
7
|
+
import { getActivities, getActivityDetails, getActivityIntervals, getWellness, getEvents, getEventById, getNotesByDate, createEvent, updateEvent, deleteEvent, getAthleteProfile, getAthleteZones, getAthleteSummary, getWellnessDay, updateWellness, getActivityStreams, getActivityPowerCurves, listWorkouts, createWorkout, bulkCreateEvents, bulkDeleteEvents, getAthleteFitness, getActivityMessages, addActivityMessage, } from "./client.js";
|
|
8
|
+
import { formatActivity, formatWellness, formatEvent, formatIntervalRow, formatSportZones, formatMessage, } from "./format.js";
|
|
9
9
|
function getConfig(args) {
|
|
10
10
|
const apiKey = args["api_key"] ?? process.env.API_KEY ?? "";
|
|
11
11
|
const athleteId = args["athlete_id"] ??
|
|
@@ -282,6 +282,33 @@ const TOOLS = [
|
|
|
282
282
|
},
|
|
283
283
|
},
|
|
284
284
|
},
|
|
285
|
+
{
|
|
286
|
+
name: "get_activity_messages",
|
|
287
|
+
description: "Get the comments/notes left on a specific activity (the chat thread shown under an activity in Intervals.icu, e.g. coach feedback).",
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: "object",
|
|
290
|
+
required: ["activity_id"],
|
|
291
|
+
properties: {
|
|
292
|
+
activity_id: { type: "string", description: "The activity ID" },
|
|
293
|
+
athlete_id: { type: "string", description: "Athlete ID (defaults to ATHLETE_ID env var)" },
|
|
294
|
+
api_key: { type: "string", description: "API key (defaults to API_KEY env var)" },
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "add_activity_message",
|
|
300
|
+
description: "Post a comment/note on a specific activity (adds to the activity's chat thread in Intervals.icu).",
|
|
301
|
+
inputSchema: {
|
|
302
|
+
type: "object",
|
|
303
|
+
required: ["activity_id", "content"],
|
|
304
|
+
properties: {
|
|
305
|
+
activity_id: { type: "string", description: "The activity ID" },
|
|
306
|
+
content: { type: "string", description: "Comment text to post" },
|
|
307
|
+
athlete_id: { type: "string", description: "Athlete ID (defaults to ATHLETE_ID env var)" },
|
|
308
|
+
api_key: { type: "string", description: "API key (defaults to API_KEY env var)" },
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
},
|
|
285
312
|
{
|
|
286
313
|
name: "list_workouts",
|
|
287
314
|
description: "List all workouts in the athlete's workout library.",
|
|
@@ -624,6 +651,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
624
651
|
const curves = await getActivityPowerCurves(config, activityId);
|
|
625
652
|
return { content: [{ type: "text", text: `Power curves for activity ${activityId}:\n\n${JSON.stringify(curves, null, 2)}` }] };
|
|
626
653
|
}
|
|
654
|
+
case "get_activity_messages": {
|
|
655
|
+
const activityId = z.string().parse(args["activity_id"]);
|
|
656
|
+
const config = getConfig(args);
|
|
657
|
+
const messages = await getActivityMessages(config, activityId);
|
|
658
|
+
if (!messages.length)
|
|
659
|
+
return { content: [{ type: "text", text: "No comments on this activity." }] };
|
|
660
|
+
const text = messages.map(formatMessage).join("\n");
|
|
661
|
+
return { content: [{ type: "text", text }] };
|
|
662
|
+
}
|
|
663
|
+
case "add_activity_message": {
|
|
664
|
+
const activityId = z.string().parse(args["activity_id"]);
|
|
665
|
+
const content = z.string().parse(args["content"]);
|
|
666
|
+
const config = getConfig(args);
|
|
667
|
+
await addActivityMessage(config, activityId, content);
|
|
668
|
+
return { content: [{ type: "text", text: `Comment added to activity ${activityId}.` }] };
|
|
669
|
+
}
|
|
627
670
|
case "list_workouts": {
|
|
628
671
|
const config = getConfig(args);
|
|
629
672
|
const workouts = await listWorkouts(config);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intervals-icu-mcp-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for Intervals.icu —
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MCP server for Intervals.icu — 24 tools for activities, wellness, calendar events, workouts and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"intervals-icu-mcp": "dist/index.js"
|