@miragon/design-iq-mcp 5.9.0 → 5.10.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/http.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-DizBhl75.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-D-ZnEmWn.js";
3
3
  import { createServer } from "node:http";
4
4
  import { timingSafeEqual } from "node:crypto";
5
5
  import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-DizBhl75.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-D-ZnEmWn.js";
3
3
  import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
@@ -68,6 +68,7 @@ const NOTATIONS = [
68
68
  mediaKind: "xml",
69
69
  docShape: "text",
70
70
  monacoLanguage: "xml",
71
+ todos: true,
71
72
  graphHints: {
72
73
  flowEdgeKinds: ["sequenceFlow"],
73
74
  entryNodeTypes: ["startEvent"]
@@ -100,6 +101,7 @@ const NOTATIONS = [
100
101
  mediaKind: "dsl",
101
102
  docShape: "text",
102
103
  monacoLanguage: "plaintext",
104
+ todos: true,
103
105
  graphHints: {
104
106
  flowEdgeKinds: ["dependency"],
105
107
  entryNodeTypes: []
@@ -115,7 +117,8 @@ const NOTATIONS = [
115
117
  extensions: [".tt", ".ttm.json"],
116
118
  mediaKind: "json",
117
119
  docShape: "text",
118
- monacoLanguage: "json"
120
+ monacoLanguage: "json",
121
+ todos: true
119
122
  },
120
123
  {
121
124
  id: "event-storming",
@@ -128,6 +131,7 @@ const NOTATIONS = [
128
131
  mediaKind: "dsl",
129
132
  docShape: "text",
130
133
  monacoLanguage: "plaintext",
134
+ todos: true,
131
135
  graphHints: {
132
136
  flowEdgeKinds: ["arrow"],
133
137
  entryNodeTypes: []
@@ -144,6 +148,7 @@ const NOTATIONS = [
144
148
  mediaKind: "json",
145
149
  docShape: "text",
146
150
  monacoLanguage: "json",
151
+ todos: true,
147
152
  graphHints: {
148
153
  flowEdgeKinds: [
149
154
  "partnership",
@@ -177,7 +182,8 @@ const NOTATIONS = [
177
182
  extensions: [".md"],
178
183
  mediaKind: "markdown",
179
184
  docShape: "text",
180
- monacoLanguage: "markdown"
185
+ monacoLanguage: "markdown",
186
+ todos: true
181
187
  }
182
188
  ];
183
189
  function byId(id) {
@@ -1033,7 +1039,8 @@ function parseAnchor(text) {
1033
1039
  const end = text.indexOf(CLOSE, start);
1034
1040
  if (end === -1) return null;
1035
1041
  const anchor = {
1036
- process: "",
1042
+ notation: "",
1043
+ model: "",
1037
1044
  file: null,
1038
1045
  elements: [],
1039
1046
  processVersion: null
@@ -1044,7 +1051,8 @@ function parseAnchor(text) {
1044
1051
  if (sep === -1) continue;
1045
1052
  const key = line.slice(0, sep);
1046
1053
  const value = line.slice(sep + 2).trim();
1047
- if (key === "process") anchor.process = value;
1054
+ if (key === "model") anchor.model = value;
1055
+ else if (key === "notation") anchor.notation = value;
1048
1056
  else if (key === "file") anchor.file = value;
1049
1057
  else if (key === "version") anchor.processVersion = value;
1050
1058
  else if (key === "type") {
@@ -1067,7 +1075,7 @@ function parseAnchor(text) {
1067
1075
  });
1068
1076
  }
1069
1077
  }
1070
- return anchor.process ? anchor : null;
1078
+ return anchor.notation && anchor.model ? anchor : null;
1071
1079
  }
1072
1080
  //#endregion
1073
1081
  //#region ../github-app/src/todos.ts
@@ -1083,10 +1091,12 @@ function parseAnchor(text) {
1083
1091
  */
1084
1092
  /** the label every platform-managed todo carries */
1085
1093
  const TODO_LABEL = "todo";
1086
- /** the per-process label that makes the tracker-side filter cheap */
1087
- const processLabel = (processId) => `process:${processId}`;
1088
- /** the `labels=` filter for listing: every todo, or one process's */
1089
- const todoLabelQuery = (processId) => processId ? `${TODO_LABEL},${processLabel(processId)}` : TODO_LABEL;
1094
+ /** the per-model label that makes the tracker-side filter cheap:
1095
+ * `<notation>:<id>` (`bpmn:order-to-cash`, `wardley:tea-shop`) — ids are
1096
+ * unique per notation only */
1097
+ const modelLabel = (model) => `${model.notation}:${model.id}`;
1098
+ /** the `labels=` filter for listing: every todo, or one model's */
1099
+ const todoLabelQuery = (model) => model ? `${TODO_LABEL},${modelLabel(model)}` : TODO_LABEL;
1090
1100
  const isPullRequestRow = (row) => row.pull_request !== void 0;
1091
1101
  //#endregion
1092
1102
  //#region ../mcp-kit/index.ts
@@ -1617,7 +1627,7 @@ function readOnlyInstructions(on) {
1617
1627
  DIAGRAMS_IN_DOCUMENTS,
1618
1628
  "Start with `list_models` to see which models it holds.",
1619
1629
  "These tools are notation-neutral: `get_view` (the derived structure), `get_model` (the raw graph of nodes and edges), `enumerate_paths` and `find_cycles` (flow analysis where the notation has flow semantics) and `which_models_use` (which models reference a given one).",
1620
- "BPMN has deeper tooling: `list_processes`, `get_process` (the derived process view: roles, steps, flow, sub-process calls), `who_owns` (ownership from lanes) and `which_processes_use`" + (on.todos ? "; `list_todos` lists the open todos anchored to processes." : "."),
1630
+ "BPMN has deeper tooling: `list_processes`, `get_process` (the derived process view: roles, steps, flow, sub-process calls), `who_owns` (ownership from lanes) and `which_processes_use`" + (on.todos ? "; `list_todos` lists the open todos filed on models and their elements." : "."),
1621
1631
  "Live editing, the modeler widgets and release as a pull request are on the designIQ Live Host, not here."
1622
1632
  ].join(" ");
1623
1633
  }
@@ -1908,14 +1918,21 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1908
1918
  const api = (todos.apiUrl ?? "https://api.github.com").replace(/\/$/, "");
1909
1919
  server.registerTool("list_todos", {
1910
1920
  title: "List open todos",
1911
- description: "List the OPEN model-anchored todos of this content repo — work items filed from the live model into the repo's issue tracker (label 'todo'). Each row carries the tracker id and URL, title, assignees, createdAt and the parsed anchor (process, model file, anchored BPMN elements). Optional filter on one process. Use for 'what is open on process X' or to cross-check a model answer against known open discrepancies.",
1912
- inputSchema: z.object({ process: z.string().optional().describe("Only todos anchored to this process id, e.g. order-to-cash") }),
1921
+ description: "List the OPEN model-anchored todos of this content repo — work items filed from the live model into the repo's issue tracker (label 'todo'). Each row carries the tracker id and URL, title, assignees, createdAt and the parsed anchor (notation, model id, model file, anchored elements). Optional filter on one model: `id` (and `notation` for a stem shared across notations; without it a process wins). Use for 'what is open on process X' or to cross-check a model answer against known open discrepancies.",
1922
+ inputSchema: z.object({
1923
+ id: z.string().optional().describe("Only todos of this model id (any notation, from list_models)"),
1924
+ notation: z.string().optional().describe("registry notation id — disambiguates a stem shared across notations")
1925
+ }),
1913
1926
  annotations: {
1914
1927
  readOnlyHint: true,
1915
1928
  openWorldHint: true
1916
1929
  }
1917
- }, safe(async ({ process: processId }) => {
1918
- const res = await fetch(`${api}/repos/${todosRepo}/issues?state=open&labels=${encodeURIComponent(todoLabelQuery(processId))}&per_page=100`, { headers: {
1930
+ }, safe(async ({ id, notation }) => {
1931
+ const model = id ? {
1932
+ notation: notation ?? (await findModel(id))?.notation ?? "bpmn",
1933
+ id
1934
+ } : void 0;
1935
+ const res = await fetch(`${api}/repos/${todosRepo}/issues?state=open&labels=${encodeURIComponent(todoLabelQuery(model))}&per_page=100`, { headers: {
1919
1936
  accept: "application/vnd.github+json",
1920
1937
  authorization: `Bearer ${todosToken}`,
1921
1938
  "user-agent": "designiq-mcp"
@@ -1929,7 +1946,10 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1929
1946
  assignees: (row.assignees ?? []).map((a) => a.login),
1930
1947
  createdAt: row.created_at
1931
1948
  }));
1932
- if (todos.length === 0) return ok(`No open todos${processId ? ` for process '${processId}'` : ""} in ${todosRepo}.`);
1949
+ if (todos.length === 0) {
1950
+ const of = model ? ` for ${model.notation === "bpmn" ? "process" : model.notation} '${model.id}'` : "";
1951
+ return ok(`No open todos${of} in ${todosRepo}.`);
1952
+ }
1933
1953
  return ok(todos);
1934
1954
  }));
1935
1955
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miragon/design-iq-mcp",
3
- "version": "5.9.0",
3
+ "version": "5.10.0",
4
4
  "description": "Read-only MCP server exposing a designIQ content repo's models — BPMN processes, DMN decisions, Wardley Maps, Team Topologies, Event Storming boards, Context Maps and more — to any MCP client. Discovered from designiq.yml, views derived from the models.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -49,11 +49,11 @@
49
49
  "devDependencies": {
50
50
  "@modelcontextprotocol/client": "2.3.1",
51
51
  "tsdown": "0.23.1",
52
- "@designiq/contracts": "0.1.0",
53
- "@designiq/github-app": "0.1.0",
54
52
  "@designiq/http-kit": "0.1.0",
53
+ "@designiq/contracts": "0.1.0",
55
54
  "@designiq/mcp-kit": "0.1.0",
56
- "@designiq/notations": "0.1.0"
55
+ "@designiq/notations": "0.1.0",
56
+ "@designiq/github-app": "0.1.0"
57
57
  },
58
58
  "scripts": {
59
59
  "start": "node server.ts",