@ourroadmaps/mcp 0.5.0 → 0.7.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 +279 -2
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -23670,6 +23670,70 @@ var updateProductSchema = exports_external.object({
23670
23670
  order: exports_external.number().int().optional()
23671
23671
  });
23672
23672
  var productListSchema = exports_external.array(productSchema);
23673
+ // ../../packages/shared/src/schemas/story.ts
23674
+ var epicSchema = exports_external.object({
23675
+ id: exports_external.string().uuid(),
23676
+ roadmapItemId: exports_external.string().uuid(),
23677
+ organizationId: exports_external.string(),
23678
+ title: exports_external.string(),
23679
+ description: exports_external.string().nullable(),
23680
+ order: exports_external.number().int(),
23681
+ createdAt: exports_external.string(),
23682
+ updatedAt: exports_external.string(),
23683
+ deletedAt: exports_external.string().nullable()
23684
+ });
23685
+ var storySchema = exports_external.object({
23686
+ id: exports_external.string().uuid(),
23687
+ roadmapItemId: exports_external.string().uuid(),
23688
+ epicId: exports_external.string().uuid().nullable(),
23689
+ organizationId: exports_external.string(),
23690
+ title: exports_external.string(),
23691
+ description: exports_external.string().nullable(),
23692
+ order: exports_external.number().int(),
23693
+ createdAt: exports_external.string(),
23694
+ updatedAt: exports_external.string(),
23695
+ deletedAt: exports_external.string().nullable()
23696
+ });
23697
+ var epicWithStoriesSchema = epicSchema.extend({
23698
+ stories: exports_external.array(storySchema)
23699
+ });
23700
+ var createEpicSchema = exports_external.object({
23701
+ title: exports_external.string().min(1),
23702
+ description: exports_external.string().nullable().optional()
23703
+ });
23704
+ var createStorySchema = exports_external.object({
23705
+ title: exports_external.string().min(1),
23706
+ description: exports_external.string().nullable().optional()
23707
+ });
23708
+ var saveStoriesInputSchema = exports_external.object({
23709
+ epics: exports_external.array(exports_external.object({
23710
+ title: exports_external.string().min(1),
23711
+ description: exports_external.string().nullable().optional(),
23712
+ stories: exports_external.array(exports_external.object({
23713
+ title: exports_external.string().min(1),
23714
+ description: exports_external.string().nullable().optional()
23715
+ })).optional().default([])
23716
+ })).optional().default([]),
23717
+ stories: exports_external.array(exports_external.object({
23718
+ title: exports_external.string().min(1),
23719
+ description: exports_external.string().nullable().optional()
23720
+ })).optional().default([])
23721
+ });
23722
+ var updateEpicSchema = exports_external.object({
23723
+ title: exports_external.string().min(1).optional(),
23724
+ description: exports_external.string().nullable().optional()
23725
+ });
23726
+ var updateStorySchema = exports_external.object({
23727
+ title: exports_external.string().min(1).optional(),
23728
+ description: exports_external.string().nullable().optional(),
23729
+ epicId: exports_external.string().uuid().nullable().optional()
23730
+ });
23731
+ var reorderStoriesSchema = exports_external.object({
23732
+ epicOrder: exports_external.array(exports_external.string().uuid()).optional(),
23733
+ storyOrder: exports_external.record(exports_external.string(), exports_external.array(exports_external.string().uuid())).optional(),
23734
+ standaloneOrder: exports_external.array(exports_external.string().uuid()).optional()
23735
+ });
23736
+
23673
23737
  // ../../packages/shared/src/schemas/roadmap.ts
