@unified-product-graph/mcp-server 0.8.6 → 0.8.7
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/CHANGELOG.md +4 -0
- package/TOOLS.md +6 -4
- package/dist/index.js +202 -25
- package/dist/index.js.map +1 -1
- package/dist/tools-manifest.json +44 -41
- package/package.json +2 -1
- package/skills/upg-prioritise/SKILL.md +23 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@unified-product-graph/mcp-server` are documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
4
4
|
|
|
5
|
+
## [0.8.7] - 2026-06-03
|
|
6
|
+
|
|
7
|
+
`list_frameworks` now returns a lightweight summary per framework (the full four-layer record was overflowing the tool-result token cap on the default call); `get_framework` returns the full record. `apply_framework` shares one cross-surface envelope with the CLI (`{ exercise_id, exercise, included, warnings }`). `get_framework` gives a helpful error on an unknown id. Last-writer provenance is stamped on writes. The `upg-prioritise` skill teaches the apply/score exercise flow. Co-versions the @unified-product-graph/* 0.8.7 train.
|
|
8
|
+
|
|
5
9
|
## [0.8.5] - 2026-06-02
|
|
6
10
|
|
|
7
11
|
Field-report fast-follow (tester report on 0.8.4).
|
package/TOOLS.md
CHANGED
|
@@ -1413,11 +1413,13 @@ Apply a framework (MoSCoW, RICE, Kano, ...) to a set of entities: creates a fram
|
|
|
1413
1413
|
|
|
1414
1414
|
**Returns:**
|
|
1415
1415
|
|
|
1416
|
-
JSON: `{ exercise_id, exercise, included: [{ edge_id, entity_id }], warnings }
|
|
1416
|
+
JSON: `{ exercise_id, exercise, included: [{ edge_id, entity_id, edge_type }], warnings }`
|
|
1417
|
+
(the shared cross-surface envelope; identical to CLI `apply --json`).
|
|
1417
1418
|
|
|
1418
1419
|
**Throws:**
|
|
1419
1420
|
|
|
1420
|
-
- textError on a missing/unknown framework_id
|
|
1421
|
+
- textError on a missing/unknown framework_id, or when no requested
|
|
1422
|
+
entity resolves (no dangling exercise is left behind).
|
|
1421
1423
|
|
|
1422
1424
|
**See also:** `score_entity`
|
|
1423
1425
|
|
|
@@ -2021,7 +2023,7 @@ JSON: `{ patterns: string[], total: number }`
|
|
|
2021
2023
|
|
|
2022
2024
|
### `list_frameworks`
|
|
2023
2025
|
|
|
2024
|
-
List the canonical `UPGFramework` definitions
|
|
2026
|
+
List the canonical `UPGFramework` definitions: the curated, famous product frameworks that anchor the public catalog (spanning strategy, discovery, prioritisation, design, growth, engineering, and reflection classics). Returns a lightweight summary per framework (id, name, category, description, tags, approach_ids, structure_pattern); call `get_framework(id)` for the full record. Paginated (default 50, max 200). Cursor is opaque: pass `next_cursor` from a previous response. Optional `category` is exact-match against `UPGFramework.category` and applies before pagination.
|
|
2025
2027
|
|
|
2026
2028
|
**Atomicity:** `atomic (read-only)`
|
|
2027
2029
|
|
|
@@ -2035,7 +2037,7 @@ List the canonical `UPGFramework` definitions; the 34 curated, famous product fr
|
|
|
2035
2037
|
|
|
2036
2038
|
**Returns:**
|
|
2037
2039
|
|
|
2038
|
-
JSON: `{ total, count, next_cursor?, frameworks:
|
|
2040
|
+
JSON: `{ total, count, next_cursor?, frameworks: Array<{ id, name, category, description, tags, approach_ids, structure_pattern }> }`
|
|
2039
2041
|
|
|
2040
2042
|
**See also:** `get_framework`, `list_framework_categories`, `list_framework_structure_patterns`, `prioritise`, `list_approaches`
|
|
2041
2043
|
|
package/dist/index.js
CHANGED
|
@@ -7923,7 +7923,6 @@ function migrateStatusValue(entityType, currentStatus) {
|
|
|
7923
7923
|
if (!typeMap) return null;
|
|
7924
7924
|
return typeMap[currentStatus] ?? null;
|
|
7925
7925
|
}
|
|
7926
|
-
var crossProductEdgeTypeSet = new Set(UPG_CROSS_EDGE_TYPES);
|
|
7927
7926
|
var UPG_PROPERTY_SCHEMA = {
|
|
7928
7927
|
// A11yAnnotationProperties: Accessibility annotation.
|
|
7929
7928
|
a11y_annotation: {
|
|
@@ -11080,6 +11079,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11080
11079
|
function getPropertySchema(entityType) {
|
|
11081
11080
|
return UPG_PROPERTY_SCHEMA[entityType];
|
|
11082
11081
|
}
|
|
11082
|
+
var crossProductEdgeTypeSet = new Set(UPG_CROSS_EDGE_TYPES);
|
|
11083
11083
|
var UPG_FRAMEWORKS = [
|
|
11084
11084
|
{
|
|
11085
11085
|
"id": "opportunity-solution-tree",
|
|
@@ -12315,7 +12315,7 @@ var UPG_FRAMEWORKS = [
|
|
|
12315
12315
|
],
|
|
12316
12316
|
"name": "RICE Scoring",
|
|
12317
12317
|
"version": "1.0.0",
|
|
12318
|
-
"description": "Score features and
|
|
12318
|
+
"description": "Score features, opportunities, and needs by Reach, Impact, Confidence, and Effort to produce a ranked priority list.",
|
|
12319
12319
|
"category": "prioritization",
|
|
12320
12320
|
"origin": {
|
|
12321
12321
|
"type": "practitioner",
|
|
@@ -12333,7 +12333,7 @@ var UPG_FRAMEWORKS = [
|
|
|
12333
12333
|
{
|
|
12334
12334
|
"label": "Items to score",
|
|
12335
12335
|
"entityTypeId": "feature",
|
|
12336
|
-
"description": "Features, opportunities, or
|
|
12336
|
+
"description": "Features, opportunities, or needs being evaluated"
|
|
12337
12337
|
},
|
|
12338
12338
|
{
|
|
12339
12339
|
"label": "Opportunities to score",
|
|
@@ -12499,7 +12499,60 @@ var UPG_FRAMEWORKS = [
|
|
|
12499
12499
|
"label": "RICE Score",
|
|
12500
12500
|
"format": "number"
|
|
12501
12501
|
}
|
|
12502
|
-
]
|
|
12502
|
+
],
|
|
12503
|
+
"scoring_lens": {
|
|
12504
|
+
"applies_to": [
|
|
12505
|
+
"feature",
|
|
12506
|
+
"opportunity",
|
|
12507
|
+
"need"
|
|
12508
|
+
],
|
|
12509
|
+
"inputs": [
|
|
12510
|
+
{
|
|
12511
|
+
"property": "reach",
|
|
12512
|
+
"type": "assessment",
|
|
12513
|
+
"scale_id": "reach_5",
|
|
12514
|
+
"required": true,
|
|
12515
|
+
"scope": "framework",
|
|
12516
|
+
"label": "Reach",
|
|
12517
|
+
"description": "How many users will this impact per quarter?"
|
|
12518
|
+
},
|
|
12519
|
+
{
|
|
12520
|
+
"property": "impact",
|
|
12521
|
+
"type": "assessment",
|
|
12522
|
+
"scale_id": "impact_5",
|
|
12523
|
+
"required": true,
|
|
12524
|
+
"scope": "framework",
|
|
12525
|
+
"label": "Impact",
|
|
12526
|
+
"description": "How much will this impact each user, on the impact scale?"
|
|
12527
|
+
},
|
|
12528
|
+
{
|
|
12529
|
+
"property": "confidence",
|
|
12530
|
+
"type": "assessment",
|
|
12531
|
+
"scale_id": "confidence_5",
|
|
12532
|
+
"required": true,
|
|
12533
|
+
"scope": "framework",
|
|
12534
|
+
"label": "Confidence",
|
|
12535
|
+
"description": "How confident are you in the reach, impact, and effort estimates?"
|
|
12536
|
+
},
|
|
12537
|
+
{
|
|
12538
|
+
"property": "effort",
|
|
12539
|
+
"type": "assessment",
|
|
12540
|
+
"scale_id": "effort_5",
|
|
12541
|
+
"required": true,
|
|
12542
|
+
"scope": "framework",
|
|
12543
|
+
"label": "Effort",
|
|
12544
|
+
"description": "How much work is required to build and ship this, on the effort scale?"
|
|
12545
|
+
}
|
|
12546
|
+
],
|
|
12547
|
+
"computed": [
|
|
12548
|
+
{
|
|
12549
|
+
"property": "rice_score",
|
|
12550
|
+
"expression": "(reach * impact * confidence) / effort",
|
|
12551
|
+
"label": "RICE Score",
|
|
12552
|
+
"format": "number"
|
|
12553
|
+
}
|
|
12554
|
+
]
|
|
12555
|
+
}
|
|
12503
12556
|
},
|
|
12504
12557
|
"structure": {
|
|
12505
12558
|
"pattern": "table"
|
|
@@ -14624,7 +14677,7 @@ var UPG_FRAMEWORKS = [
|
|
|
14624
14677
|
"entity_types": [
|
|
14625
14678
|
{
|
|
14626
14679
|
"type": "team",
|
|
14627
|
-
"role": "
|
|
14680
|
+
"role": "item"
|
|
14628
14681
|
},
|
|
14629
14682
|
{
|
|
14630
14683
|
"type": "retrospective",
|
|
@@ -15018,7 +15071,48 @@ var UPG_FRAMEWORKS = [
|
|
|
15018
15071
|
"label": "ICE Score",
|
|
15019
15072
|
"format": "number"
|
|
15020
15073
|
}
|
|
15021
|
-
]
|
|
15074
|
+
],
|
|
15075
|
+
"scoring_lens": {
|
|
15076
|
+
"applies_to": [
|
|
15077
|
+
"feature",
|
|
15078
|
+
"opportunity",
|
|
15079
|
+
"need"
|
|
15080
|
+
],
|
|
15081
|
+
"inputs": [
|
|
15082
|
+
{
|
|
15083
|
+
"property": "impact",
|
|
15084
|
+
"type": "number",
|
|
15085
|
+
"required": true,
|
|
15086
|
+
"scope": "framework",
|
|
15087
|
+
"label": "Impact",
|
|
15088
|
+
"description": "Expected impact on the target metric (1-10)"
|
|
15089
|
+
},
|
|
15090
|
+
{
|
|
15091
|
+
"property": "confidence",
|
|
15092
|
+
"type": "number",
|
|
15093
|
+
"required": true,
|
|
15094
|
+
"scope": "framework",
|
|
15095
|
+
"label": "Confidence",
|
|
15096
|
+
"description": "Confidence in the impact estimate (1-10)"
|
|
15097
|
+
},
|
|
15098
|
+
{
|
|
15099
|
+
"property": "ease",
|
|
15100
|
+
"type": "number",
|
|
15101
|
+
"required": true,
|
|
15102
|
+
"scope": "framework",
|
|
15103
|
+
"label": "Ease",
|
|
15104
|
+
"description": "Ease of implementation (1-10)"
|
|
15105
|
+
}
|
|
15106
|
+
],
|
|
15107
|
+
"computed": [
|
|
15108
|
+
{
|
|
15109
|
+
"property": "ice_score",
|
|
15110
|
+
"expression": "impact * confidence * ease",
|
|
15111
|
+
"label": "ICE Score",
|
|
15112
|
+
"format": "number"
|
|
15113
|
+
}
|
|
15114
|
+
]
|
|
15115
|
+
}
|
|
15022
15116
|
},
|
|
15023
15117
|
"structure": {
|
|
15024
15118
|
"pattern": "table"
|
|
@@ -15227,7 +15321,55 @@ var UPG_FRAMEWORKS = [
|
|
|
15227
15321
|
"label": "WSJF Score",
|
|
15228
15322
|
"format": "number"
|
|
15229
15323
|
}
|
|
15230
|
-
]
|
|
15324
|
+
],
|
|
15325
|
+
"scoring_lens": {
|
|
15326
|
+
"applies_to": [
|
|
15327
|
+
"feature",
|
|
15328
|
+
"opportunity"
|
|
15329
|
+
],
|
|
15330
|
+
"inputs": [
|
|
15331
|
+
{
|
|
15332
|
+
"property": "user_value",
|
|
15333
|
+
"type": "number",
|
|
15334
|
+
"required": true,
|
|
15335
|
+
"scope": "framework",
|
|
15336
|
+
"label": "User/Business Value",
|
|
15337
|
+
"description": "Relative value to users and the business if delivered"
|
|
15338
|
+
},
|
|
15339
|
+
{
|
|
15340
|
+
"property": "time_criticality",
|
|
15341
|
+
"type": "number",
|
|
15342
|
+
"required": true,
|
|
15343
|
+
"scope": "framework",
|
|
15344
|
+
"label": "Time Criticality",
|
|
15345
|
+
"description": "How much value decays if delivery is delayed (deadlines, competition, seasonal windows)"
|
|
15346
|
+
},
|
|
15347
|
+
{
|
|
15348
|
+
"property": "risk_reduction",
|
|
15349
|
+
"type": "number",
|
|
15350
|
+
"required": true,
|
|
15351
|
+
"scope": "framework",
|
|
15352
|
+
"label": "Risk Reduction / Opportunity Enablement",
|
|
15353
|
+
"description": "Value from reducing risk or enabling future opportunities"
|
|
15354
|
+
},
|
|
15355
|
+
{
|
|
15356
|
+
"property": "job_size",
|
|
15357
|
+
"type": "number",
|
|
15358
|
+
"required": true,
|
|
15359
|
+
"scope": "framework",
|
|
15360
|
+
"label": "Job Size",
|
|
15361
|
+
"description": "Estimated effort (story points, t-shirt size, or person-weeks)"
|
|
15362
|
+
}
|
|
15363
|
+
],
|
|
15364
|
+
"computed": [
|
|
15365
|
+
{
|
|
15366
|
+
"property": "wsjf_score",
|
|
15367
|
+
"expression": "(user_value + time_criticality + risk_reduction) / job_size",
|
|
15368
|
+
"label": "WSJF Score",
|
|
15369
|
+
"format": "number"
|
|
15370
|
+
}
|
|
15371
|
+
]
|
|
15372
|
+
}
|
|
15231
15373
|
},
|
|
15232
15374
|
"structure": {
|
|
15233
15375
|
"pattern": "table"
|
|
@@ -15300,7 +15442,7 @@ var UPG_FRAMEWORKS = [
|
|
|
15300
15442
|
],
|
|
15301
15443
|
"name": "Cost of Delay",
|
|
15302
15444
|
"version": "1.0.0",
|
|
15303
|
-
"description": "Quantify the economic cost of not shipping a feature to drive priority decisions. Combines urgency with value.",
|
|
15445
|
+
"description": "Quantify the economic cost of not shipping a feature or opportunity to drive priority decisions. Combines urgency with value.",
|
|
15304
15446
|
"category": "prioritization",
|
|
15305
15447
|
"origin": {
|
|
15306
15448
|
"type": "practitioner",
|
|
@@ -15416,7 +15558,39 @@ var UPG_FRAMEWORKS = [
|
|
|
15416
15558
|
"label": "WSJF Score",
|
|
15417
15559
|
"format": "number"
|
|
15418
15560
|
}
|
|
15419
|
-
]
|
|
15561
|
+
],
|
|
15562
|
+
"scoring_lens": {
|
|
15563
|
+
"applies_to": [
|
|
15564
|
+
"feature",
|
|
15565
|
+
"opportunity"
|
|
15566
|
+
],
|
|
15567
|
+
"inputs": [
|
|
15568
|
+
{
|
|
15569
|
+
"property": "cost_of_delay",
|
|
15570
|
+
"type": "number",
|
|
15571
|
+
"required": true,
|
|
15572
|
+
"scope": "framework",
|
|
15573
|
+
"label": "Cost of Delay",
|
|
15574
|
+
"description": "Weekly revenue impact of not shipping"
|
|
15575
|
+
},
|
|
15576
|
+
{
|
|
15577
|
+
"property": "job_size",
|
|
15578
|
+
"type": "number",
|
|
15579
|
+
"required": true,
|
|
15580
|
+
"scope": "framework",
|
|
15581
|
+
"label": "Job Size",
|
|
15582
|
+
"description": "Weeks of development effort"
|
|
15583
|
+
}
|
|
15584
|
+
],
|
|
15585
|
+
"computed": [
|
|
15586
|
+
{
|
|
15587
|
+
"property": "wsjf_score",
|
|
15588
|
+
"expression": "cost_of_delay / job_size",
|
|
15589
|
+
"label": "WSJF Score",
|
|
15590
|
+
"format": "number"
|
|
15591
|
+
}
|
|
15592
|
+
]
|
|
15593
|
+
}
|
|
15420
15594
|
},
|
|
15421
15595
|
"structure": {
|
|
15422
15596
|
"pattern": "table"
|
|
@@ -24004,7 +24178,7 @@ function serializePortfolioWithHeader(doc, opts) {
|
|
|
24004
24178
|
header.integrity = { algorithm: INTEGRITY_ALGORITHM, body: computeBodyChecksum(doc) };
|
|
24005
24179
|
return JSON.stringify({ $upg: header, ...body }, null, 2) + "\n";
|
|
24006
24180
|
}
|
|
24007
|
-
var UPG_VERSION = "0.8.
|
|
24181
|
+
var UPG_VERSION = "0.8.7";
|
|
24008
24182
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
24009
24183
|
var UPG_TYPES = getTypes();
|
|
24010
24184
|
var UPG_TYPES_SET = new Set(UPG_TYPES);
|
|
@@ -26513,6 +26687,7 @@ var getEntitySchema = (args, _ctx) => {
|
|
|
26513
26687
|
// src/tools/frameworks.ts
|
|
26514
26688
|
import {
|
|
26515
26689
|
applyFramework as applyFrameworkLib,
|
|
26690
|
+
applyFrameworkEnvelope,
|
|
26516
26691
|
scoreEntity as scoreEntityLib
|
|
26517
26692
|
} from "@unified-product-graph/sdk";
|
|
26518
26693
|
var applyFramework = (args, ctx) => {
|
|
@@ -26528,18 +26703,7 @@ var applyFramework = (args, ctx) => {
|
|
|
26528
26703
|
entity_ids: args.entity_ids ?? [],
|
|
26529
26704
|
status: args.status
|
|
26530
26705
|
});
|
|
26531
|
-
return text(
|
|
26532
|
-
JSON.stringify(
|
|
26533
|
-
{
|
|
26534
|
-
exercise_id: result.exercise.id,
|
|
26535
|
-
exercise: result.exercise,
|
|
26536
|
-
included: result.edges.map((e) => ({ edge_id: e.id, entity_id: e.target })),
|
|
26537
|
-
warnings: result.warnings
|
|
26538
|
-
},
|
|
26539
|
-
null,
|
|
26540
|
-
2
|
|
26541
|
-
)
|
|
26542
|
-
);
|
|
26706
|
+
return text(JSON.stringify(applyFrameworkEnvelope(result), null, 2));
|
|
26543
26707
|
} catch (err) {
|
|
26544
26708
|
return textError(err.message);
|
|
26545
26709
|
}
|
|
@@ -27286,10 +27450,19 @@ var listFrameworks = (args) => {
|
|
|
27286
27450
|
const slice = pool.slice(cursorOffset, cursorOffset + limit);
|
|
27287
27451
|
const nextOffset = cursorOffset + slice.length;
|
|
27288
27452
|
const nextCursor = nextOffset < total ? encodeCursor(nextOffset) : void 0;
|
|
27453
|
+
const frameworks = slice.map((f) => ({
|
|
27454
|
+
id: f.id,
|
|
27455
|
+
name: f.name,
|
|
27456
|
+
category: f.category,
|
|
27457
|
+
description: f.description,
|
|
27458
|
+
tags: f.tags,
|
|
27459
|
+
approach_ids: f.approach_ids,
|
|
27460
|
+
structure_pattern: f.structure?.pattern
|
|
27461
|
+
}));
|
|
27289
27462
|
const body = {
|
|
27290
27463
|
total,
|
|
27291
27464
|
count: slice.length,
|
|
27292
|
-
frameworks
|
|
27465
|
+
frameworks
|
|
27293
27466
|
};
|
|
27294
27467
|
if (nextCursor) body.next_cursor = nextCursor;
|
|
27295
27468
|
return text(JSON.stringify(body, null, 2));
|
|
@@ -27298,7 +27471,10 @@ var getFramework = (args) => {
|
|
|
27298
27471
|
const id = args.id;
|
|
27299
27472
|
if (!id) return textError("Missing required parameter: id");
|
|
27300
27473
|
const framework = UPG_FRAMEWORKS_BY_ID[id];
|
|
27301
|
-
if (!framework)
|
|
27474
|
+
if (!framework)
|
|
27475
|
+
return textError(
|
|
27476
|
+
`Unknown framework id: "${id}". Pass a framework id from the catalog (e.g. 'moscow', 'rice-scoring', 'kano-model'). See list_frameworks for the full list.`
|
|
27477
|
+
);
|
|
27302
27478
|
return text(JSON.stringify(framework, null, 2));
|
|
27303
27479
|
};
|
|
27304
27480
|
function buildEdgeEntries(filterSource, filterTarget) {
|
|
@@ -28989,7 +29165,7 @@ var TOOL_DEFINITIONS = [
|
|
|
28989
29165
|
},
|
|
28990
29166
|
{
|
|
28991
29167
|
name: "list_frameworks",
|
|
28992
|
-
description: "List the canonical `UPGFramework` definitions
|
|
29168
|
+
description: "List the canonical `UPGFramework` definitions: the curated, famous product frameworks that anchor the public catalog (spanning strategy, discovery, prioritisation, design, growth, engineering, and reflection classics). Returns a lightweight summary per framework (id, name, category, description, tags, approach_ids, structure_pattern); call `get_framework(id)` for the full record. Paginated (default 50, max 200). Cursor is opaque: pass `next_cursor` from a previous response. Optional `category` is exact-match against `UPGFramework.category` and applies before pagination.",
|
|
28993
29169
|
inputSchema: {
|
|
28994
29170
|
type: "object",
|
|
28995
29171
|
properties: {
|
|
@@ -29918,6 +30094,7 @@ async function runMcpServer() {
|
|
|
29918
30094
|
}
|
|
29919
30095
|
}
|
|
29920
30096
|
const store = new UPGFileStore();
|
|
30097
|
+
store.setWriter("upg-mcp-local", SERVER_VERSION);
|
|
29921
30098
|
await store.load(resolvedPath);
|
|
29922
30099
|
const deprecated = getDeprecatedTypes();
|
|
29923
30100
|
const nodes = store.getAllNodes();
|