@ourroadmaps/mcp 0.18.1 → 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.
Files changed (2) hide show
  1. package/dist/index.js +276 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -899,6 +899,36 @@ class ApiClient {
899
899
  method: "DELETE"
900
900
  });
901
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
+ }
902
932
  async updateDesignDescription(roadmapId, description) {
903
933
  const response = await this.request(`/v1/designs/roadmaps/${roadmapId}/design`, {
904
934
  method: "PATCH",
@@ -1018,6 +1048,12 @@ function registerAllTools(server) {
1018
1048
  registerGetHistorySummary(server);
1019
1049
  registerCreateStatusUpdate(server);
1020
1050
  registerSaveStories(server);
1051
+ registerSearchInitiatives(server);
1052
+ registerGetInitiative(server);
1053
+ registerCreateInitiative(server);
1054
+ registerUpdateInitiative(server);
1055
+ registerDeleteInitiative(server);
1056
+ registerReorderInitiatives(server);
1021
1057
  registerUploadWireframe(server);
1022
1058
  registerUpdateWireframe(server);
1023
1059
  registerDeleteWireframe(server);
@@ -1345,19 +1381,25 @@ function registerCreateRoadmapItem(server) {
1345
1381
  inputSchema: {
1346
1382
  title: z11.string().describe("Title of the roadmap item"),
1347
1383
  status: roadmapStatusSchema.optional().describe('Status (defaults to "not_started")'),
1348
- 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")
1349
1386
  }
1350
1387
  }, async ({
1351
1388
  title,
1352
1389
  status,
1353
- horizon
1390
+ horizon,
1391
+ initiativeId
1354
1392
  }) => {
1355
1393
  const client2 = getApiClient();
1356
- const roadmap2 = await client2.createRoadmap({
1394
+ const createData = {
1357
1395
  title,
1358
1396
  status: status ?? "not_started",
1359
1397
  horizon: horizon ?? "inbox"
1360
- });
1398
+ };
1399
+ if (initiativeId) {
1400
+ createData.initiativeId = initiativeId;
1401
+ }
1402
+ const roadmap2 = await client2.createRoadmap(createData);
1361
1403
  return {
1362
1404
  content: [
1363
1405
  {
@@ -1379,7 +1421,7 @@ function registerCreateRoadmapItem(server) {
1379
1421
  var effortSizeSchema = z11.enum(["xs", "s", "m", "l", "xl"]);
1380
1422
  function registerUpdateRoadmapItem(server) {
1381
1423
  server.registerTool("update_roadmap_item", {
1382
- 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.",
1383
1425
  inputSchema: {
1384
1426
  id: z11.string().describe("The UUID of the roadmap item to update"),
1385
1427
  title: z11.string().optional().describe("New title"),
@@ -1388,6 +1430,7 @@ function registerUpdateRoadmapItem(server) {
1388
1430
  value: z11.number().int().min(1).max(3).nullable().optional().describe("Value rating (1-3 stars, where 3 is highest value)"),
1389
1431
  effort: effortSizeSchema.nullable().optional().describe("Effort estimate (xs=extra small, s=small, m=medium, l=large, xl=extra large)"),
1390
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"),
1391
1434
  designDescription: z11.string().nullable().optional().describe("Description for the Design phase"),
1392
1435
  planDescription: z11.string().nullable().optional().describe("Description for the Planning phase"),
1393
1436
  buildDescription: z11.string().nullable().optional().describe("Description for the Build phase"),
@@ -1402,6 +1445,7 @@ function registerUpdateRoadmapItem(server) {
1402
1445
  value,
1403
1446
  effort,
1404
1447
  order,
1448
+ initiativeId,
1405
1449
  designDescription,
1406
1450
  planDescription,
1407
1451
  buildDescription,
@@ -1422,6 +1466,8 @@ function registerUpdateRoadmapItem(server) {
1422
1466
  updates.effort = effort;
1423
1467
  if (order !== undefined)
1424
1468
  updates.order = order;
1469
+ if (initiativeId !== undefined)
1470
+ updates.initiativeId = initiativeId;
1425
1471
  const roadmap2 = Object.keys(updates).length > 0 ? await client2.updateRoadmap(id, updates) : await client2.getRoadmap(id);
1426
1472
  const phaseUpdates = {};
1427
1473
  if (designDescription !== undefined) {
@@ -3068,6 +3114,231 @@ Expires: ${expiryDate}`
3068
3114
  };
3069
3115
  });
3070
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
+ }
3071
3342
 
3072
3343
  // src/index.ts
3073
3344
  async function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ourroadmaps/mcp",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "description": "MCP server for OurRoadmaps - manage roadmaps, features, and ideas from Claude Code",
5
5
  "type": "module",
6
6
  "bin": {