23674
23738
  var flexibleDateSchema = exports_external.object({
23675
23739
  value: exports_external.string(),
@@ -23782,7 +23846,9 @@ var roadmapDetailSchema = roadmapSchema.extend({
23782
23846
  wireframes: exports_external.array(wireframeSchema),
23783
23847
  brainstormMedia: exports_external.array(brainstormMediaSchema),
23784
23848
  brainstormNotes: exports_external.string().nullable(),
23785
- featureLinks: exports_external.array(featureLinkSchema)
23849
+ featureLinks: exports_external.array(featureLinkSchema),
23850
+ epics: exports_external.array(epicWithStoriesSchema),
23851
+ stories: exports_external.array(storySchema)
23786
23852
  });
23787
23853
  var roadmapListSchema = exports_external.array(roadmapSchema);
23788
23854
  // ../../packages/shared/src/schemas/scenario.ts
@@ -23976,6 +24042,21 @@ class ApiClient {
23976
24042
  });
23977
24043
  return response.data;
23978
24044
  }
24045
+ async getProduct(id) {
24046
+ const response = await this.request(`/v1/products/${id}`);
24047
+ return response.data;
24048
+ }
24049
+ async getProductDocumentation(productId) {
24050
+ const response = await this.request(`/v1/products/${productId}/documentation`);
24051
+ return response.data;
24052
+ }
24053
+ async updateProductDocumentation(productId, data) {
24054
+ const response = await this.request(`/v1/products/${productId}/documentation`, {
24055
+ method: "PUT",
24056
+ body: JSON.stringify(data)
24057
+ });
24058
+ return response.data;
24059
+ }
23979
24060
  async listAudiences() {
23980
24061
  const response = await this.request("/v1/audiences");
23981
24062
  return response.data;
@@ -24055,6 +24136,13 @@ class ApiClient {
24055
24136
  const response = await this.request(`/v1/history?${searchParams.toString()}`);
24056
24137
  return response.data;
24057
24138
  }
24139
+ async saveStories(roadmapId, data) {
24140
+ const response = await this.request(`/v1/roadmaps/${roadmapId}/stories`, {
24141
+ method: "POST",
24142
+ body: JSON.stringify(data)
24143
+ });
24144
+ return response.data;
24145
+ }
24058
24146
  }
24059
24147
  var client = null;
24060
24148
  function getApiClient() {
@@ -24093,12 +24181,17 @@ function registerAllTools(server) {
24093
24181
  registerCreateProduct(server);
24094
24182
  registerUpdateProduct(server);
24095
24183
  registerDeleteProduct(server);
24184
+ registerGetProduct(server);
24185
+ registerSearchProducts(server);
24186
+ registerGetProductDocumentation(server);
24187
+ registerUpdateProductDocumentation(server);
24096
24188
  registerCreateAudience(server);
24097
24189
  registerUpdateAudience(server);
24098
24190
  registerDeleteAudience(server);
24099
24191
  registerListStatusUpdates(server);
24100
24192
  registerGetHistory(server);
24101
24193
  registerCreateStatusUpdate(server);
24194
+ registerSaveStories(server);
24102
24195
  }
24103
24196
  function registerSearchRoadmaps(server) {
24104
24197
  server.registerTool("search_roadmaps", {
@@ -24142,7 +24235,7 @@ function registerSearchRoadmaps(server) {
24142
24235
  }
24143
24236
  function registerGetRoadmap(server) {
24144
24237
  server.registerTool("get_roadmap", {
24145
- description: "Get full details of a roadmap item including PRD, wireframes, brainstorm media, linked features, and scenarios.",
24238
+ description: "Get full details of a roadmap item including PRD, wireframes, brainstorm media, linked features, epics, and stories.",
24146
24239
  inputSchema: {
24147
24240
  id: exports_external.string().describe("The UUID of the roadmap item")
24148
24241
  }
@@ -24177,6 +24270,8 @@ function registerGetRoadmap(server) {
24177
24270
  featureName: l.feature.name,
24178
24271
  featureType: l.feature.type
24179
24272
  })),
24273
+ epics: roadmap2.epics,
24274
+ stories: roadmap2.stories,
24180
24275
  createdAt: roadmap2.createdAt
24181
24276
  }, null, 2)
24182
24277
  }
@@ -25043,6 +25138,145 @@ function registerDeleteProduct(server) {
25043
25138
  };
25044
25139
  });
25045
25140
  }
