@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.
- package/dist/index.js +279 -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
|
|
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.
|
|
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": "
|
|
33
|
+
"license": "UNLICENSED",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@modelcontextprotocol/sdk": "^1.24.3",
|
|
36
36
|
"@ourroadmaps/shared": "*",
|