@ourroadmaps/mcp 0.7.4 → 0.8.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 +44 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -102,6 +102,7 @@ var featureSchema = z4.object({
|
|
|
102
102
|
organizationId: z4.string(),
|
|
103
103
|
type: featureTypeSchema,
|
|
104
104
|
name: z4.string(),
|
|
105
|
+
description: z4.string().nullable(),
|
|
105
106
|
parentId: z4.string().uuid().nullable(),
|
|
106
107
|
order: z4.number().int(),
|
|
107
108
|
isExpanded: z4.boolean(),
|
|
@@ -460,9 +461,15 @@ class ApiClient {
|
|
|
460
461
|
}
|
|
461
462
|
return await response.json();
|
|
462
463
|
}
|
|
463
|
-
async listRoadmaps() {
|
|
464
|
-
const
|
|
465
|
-
|
|
464
|
+
async listRoadmaps(params) {
|
|
465
|
+
const searchParams = new URLSearchParams;
|
|
466
|
+
if (params?.limit)
|
|
467
|
+
searchParams.set("limit", String(params.limit));
|
|
468
|
+
if (params?.offset)
|
|
469
|
+
searchParams.set("offset", String(params.offset));
|
|
470
|
+
const query = searchParams.toString();
|
|
471
|
+
const path = query ? `/v1/roadmaps?${query}` : "/v1/roadmaps";
|
|
472
|
+
return await this.request(path);
|
|
466
473
|
}
|
|
467
474
|
async getRoadmap(id) {
|
|
468
475
|
const response = await this.request(`/v1/roadmaps/${id}`);
|
|
@@ -528,11 +535,17 @@ class ApiClient {
|
|
|
528
535
|
method: "DELETE"
|
|
529
536
|
});
|
|
530
537
|
}
|
|
531
|
-
async
|
|
532
|
-
await this.request(`/v1/features/${featureId}/outcomes`, {
|
|
538
|
+
async saveFeatureOutcomes(featureId, outcomes) {
|
|
539
|
+
const response = await this.request(`/v1/features/${featureId}/outcomes`, {
|
|
533
540
|
method: "POST",
|
|
534
|
-
body: JSON.stringify({
|
|
541
|
+
body: JSON.stringify({
|
|
542
|
+
outcomes: outcomes.map((description, index) => ({
|
|
543
|
+
description,
|
|
544
|
+
order: index
|
|
545
|
+
}))
|
|
546
|
+
})
|
|
535
547
|
});
|
|
548
|
+
return response.data;
|
|
536
549
|
}
|
|
537
550
|
async linkFeatureToRoadmap(featureId, roadmapId) {
|
|
538
551
|
await this.request(`/v1/features/${featureId}/roadmap-items`, {
|
|
@@ -749,15 +762,20 @@ function registerSearchRoadmaps(server) {
|
|
|
749
762
|
inputSchema: {
|
|
750
763
|
query: z10.string().optional().describe("Search query to match against title or description"),
|
|
751
764
|
status: roadmapStatusSchema.optional().describe("Filter by status"),
|
|
752
|
-
horizon: horizonSchema.optional().describe("Filter by planning horizon")
|
|
765
|
+
horizon: horizonSchema.optional().describe("Filter by planning horizon"),
|
|
766
|
+
limit: z10.number().int().min(1).max(100).optional().describe("Max items to return (default 10)"),
|
|
767
|
+
offset: z10.number().int().min(0).optional().describe("Number of items to skip (default 0)")
|
|
753
768
|
}
|
|
754
769
|
}, async ({
|
|
755
770
|
query,
|
|
756
771
|
status,
|
|
757
|
-
horizon
|
|
772
|
+
horizon,
|
|
773
|
+
limit,
|
|
774
|
+
offset
|
|
758
775
|
}) => {
|
|
759
776
|
const client2 = getApiClient();
|
|
760
|
-
|
|
777
|
+
const response = await client2.listRoadmaps({ limit, offset });
|
|
778
|
+
let roadmaps = response.items;
|
|
761
779
|
if (query) {
|
|
762
780
|
const q = query.toLowerCase();
|
|
763
781
|
roadmaps = roadmaps.filter((r) => r.title.toLowerCase().includes(q));
|
|
@@ -772,15 +790,18 @@ function registerSearchRoadmaps(server) {
|
|
|
772
790
|
content: [
|
|
773
791
|
{
|
|
774
792
|
type: "text",
|
|
775
|
-
text: JSON.stringify(
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
793
|
+
text: JSON.stringify({
|
|
794
|
+
items: roadmaps.map((r) => ({
|
|
795
|
+
id: r.id,
|
|
796
|
+
title: r.title,
|
|
797
|
+
status: r.status,
|
|
798
|
+
horizon: r.horizon,
|
|
799
|
+
value: r.value,
|
|
800
|
+
effort: r.effort,
|
|
801
|
+
order: r.order
|
|
802
|
+
})),
|
|
803
|
+
pagination: response.pagination
|
|
804
|
+
}, null, 2)
|
|
784
805
|
}
|
|
785
806
|
]
|
|
786
807
|
};
|
|
@@ -947,28 +968,20 @@ function registerGetContext(server) {
|
|
|
947
968
|
- Audiences: Who the product serves (stakeholders and user personas) with their preferences
|
|
948
969
|
- Scenarios: User workflows and how they accomplish goals
|
|
949
970
|
- Features: Capabilities and functionality areas organized hierarchically
|
|
950
|
-
- Roadmap Summary:
|
|
971
|
+
- Roadmap Summary: Total count of roadmap items
|
|
951
972
|
|
|
952
973
|
Use this as your FIRST call when starting work on a roadmap to understand the full context.`,
|
|
953
974
|
inputSchema: {}
|
|
954
975
|
}, async () => {
|
|
955
976
|
const client2 = getApiClient();
|
|
956
|
-
const [strategy, products, audiences, scenarios, features,
|
|
977
|
+
const [strategy, products, audiences, scenarios, features, roadmapsResponse] = await Promise.all([
|
|
957
978
|
client2.getStrategy(),
|
|
958
979
|
client2.listProducts(),
|
|
959
980
|
client2.listAudiences(),
|
|
960
981
|
client2.listScenarios(),
|
|
961
982
|
client2.listFeatures(),
|
|
962
|
-
client2.listRoadmaps()
|
|
983
|
+
client2.listRoadmaps({ limit: 1 })
|
|
963
984
|
]);
|
|
964
|
-
const statusCounts = {};
|
|
965
|
-
const horizonCounts = {};
|
|
966
|
-
for (const r of roadmaps) {
|
|
967
|
-
const status = r.status ?? "unknown";
|
|
968
|
-
const horizon = r.horizon ?? "unknown";
|
|
969
|
-
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
970
|
-
horizonCounts[horizon] = (horizonCounts[horizon] || 0) + 1;
|
|
971
|
-
}
|
|
972
985
|
return {
|
|
973
986
|
content: [
|
|
974
987
|
{
|
|
@@ -1006,9 +1019,7 @@ Use this as your FIRST call when starting work on a roadmap to understand the fu
|
|
|
1006
1019
|
parentId: f.parentId
|
|
1007
1020
|
})),
|
|
1008
1021
|
roadmapSummary: {
|
|
1009
|
-
total:
|
|
1010
|
-
byStatus: statusCounts,
|
|
1011
|
-
byHorizon: horizonCounts
|
|
1022
|
+
total: roadmapsResponse.pagination.total
|
|
1012
1023
|
}
|
|
1013
1024
|
}, null, 2)
|
|
1014
1025
|
}
|
|
@@ -1177,9 +1188,7 @@ function registerAddFeature(server) {
|
|
|
1177
1188
|
parentId: parentId ?? null
|
|
1178
1189
|
});
|
|
1179
1190
|
if (outcomes && outcomes.length > 0) {
|
|
1180
|
-
|
|
1181
|
-
await client2.addFeatureOutcome(feature2.id, outcome);
|
|
1182
|
-
}
|
|
1191
|
+
await client2.saveFeatureOutcomes(feature2.id, outcomes);
|
|
1183
1192
|
}
|
|
1184
1193
|
if (linkToRoadmapId) {
|
|
1185
1194
|
await client2.linkFeatureToRoadmap(feature2.id, linkToRoadmapId);
|