25141
+ function registerGetProduct(server) {
25142
+ server.registerTool("get_product", {
25143
+ description: "Get full details of a product by ID, including its documentation (design system and ADRs).",
25144
+ inputSchema: {
25145
+ id: exports_external.string().describe("The UUID of the product")
25146
+ }
25147
+ }, async ({ id }) => {
25148
+ const client2 = getApiClient();
25149
+ const [product2, documentation] = await Promise.all([
25150
+ client2.getProduct(id),
25151
+ client2.getProductDocumentation(id)
25152
+ ]);
25153
+ return {
25154
+ content: [
25155
+ {
25156
+ type: "text",
25157
+ text: JSON.stringify({
25158
+ product: {
25159
+ id: product2.id,
25160
+ type: product2.type,
25161
+ name: product2.name,
25162
+ parentId: product2.parentId,
25163
+ order: product2.order,
25164
+ isExpanded: product2.isExpanded,
25165
+ createdAt: product2.createdAt
25166
+ },
25167
+ documentation: documentation ? {
25168
+ designSystem: documentation.designSystem,
25169
+ adrs: documentation.adrs,
25170
+ updatedAt: documentation.updatedAt
25171
+ } : null
25172
+ }, null, 2)
25173
+ }
25174
+ ]
25175
+ };
25176
+ });
25177
+ }
25178
+ function registerSearchProducts(server) {
25179
+ server.registerTool("search_products", {
25180
+ description: "Search for products by name. Returns a list of matching products with basic info.",
25181
+ inputSchema: {
25182
+ query: exports_external.string().optional().describe("Search query to match against product name"),
25183
+ type: productTypeSchema2.optional().describe("Filter by product type")
25184
+ }
25185
+ }, async ({ query, type }) => {
25186
+ const client2 = getApiClient();
25187
+ let products = await client2.listProducts();
25188
+ if (query) {
25189
+ const lowerQuery = query.toLowerCase();
25190
+ products = products.filter((p) => p.name.toLowerCase().includes(lowerQuery));
25191
+ }
25192
+ if (type) {
25193
+ products = products.filter((p) => p.type === type);
25194
+ }
25195
+ return {
25196
+ content: [
25197
+ {
25198
+ type: "text",
25199
+ text: JSON.stringify({
25200
+ count: products.length,
25201
+ products: products.map((p) => ({
25202
+ id: p.id,
25203
+ type: p.type,
25204
+ name: p.name,
25205
+ parentId: p.parentId
25206
+ }))
25207
+ }, null, 2)
25208
+ }
25209
+ ]
25210
+ };
25211
+ });
25212
+ }
25213
+ function registerGetProductDocumentation(server) {
25214
+ server.registerTool("get_product_documentation", {
25215
+ description: "Get the documentation (design system and ADRs) for a product. Use this to read existing documentation before updating.",
25216
+ inputSchema: {
25217
+ productId: exports_external.string().describe("The UUID of the product")
25218
+ }
25219
+ }, async ({ productId }) => {
25220
+ const client2 = getApiClient();
25221
+ const documentation = await client2.getProductDocumentation(productId);
25222
+ return {
25223
+ content: [
25224
+ {
25225
+ type: "text",
25226
+ text: JSON.stringify({
25227
+ productId,
25228
+ documentation: documentation ? {
25229
+ id: documentation.id,
25230
+ designSystem: documentation.designSystem,
25231
+ adrs: documentation.adrs,
25232
+ createdAt: documentation.createdAt,
25233
+ updatedAt: documentation.updatedAt
25234
+ } : null
25235
+ }, null, 2)
25236
+ }
25237
+ ]
25238
+ };
25239
+ });
25240
+ }
25241
+ function registerUpdateProductDocumentation(server) {
25242
+ server.registerTool("update_product_documentation", {
25243
+ description: "Update the documentation for a product. Use this to keep design system and ADRs up to date. Creates documentation if it does not exist.",
25244
+ inputSchema: {
25245
+ productId: exports_external.string().describe("The UUID of the product"),
25246
+ designSystem: exports_external.string().nullable().optional().describe("Design system documentation - colors, typography, spacing, components. Pass null to clear."),
25247
+ adrs: exports_external.string().nullable().optional().describe("Architecture Decision Records - document key technical decisions. Pass null to clear.")
25248
+ }
25249
+ }, async ({
25250
+ productId,
25251
+ designSystem,
25252
+ adrs
25253
+ }) => {
25254
+ const client2 = getApiClient();
25255
+ const updates = {};
25256
+ if (designSystem !== undefined)
25257
+ updates.designSystem = designSystem;
25258
+ if (adrs !== undefined)
25259
+ updates.adrs = adrs;
25260
+ const documentation = await client2.updateProductDocumentation(productId, updates);
25261
+ return {
25262
+ content: [
25263
+ {
25264
+ type: "text",
25265
+ text: JSON.stringify({
25266
+ success: true,
25267
+ documentation: {
25268
+ id: documentation.id,
25269
+ productId: documentation.productId,
25270
+ designSystem: documentation.designSystem,
25271
+ adrs: documentation.adrs,
25272
+ updatedAt: documentation.updatedAt
25273
+ }
25274
+ }, null, 2)
25275
+ }
25276
+ ]
25277
+ };
25278
+ });
25279
+ }
25046
25280
  var audienceTypeSchema2 = exports_external.enum(["stakeholder", "user_persona"]);
