@ourroadmaps/mcp 0.18.0 → 0.19.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/index.js +283 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -536,8 +536,12 @@ class ApiClient {
|
|
|
536
536
|
searchParams.set("limit", String(params.limit));
|
|
537
537
|
if (params?.offset)
|
|
538
538
|
searchParams.set("offset", String(params.offset));
|
|
539
|
-
|
|
540
|
-
|
|
539
|
+
if (params?.horizon)
|
|
540
|
+
searchParams.set("horizon", params.horizon);
|
|
541
|
+
if (params?.query)
|
|
542
|
+
searchParams.set("query", params.query);
|
|
543
|
+
const queryString = searchParams.toString();
|
|
544
|
+
const path = queryString ? `/v1/roadmaps?${queryString}` : "/v1/roadmaps";
|
|
541
545
|
return await this.request(path);
|
|
542
546
|
}
|
|
543
547
|
async getRoadmap(id) {
|
|
@@ -895,6 +899,36 @@ class ApiClient {
|
|
|
895
899
|
method: "DELETE"
|
|
896
900
|
});
|
|
897
901
|
}
|
|
902
|
+
async listInitiatives() {
|
|
903
|
+
const response = await this.request("/v1/initiatives");
|
|
904
|
+
return response.data;
|
|
905
|
+
}
|
|
906
|
+
async getInitiative(id) {
|
|
907
|
+
return await this.request(`/v1/initiatives/${id}`);
|
|
908
|
+
}
|
|
909
|
+
async createInitiative(data) {
|
|
910
|
+
return await this.request("/v1/initiatives", {
|
|
911
|
+
method: "POST",
|
|
912
|
+
body: JSON.stringify(data)
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
async updateInitiative(id, data) {
|
|
916
|
+
return await this.request(`/v1/initiatives/${id}`, {
|
|
917
|
+
method: "PATCH",
|
|
918
|
+
body: JSON.stringify(data)
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
async deleteInitiative(id) {
|
|
922
|
+
await this.request(`/v1/initiatives/${id}`, {
|
|
923
|
+
method: "DELETE"
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
async reorderInitiatives(items) {
|
|
927
|
+
return await this.request("/v1/initiatives/reorder", {
|
|
928
|
+
method: "POST",
|
|
929
|
+
body: JSON.stringify({ items })
|
|
930
|
+
});
|
|
931
|
+
}
|
|
898
932
|
async updateDesignDescription(roadmapId, description) {
|
|
899
933
|
const response = await this.request(`/v1/designs/roadmaps/${roadmapId}/design`, {
|
|
900
934
|
method: "PATCH",
|
|
@@ -1014,6 +1048,12 @@ function registerAllTools(server) {
|
|
|
1014
1048
|
registerGetHistorySummary(server);
|
|
1015
1049
|
registerCreateStatusUpdate(server);
|
|
1016
1050
|
registerSaveStories(server);
|
|
1051
|
+
registerSearchInitiatives(server);
|
|
1052
|
+
registerGetInitiative(server);
|
|
1053
|
+
registerCreateInitiative(server);
|
|
1054
|
+
registerUpdateInitiative(server);
|
|
1055
|
+
registerDeleteInitiative(server);
|
|
1056
|
+
registerReorderInitiatives(server);
|
|
1017
1057
|
registerUploadWireframe(server);
|
|
1018
1058
|
registerUpdateWireframe(server);
|
|
1019
1059
|
registerDeleteWireframe(server);
|
|
@@ -1045,18 +1085,11 @@ function registerSearchRoadmaps(server) {
|
|
|
1045
1085
|
offset
|
|
1046
1086
|
}) => {
|
|
1047
1087
|
const client2 = getApiClient();
|
|
1048
|
-
const response = await client2.listRoadmaps({ limit, offset });
|
|
1088
|
+
const response = await client2.listRoadmaps({ limit, offset, horizon, query });
|
|
1049
1089
|
let roadmaps = response.items;
|
|
1050
|
-
if (query) {
|
|
1051
|
-
const q = query.toLowerCase();
|
|
1052
|
-
roadmaps = roadmaps.filter((r) => r.title.toLowerCase().includes(q));
|
|
1053
|
-
}
|
|
1054
1090
|
if (status) {
|
|
1055
1091
|
roadmaps = roadmaps.filter((r) => r.status === status);
|
|
1056
1092
|
}
|
|
1057
|
-
if (horizon) {
|
|
1058
|
-
roadmaps = roadmaps.filter((r) => r.horizon === horizon);
|
|
1059
|
-
}
|
|
1060
1093
|
return {
|
|
1061
1094
|
content: [
|
|
1062
1095
|
{
|
|
@@ -1348,19 +1381,25 @@ function registerCreateRoadmapItem(server) {
|
|
|
1348
1381
|
inputSchema: {
|
|
1349
1382
|
title: z11.string().describe("Title of the roadmap item"),
|
|
1350
1383
|
status: roadmapStatusSchema.optional().describe('Status (defaults to "not_started")'),
|
|
1351
|
-
horizon: horizonSchema.optional().describe('Planning horizon (defaults to "inbox")')
|
|
1384
|
+
horizon: horizonSchema.optional().describe('Planning horizon (defaults to "inbox")'),
|
|
1385
|
+
initiativeId: z11.string().optional().describe("UUID of initiative to link this item to on creation")
|
|
1352
1386
|
}
|
|
1353
1387
|
}, async ({
|
|
1354
1388
|
title,
|
|
1355
1389
|
status,
|
|
1356
|
-
horizon
|
|
1390
|
+
horizon,
|
|
1391
|
+
initiativeId
|
|
1357
1392
|
}) => {
|
|
1358
1393
|
const client2 = getApiClient();
|
|
1359
|
-
const
|
|
1394
|
+
const createData = {
|
|
1360
1395
|
title,
|
|
1361
1396
|
status: status ?? "not_started",
|
|
1362
1397
|
horizon: horizon ?? "inbox"
|
|
1363
|
-
}
|
|
1398
|
+
};
|
|
1399
|
+
if (initiativeId) {
|
|
1400
|
+
createData.initiativeId = initiativeId;
|
|
1401
|
+
}
|
|
1402
|
+
const roadmap2 = await client2.createRoadmap(createData);
|
|
1364
1403
|
return {
|
|
1365
1404
|
content: [
|
|
1366
1405
|
{
|
|
@@ -1382,7 +1421,7 @@ function registerCreateRoadmapItem(server) {
|
|
|
1382
1421
|
var effortSizeSchema = z11.enum(["xs", "s", "m", "l", "xl"]);
|
|
1383
1422
|
function registerUpdateRoadmapItem(server) {
|
|
1384
1423
|
server.registerTool("update_roadmap_item", {
|
|
1385
|
-
description: "Update an existing roadmap item. Can update title, status, horizon, value, effort, order, prompt, or brainstorm notes.",
|
|
1424
|
+
description: "Update an existing roadmap item. Can update title, status, horizon, value, effort, order, prompt, initiative link, or brainstorm notes.",
|
|
1386
1425
|
inputSchema: {
|
|
1387
1426
|
id: z11.string().describe("The UUID of the roadmap item to update"),
|
|
1388
1427
|
title: z11.string().optional().describe("New title"),
|
|
@@ -1391,6 +1430,7 @@ function registerUpdateRoadmapItem(server) {
|
|
|
1391
1430
|
value: z11.number().int().min(1).max(3).nullable().optional().describe("Value rating (1-3 stars, where 3 is highest value)"),
|
|
1392
1431
|
effort: effortSizeSchema.nullable().optional().describe("Effort estimate (xs=extra small, s=small, m=medium, l=large, xl=extra large)"),
|
|
1393
1432
|
order: z11.number().int().min(0).optional().describe("Sort order for prioritization (lower numbers appear first)"),
|
|
1433
|
+
initiativeId: z11.string().nullable().optional().describe("UUID to link item to initiative, or null to unlink from any initiative"),
|
|
1394
1434
|
designDescription: z11.string().nullable().optional().describe("Description for the Design phase"),
|
|
1395
1435
|
planDescription: z11.string().nullable().optional().describe("Description for the Planning phase"),
|
|
1396
1436
|
buildDescription: z11.string().nullable().optional().describe("Description for the Build phase"),
|
|
@@ -1405,6 +1445,7 @@ function registerUpdateRoadmapItem(server) {
|
|
|
1405
1445
|
value,
|
|
1406
1446
|
effort,
|
|
1407
1447
|
order,
|
|
1448
|
+
initiativeId,
|
|
1408
1449
|
designDescription,
|
|
1409
1450
|
planDescription,
|
|
1410
1451
|
buildDescription,
|
|
@@ -1425,6 +1466,8 @@ function registerUpdateRoadmapItem(server) {
|
|
|
1425
1466
|
updates.effort = effort;
|
|
1426
1467
|
if (order !== undefined)
|
|
1427
1468
|
updates.order = order;
|
|
1469
|
+
if (initiativeId !== undefined)
|
|
1470
|
+
updates.initiativeId = initiativeId;
|
|
1428
1471
|
const roadmap2 = Object.keys(updates).length > 0 ? await client2.updateRoadmap(id, updates) : await client2.getRoadmap(id);
|
|
1429
1472
|
const phaseUpdates = {};
|
|
1430
1473
|
if (designDescription !== undefined) {
|
|
@@ -3071,6 +3114,231 @@ Expires: ${expiryDate}`
|
|
|
3071
3114
|
};
|
|
3072
3115
|
});
|
|
3073
3116
|
}
|
|
3117
|
+
var dateGranularitySchema2 = z11.enum(["day", "month", "quarter", "half_year", "year"]);
|
|
3118
|
+
function registerSearchInitiatives(server) {
|
|
3119
|
+
server.registerTool("search_initiatives", {
|
|
3120
|
+
description: "Search for initiatives by title or filter by horizon. Returns a list of matching initiatives with item counts.",
|
|
3121
|
+
inputSchema: {
|
|
3122
|
+
query: z11.string().optional().describe("Search query to match against title or description"),
|
|
3123
|
+
horizon: horizonSchema.optional().describe("Filter by planning horizon"),
|
|
3124
|
+
limit: z11.number().int().min(1).max(100).optional().describe("Max items to return (default 10)"),
|
|
3125
|
+
offset: z11.number().int().min(0).optional().describe("Number of items to skip (default 0)")
|
|
3126
|
+
}
|
|
3127
|
+
}, async ({
|
|
3128
|
+
query,
|
|
3129
|
+
horizon,
|
|
3130
|
+
limit = 10,
|
|
3131
|
+
offset = 0
|
|
3132
|
+
}) => {
|
|
3133
|
+
const client2 = getApiClient();
|
|
3134
|
+
let initiatives = await client2.listInitiatives();
|
|
3135
|
+
if (query) {
|
|
3136
|
+
const lowerQuery = query.toLowerCase();
|
|
3137
|
+
initiatives = initiatives.filter((i) => i.title.toLowerCase().includes(lowerQuery) || i.description?.toLowerCase().includes(lowerQuery));
|
|
3138
|
+
}
|
|
3139
|
+
if (horizon) {
|
|
3140
|
+
initiatives = initiatives.filter((i) => i.horizon === horizon);
|
|
3141
|
+
}
|
|
3142
|
+
const total = initiatives.length;
|
|
3143
|
+
const paginatedInitiatives = initiatives.slice(offset, offset + limit);
|
|
3144
|
+
return {
|
|
3145
|
+
content: [
|
|
3146
|
+
{
|
|
3147
|
+
type: "text",
|
|
3148
|
+
text: JSON.stringify({
|
|
3149
|
+
items: paginatedInitiatives.map((i) => ({
|
|
3150
|
+
id: i.id,
|
|
3151
|
+
title: i.title,
|
|
3152
|
+
description: i.description,
|
|
3153
|
+
horizon: i.horizon,
|
|
3154
|
+
targetDate: i.targetDate,
|
|
3155
|
+
itemCount: i.itemCount,
|
|
3156
|
+
doneCount: i.doneCount,
|
|
3157
|
+
order: i.order
|
|
3158
|
+
})),
|
|
3159
|
+
pagination: {
|
|
3160
|
+
limit,
|
|
3161
|
+
offset,
|
|
3162
|
+
total,
|
|
3163
|
+
hasMore: offset + limit < total
|
|
3164
|
+
}
|
|
3165
|
+
}, null, 2)
|
|
3166
|
+
}
|
|
3167
|
+
]
|
|
3168
|
+
};
|
|
3169
|
+
});
|
|
3170
|
+
}
|
|
3171
|
+
function registerGetInitiative(server) {
|
|
3172
|
+
server.registerTool("get_initiative", {
|
|
3173
|
+
description: "Get full details of an initiative including all linked roadmap items.",
|
|
3174
|
+
inputSchema: {
|
|
3175
|
+
id: z11.string().describe("The UUID of the initiative")
|
|
3176
|
+
}
|
|
3177
|
+
}, async ({ id }) => {
|
|
3178
|
+
const client2 = getApiClient();
|
|
3179
|
+
const result = await client2.getInitiative(id);
|
|
3180
|
+
return {
|
|
3181
|
+
content: [
|
|
3182
|
+
{
|
|
3183
|
+
type: "text",
|
|
3184
|
+
text: JSON.stringify(result, null, 2)
|
|
3185
|
+
}
|
|
3186
|
+
]
|
|
3187
|
+
};
|
|
3188
|
+
});
|
|
3189
|
+
}
|
|
3190
|
+
function registerCreateInitiative(server) {
|
|
3191
|
+
server.registerTool("create_initiative", {
|
|
3192
|
+
description: "Create a new initiative. Initiatives group related roadmap items for cross-functional coordination.",
|
|
3193
|
+
inputSchema: {
|
|
3194
|
+
title: z11.string().describe("Title of the initiative"),
|
|
3195
|
+
description: z11.string().optional().describe("Description of the initiative (markdown)"),
|
|
3196
|
+
horizon: horizonSchema.optional().describe('Planning horizon (defaults to "inbox")'),
|
|
3197
|
+
dateGranularity: dateGranularitySchema2.optional().describe("Target date granularity: day, month, quarter, half_year, or year"),
|
|
3198
|
+
dateValue: z11.string().optional().describe('Target date value matching granularity (e.g., "2024-Q1", "2024-03")'),
|
|
3199
|
+
targetDate: z11.string().optional().describe("Target date in YYYY-MM-DD format")
|
|
3200
|
+
}
|
|
3201
|
+
}, async ({
|
|
3202
|
+
title,
|
|
3203
|
+
description,
|
|
3204
|
+
horizon,
|
|
3205
|
+
dateGranularity,
|
|
3206
|
+
dateValue,
|
|
3207
|
+
targetDate
|
|
3208
|
+
}) => {
|
|
3209
|
+
const client2 = getApiClient();
|
|
3210
|
+
const initiative = await client2.createInitiative({
|
|
3211
|
+
title,
|
|
3212
|
+
description: description ?? null,
|
|
3213
|
+
horizon: horizon ?? "inbox",
|
|
3214
|
+
dateGranularity: dateGranularity ?? null,
|
|
3215
|
+
dateValue: dateValue ?? null,
|
|
3216
|
+
targetDate: targetDate ?? null
|
|
3217
|
+
});
|
|
3218
|
+
return {
|
|
3219
|
+
content: [
|
|
3220
|
+
{
|
|
3221
|
+
type: "text",
|
|
3222
|
+
text: JSON.stringify({
|
|
3223
|
+
success: true,
|
|
3224
|
+
initiative: {
|
|
3225
|
+
id: initiative.id,
|
|
3226
|
+
title: initiative.title,
|
|
3227
|
+
description: initiative.description,
|
|
3228
|
+
horizon: initiative.horizon,
|
|
3229
|
+
targetDate: initiative.targetDate,
|
|
3230
|
+
itemCount: initiative.itemCount,
|
|
3231
|
+
doneCount: initiative.doneCount
|
|
3232
|
+
}
|
|
3233
|
+
}, null, 2)
|
|
3234
|
+
}
|
|
3235
|
+
]
|
|
3236
|
+
};
|
|
3237
|
+
});
|
|
3238
|
+
}
|
|
3239
|
+
function registerUpdateInitiative(server) {
|
|
3240
|
+
server.registerTool("update_initiative", {
|
|
3241
|
+
description: "Update an existing initiative.",
|
|
3242
|
+
inputSchema: {
|
|
3243
|
+
id: z11.string().describe("The UUID of the initiative to update"),
|
|
3244
|
+
title: z11.string().optional().describe("New title"),
|
|
3245
|
+
description: z11.string().nullable().optional().describe("New description (null to clear)"),
|
|
3246
|
+
horizon: horizonSchema.optional().describe("New planning horizon"),
|
|
3247
|
+
dateGranularity: dateGranularitySchema2.nullable().optional().describe("New target date granularity (null to clear)"),
|
|
3248
|
+
dateValue: z11.string().nullable().optional().describe("New target date value (null to clear)"),
|
|
3249
|
+
targetDate: z11.string().nullable().optional().describe("New target date in YYYY-MM-DD format (null to clear)"),
|
|
3250
|
+
order: z11.number().int().min(0).optional().describe("Sort order for prioritization (lower numbers appear first)")
|
|
3251
|
+
}
|
|
3252
|
+
}, async ({
|
|
3253
|
+
id,
|
|
3254
|
+
title,
|
|
3255
|
+
description,
|
|
3256
|
+
horizon,
|
|
3257
|
+
dateGranularity,
|
|
3258
|
+
dateValue,
|
|
3259
|
+
targetDate,
|
|
3260
|
+
order
|
|
3261
|
+
}) => {
|
|
3262
|
+
const client2 = getApiClient();
|
|
3263
|
+
const updates = {};
|
|
3264
|
+
if (title !== undefined)
|
|
3265
|
+
updates.title = title;
|
|
3266
|
+
if (description !== undefined)
|
|
3267
|
+
updates.description = description;
|
|
3268
|
+
if (horizon !== undefined)
|
|
3269
|
+
updates.horizon = horizon;
|
|
3270
|
+
if (dateGranularity !== undefined)
|
|
3271
|
+
updates.dateGranularity = dateGranularity;
|
|
3272
|
+
if (dateValue !== undefined)
|
|
3273
|
+
updates.dateValue = dateValue;
|
|
3274
|
+
if (targetDate !== undefined)
|
|
3275
|
+
updates.targetDate = targetDate;
|
|
3276
|
+
if (order !== undefined)
|
|
3277
|
+
updates.order = order;
|
|
3278
|
+
const initiative = await client2.updateInitiative(id, updates);
|
|
3279
|
+
return {
|
|
3280
|
+
content: [
|
|
3281
|
+
{
|
|
3282
|
+
type: "text",
|
|
3283
|
+
text: JSON.stringify({
|
|
3284
|
+
success: true,
|
|
3285
|
+
initiative: {
|
|
3286
|
+
id: initiative.id,
|
|
3287
|
+
title: initiative.title,
|
|
3288
|
+
description: initiative.description,
|
|
3289
|
+
horizon: initiative.horizon,
|
|
3290
|
+
targetDate: initiative.targetDate,
|
|
3291
|
+
itemCount: initiative.itemCount,
|
|
3292
|
+
doneCount: initiative.doneCount,
|
|
3293
|
+
order: initiative.order
|
|
3294
|
+
}
|
|
3295
|
+
}, null, 2)
|
|
3296
|
+
}
|
|
3297
|
+
]
|
|
3298
|
+
};
|
|
3299
|
+
});
|
|
3300
|
+
}
|
|
3301
|
+
function registerDeleteInitiative(server) {
|
|
3302
|
+
server.registerTool("delete_initiative", {
|
|
3303
|
+
description: "Delete an initiative. This is a soft delete that also unlinks all roadmap items from the initiative.",
|
|
3304
|
+
inputSchema: {
|
|
3305
|
+
id: z11.string().describe("The UUID of the initiative to delete")
|
|
3306
|
+
}
|
|
3307
|
+
}, async ({ id }) => {
|
|
3308
|
+
const client2 = getApiClient();
|
|
3309
|
+
await client2.deleteInitiative(id);
|
|
3310
|
+
return {
|
|
3311
|
+
content: [
|
|
3312
|
+
{
|
|
3313
|
+
type: "text",
|
|
3314
|
+
text: JSON.stringify({ success: true, deleted: id }, null, 2)
|
|
3315
|
+
}
|
|
3316
|
+
]
|
|
3317
|
+
};
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3320
|
+
function registerReorderInitiatives(server) {
|
|
3321
|
+
server.registerTool("reorder_initiatives", {
|
|
3322
|
+
description: "Bulk reorder initiatives by setting their order values. Lower order values appear first.",
|
|
3323
|
+
inputSchema: {
|
|
3324
|
+
items: z11.array(z11.object({
|
|
3325
|
+
id: z11.string().describe("The UUID of the initiative"),
|
|
3326
|
+
order: z11.number().int().min(0).describe("The new order value (0-based)")
|
|
3327
|
+
})).describe("Array of initiatives with their new order values")
|
|
3328
|
+
}
|
|
3329
|
+
}, async ({ items }) => {
|
|
3330
|
+
const client2 = getApiClient();
|
|
3331
|
+
await client2.reorderInitiatives(items);
|
|
3332
|
+
return {
|
|
3333
|
+
content: [
|
|
3334
|
+
{
|
|
3335
|
+
type: "text",
|
|
3336
|
+
text: JSON.stringify({ success: true, reordered: items.length }, null, 2)
|
|
3337
|
+
}
|
|
3338
|
+
]
|
|
3339
|
+
};
|
|
3340
|
+
});
|
|
3341
|
+
}
|
|
3074
3342
|
|
|
3075
3343
|
// src/index.ts
|
|
3076
3344
|
async function main() {
|