@miragon/design-iq-mcp 5.8.1 → 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-CRI4d2yp.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-CRI4d2yp.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,10 +1051,19 @@ 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
- else if (key === "element") {
1058
+ else if (key === "type") {
1059
+ const pipe = value.indexOf(" |");
1060
+ const id = (pipe === -1 ? value : value.slice(0, pipe)).trim();
1061
+ const name = pipe === -1 ? "" : value.slice(pipe + 2).trim();
1062
+ if (id) anchor.type = {
1063
+ id,
1064
+ name: name || id
1065
+ };
1066
+ } else if (key === "element") {
1051
1067
  const pipe = value.indexOf(" | ");
1052
1068
  if (pipe === -1) anchor.elements.push({
1053
1069
  id: value.replace(/ \|$/, "").trim(),
@@ -1059,7 +1075,7 @@ function parseAnchor(text) {
1059
1075
  });
1060
1076
  }
1061
1077
  }
1062
- return anchor.process ? anchor : null;
1078
+ return anchor.notation && anchor.model ? anchor : null;
1063
1079
  }
1064
1080
  //#endregion
1065
1081
  //#region ../github-app/src/todos.ts
@@ -1075,10 +1091,12 @@ function parseAnchor(text) {
1075
1091
  */
1076
1092
  /** the label every platform-managed todo carries */
1077
1093
  const TODO_LABEL = "todo";
1078
- /** the per-process label that makes the tracker-side filter cheap */
1079
- const processLabel = (processId) => `process:${processId}`;
1080
- /** the `labels=` filter for listing: every todo, or one process's */
1081
- 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;
1082
1100
  const isPullRequestRow = (row) => row.pull_request !== void 0;
1083
1101
  //#endregion
1084
1102
  //#region ../mcp-kit/index.ts
@@ -1609,7 +1627,7 @@ function readOnlyInstructions(on) {
1609
1627
  DIAGRAMS_IN_DOCUMENTS,
1610
1628
  "Start with `list_models` to see which models it holds.",
1611
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).",
1612
- "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." : "."),
1613
1631
  "Live editing, the modeler widgets and release as a pull request are on the designIQ Live Host, not here."
1614
1632
  ].join(" ");
1615
1633
  }
@@ -1900,14 +1918,21 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1900
1918
  const api = (todos.apiUrl ?? "https://api.github.com").replace(/\/$/, "");
1901
1919
  server.registerTool("list_todos", {
1902
1920
  title: "List open todos",
1903
- 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.",
1904
- 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
+ }),
1905
1926
  annotations: {
1906
1927
  readOnlyHint: true,
1907
1928
  openWorldHint: true
1908
1929
  }
1909
- }, safe(async ({ process: processId }) => {
1910
- 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: {
1911
1936
  accept: "application/vnd.github+json",
1912
1937
  authorization: `Bearer ${todosToken}`,
1913
1938
  "user-agent": "designiq-mcp"
@@ -1921,7 +1946,10 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1921
1946
  assignees: (row.assignees ?? []).map((a) => a.login),
1922
1947
  createdAt: row.created_at
1923
1948
  }));
1924
- 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
+ }
1925
1953
  return ok(todos);
1926
1954
  }));
1927
1955
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miragon/design-iq-mcp",
3
- "version": "5.8.1",
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
52
  "@designiq/http-kit": "0.1.0",
53
+ "@designiq/contracts": "0.1.0",
54
54
  "@designiq/mcp-kit": "0.1.0",
55
- "@designiq/github-app": "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",