25047
25281
  function registerCreateAudience(server) {
25048
25282
  server.registerTool("create_audience", {
@@ -25258,6 +25492,49 @@ function registerCreateStatusUpdate(server) {
25258
25492
  };
25259
25493
  });
25260
25494
  }
25495
+ function registerSaveStories(server) {
25496
+ server.registerTool("save_stories", {
25497
+ description: "Save epics and stories for a roadmap item. Replaces all existing epics/stories. Use this to set the complete list of epics and stories for a roadmap.",
25498
+ inputSchema: {
25499
+ roadmapId: exports_external.string().uuid().describe("The UUID of the roadmap item"),
25500
+ epics: exports_external.array(exports_external.object({
25501
+ title: exports_external.string().min(1).describe("Title of the epic"),
25502
+ description: exports_external.string().nullable().optional().describe("Description of the epic"),
25503
+ stories: exports_external.array(exports_external.object({
25504
+ title: exports_external.string().min(1).describe("Title of the story"),
25505
+ description: exports_external.string().nullable().optional().describe("Description of the story")
25506
+ })).optional().describe("Stories within this epic")
25507
+ })).optional().describe("List of epics with their nested stories"),
25508
+ stories: exports_external.array(exports_external.object({
25509
+ title: exports_external.string().min(1).describe("Title of the story"),
25510
+ description: exports_external.string().nullable().optional().describe("Description of the story")
25511
+ })).optional().describe("List of standalone stories (not part of any epic)")
25512
+ }
25513
+ }, async ({
25514
+ roadmapId,
25515
+ epics,
25516
+ stories
25517
+ }) => {
25518
+ const client2 = getApiClient();
25519
+ const result = await client2.saveStories(roadmapId, {
25520
+ epics: epics ?? [],
25521
+ stories: stories ?? []
25522
+ });
25523
+ return {
25524
+ content: [
25525
+ {
25526
+ type: "text",
25527
+ text: JSON.stringify({
25528
+ success: true,
25529
+ epicCount: result.epics.length,
25530
+ storyCount: result.stories.length,
25531
+ totalStories: result.stories.length + result.epics.reduce((sum, epic) => sum + (epic.stories?.length ?? 0), 0)
25532
+ }, null, 2)
25533
+ }
25534
+ ]
25535
+ };
25536
+ });
25537
+ }
25261
25538
 
25262
25539
  // src/index.ts
25263
25540
  async function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ourroadmaps/mcp",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server for OurRoadmaps - manage roadmaps, features, and ideas from Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "url": "https://github.com/bgraner/roadmaps3.git",
31
31
  "directory": "apps/mcp"
32
32
  },
33
- "license": "MIT",
33
+ "license": "UNLICENSED",
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.24.3",
36
36
  "@ourroadmaps/shared": "*",