@miragon/design-iq-mcp 5.0.0 → 5.2.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @miragon/design-iq-mcp
2
2
 
3
3
  designIQ's read-only MCP server: it exposes the models of a designIQ content repo — processes
4
- (BPMN), decisions (DMN), Wardley maps, team topologies, event-storming boards, context maps,
5
- value chains and Markdown — to any MCP client (Claude Code, Claude Desktop, IDEs, ...). A
4
+ (BPMN), decisions (DMN), Wardley Maps, Team Topologies, Event Storming boards, Context Maps,
5
+ Value Chains and Markdown — to any MCP client (Claude Code, Claude Desktop, IDEs, ...). A
6
6
  content repo is a root `designiq.yml` naming its models folder (`models:`, legacy alias
7
7
  `processes:`; the legacy file name `bpmiq.yml` is still read); a model IS a file with a
8
8
  registered notation extension there (a process its `.bpmn`). Views are **derived from the
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-Df9L1Tf-.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-8vgJc4aD.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-Df9L1Tf-.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-8vgJc4aD.js";
3
3
  import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
@@ -93,8 +93,8 @@ const NOTATIONS = [
93
93
  id: "wardley",
94
94
  label: "Wardley Map",
95
95
  noun: {
96
- singular: "wardley map",
97
- plural: "wardley maps"
96
+ singular: "Wardley Map",
97
+ plural: "Wardley Maps"
98
98
  },
99
99
  extensions: [".owm", ".wmap"],
100
100
  mediaKind: "dsl",
@@ -109,8 +109,8 @@ const NOTATIONS = [
109
109
  id: "team-topology",
110
110
  label: "Team Topology",
111
111
  noun: {
112
- singular: "team topology",
113
- plural: "team topologies"
112
+ singular: "Team Topology",
113
+ plural: "Team Topologies"
114
114
  },
115
115
  extensions: [".tt", ".ttm.json"],
116
116
  mediaKind: "json",
@@ -121,8 +121,8 @@ const NOTATIONS = [
121
121
  id: "event-storming",
122
122
  label: "Event Storming",
123
123
  noun: {
124
- singular: "event storming board",
125
- plural: "event storming boards"
124
+ singular: "Event Storming board",
125
+ plural: "Event Storming boards"
126
126
  },
127
127
  extensions: [".storm"],
128
128
  mediaKind: "dsl",
@@ -137,8 +137,8 @@ const NOTATIONS = [
137
137
  id: "context-map",
138
138
  label: "Context Map",
139
139
  noun: {
140
- singular: "context map",
141
- plural: "context maps"
140
+ singular: "Context Map",
141
+ plural: "Context Maps"
142
142
  },
143
143
  extensions: [".cm.json"],
144
144
  mediaKind: "json",
@@ -159,8 +159,8 @@ const NOTATIONS = [
159
159
  id: "value-chain",
160
160
  label: "Value Chain",
161
161
  noun: {
162
- singular: "value chain",
163
- plural: "value chains"
162
+ singular: "Value Chain",
163
+ plural: "Value Chains"
164
164
  },
165
165
  extensions: [".vc.json"],
166
166
  mediaKind: "json",
@@ -1342,7 +1342,7 @@ const DERIVERS = {
1342
1342
  return {
1343
1343
  notation: "wardley",
1344
1344
  name: null,
1345
- summary: `Wardley map with ${counted(stats)}`,
1345
+ summary: `Wardley Map with ${counted(stats)}`,
1346
1346
  stats
1347
1347
  };
1348
1348
  },
@@ -1354,7 +1354,7 @@ const DERIVERS = {
1354
1354
  return {
1355
1355
  notation: "team-topology",
1356
1356
  name: null,
1357
- summary: `Team topology with ${counted(stats)}`,
1357
+ summary: `Team Topology with ${counted(stats)}`,
1358
1358
  stats
1359
1359
  };
1360
1360
  },
@@ -1378,7 +1378,7 @@ const DERIVERS = {
1378
1378
  return {
1379
1379
  notation: "event-storming",
1380
1380
  name: typeof title === "string" ? title : null,
1381
- summary: `Event storming board with ${Object.keys(present).length > 0 ? counted(present) : "no elements"}`,
1381
+ summary: `Event Storming board with ${Object.keys(present).length > 0 ? counted(present) : "no elements"}`,
1382
1382
  stats,
1383
1383
  detail: {
1384
1384
  level: graph.meta?.level ?? null,
@@ -1401,7 +1401,7 @@ const DERIVERS = {
1401
1401
  return {
1402
1402
  notation: "context-map",
1403
1403
  name: typeof title === "string" ? title : null,
1404
- summary: `Context map with ${counted({ contexts: stats.contexts })}${breakdown(CM_SUBDOMAIN_TYPES)}, ${counted({ relationships: stats.relationships })}${breakdown(CM_RELATIONSHIP_PATTERNS)}`,
1404
+ summary: `Context Map with ${counted({ contexts: stats.contexts })}${breakdown(CM_SUBDOMAIN_TYPES)}, ${counted({ relationships: stats.relationships })}${breakdown(CM_RELATIONSHIP_PATTERNS)}`,
1405
1405
  stats,
1406
1406
  detail: {
1407
1407
  contexts: graph.nodes.map((n) => ({
@@ -1432,7 +1432,7 @@ const DERIVERS = {
1432
1432
  return {
1433
1433
  notation: "value-chain",
1434
1434
  name: null,
1435
- summary: `Value chain with ${counted(stats)}`,
1435
+ summary: `Value Chain with ${counted(stats)}`,
1436
1436
  stats
1437
1437
  };
1438
1438
  }
@@ -1628,17 +1628,18 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1628
1628
  return graph;
1629
1629
  };
1630
1630
  const isGraph = (g) => !("content" in g);
1631
- /** the registry nouns for user-facing copy ("wardley map" / "team topologies") */
1631
+ /** the registry nouns for user-facing copy ("Wardley Map" / "Team Topologies") */
1632
1632
  const nounOf = (notation) => byId(notation)?.noun.singular ?? notation;
1633
1633
  const pluralOf = (notation) => byId(notation)?.noun.plural ?? notation;
1634
1634
  const notAContentRepo = () => fail(`No usable designiq.yml (or legacy bpmiq.yml) at the content root — not a content repo. Expected a root designiq.yml naming the models folder.`);
1635
1635
  const unknownProcess = async (id) => fail(`Unknown process '${id}'. Available: ${(await processes()).map((p) => p.id).join(", ") || "(none)"}.`);
1636
1636
  const server = new McpServer({
1637
1637
  name: "designiq-mcp",
1638
- title: "designIQ content repo (read-only)",
1638
+ title: "designIQ model repository (read-only)",
1639
1639
  version: "0.2.0"
1640
1640
  }, { instructions: readOnlyInstructions({ todos: todos !== void 0 }) });
1641
1641
  server.registerTool("list_models", {
1642
+ title: "List models",
1642
1643
  description: `List EVERY model file of the repository, grouped by notation (${NOTATIONS.map((n) => n.id).join(", ")}) — the starting point for any question. Each row: id (file stem), path, and — for notations with a registered deriver — the model's own name, summary and stats. Use to see which notations a repo contains before reaching for the notation-specific tools; list_processes is the BPMN-only listing.`,
1643
1644
  annotations: READ_ONLY
1644
1645
  }, safe(async () => {
@@ -1669,6 +1670,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1669
1670
  return ok({ models: grouped });
1670
1671
  }));
1671
1672
  server.registerTool("list_processes", {
1673
+ title: "List BPMN processes",
1672
1674
  description: "BPMN only: list the processes — every .bpmn file under the repo's designiq.yml models folder. Each row: id (file name without extension), derived name, the file path, and a count of steps/events/gateways/roles. Use for a process overview or to find a process id before calling get_process, get_model, who_owns or enumerate_paths; list_models covers every notation.",
1673
1675
  annotations: READ_ONLY
1674
1676
  }, safe(async () => {
@@ -1692,6 +1694,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1692
1694
  }));
1693
1695
  }));
1694
1696
  server.registerTool("get_process", {
1697
+ title: "Get BPMN process view",
1695
1698
  description: "BPMN only: get one process in full — the process view DERIVED from its BPMN: name, roles (BPMN lanes = owning teams), steps (activities with their role), events, gateways, the sequence/message flow, and the sub-processes it calls (callActivity → calledElement). Use for walkthroughs and any deep question about a single process; get_view covers every notation.",
1696
1699
  inputSchema: z.object({ id: z.string().describe("Process id = the .bpmn file name without extension, e.g. order-to-cash") }),
1697
1700
  annotations: READ_ONLY
@@ -1708,6 +1711,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1708
1711
  });
1709
1712
  }));
1710
1713
  server.registerTool("get_model", {
1714
+ title: "Get model graph",
1711
1715
  description: "Parse ANY model file into its generic graph: nodes (id, type, name), edges and meta — BPMN flows and lanes, DMN requirements, Wardley components/dependencies, … Use to see the raw structure, or to ground any 'how does X work' answer in the actual model.",
1712
1716
  inputSchema: z.object({
1713
1717
  id: z.string().describe("Model id = file stem (from list_models), e.g. order-to-cash"),
@@ -1726,6 +1730,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1726
1730
  }) : graph;
1727
1731
  }));
1728
1732
  server.registerTool("get_view", {
1733
+ title: "Get model view",
1729
1734
  description: `The derived view of ANY model — its own name, a one-line summary, stats, and the rich notation payload in \`detail\` where one exists (the process view for BPMN, the decision tables for DMN). Works for every notation with extract+derive capabilities (${NOTATIONS.filter((n) => hasDeriver(n.id)).map((n) => n.id).join(", ")}).`,
1730
1735
  inputSchema: z.object({
1731
1736
  id: z.string().describe("Model id = file stem (from list_models), e.g. tea-shop"),
@@ -1747,6 +1752,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1747
1752
  });
1748
1753
  }));
1749
1754
  server.registerTool("enumerate_paths", {
1755
+ title: "Enumerate flow paths",
1750
1756
  description: "Enumerate the possible start→end paths through a model's flow (cycle-safe, capped) — BPMN sequence flows, Wardley dependencies, … per the notation's graph hints. Each path is the ordered list of element names. Use for walkthroughs ('what are the ways an order can go?'), test-case derivation, and spotting unexpected shortcuts or dead branches.",
1751
1757
  inputSchema: z.object({
1752
1758
  id: z.string().describe("Model id = file stem, e.g. order-to-cash"),
@@ -1772,6 +1778,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1772
1778
  });
1773
1779
  }));
1774
1780
  server.registerTool("find_cycles", {
1781
+ title: "Find flow cycles",
1775
1782
  description: "Detect cycles (loops) in a model's flow — BPMN rework/retry loops, circular Wardley dependencies, circular DMN requirements — per the notation's graph hints. Returns each cycle as the ordered list of element names. Use when analyzing complexity, rework cost, or 'why does this case never finish'.",
1776
1783
  inputSchema: z.object({
1777
1784
  id: z.string().describe("Model id = file stem, e.g. order-to-cash"),
@@ -1793,6 +1800,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1793
1800
  });
1794
1801
  }));
1795
1802
  server.registerTool("who_owns", {
1803
+ title: "Find who owns a BPMN process",
1796
1804
  description: "BPMN only: resolve ownership of a process from its lanes — the roles/teams that own its steps (each lane, with the steps it contains) plus the pools (participants). Use for 'who owns X', 'who does what in X', or handoff questions. Note: on the slim contract ownership is whatever the model's lanes say; a process with no lanes has no modeled owner.",
1797
1805
  inputSchema: z.object({ id: z.string().describe("Process id, e.g. order-to-cash") }),
1798
1806
  annotations: READ_ONLY
@@ -1815,6 +1823,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1815
1823
  });
1816
1824
  }));
1817
1825
  server.registerTool("which_processes_use", {
1826
+ title: "Search BPMN processes",
1818
1827
  description: "BPMN only: find processes whose id, derived name, role/lane names, step names, or sub-process calls (calledElement) match a query — case-insensitive substring. Use for 'what calls invoice-handling', 'which processes have a Billing lane', 'what touches the credit check'. which_models_use follows references across every notation.",
1819
1828
  inputSchema: z.object({ query: z.string().describe("Case-insensitive substring, e.g. 'invoice-handling', 'Billing', 'credit'") }),
1820
1829
  annotations: READ_ONLY
@@ -1849,6 +1858,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1849
1858
  return ok(hits);
1850
1859
  }));
1851
1860
  server.registerTool("which_models_use", {
1861
+ title: "Find models that reference a model",
1852
1862
  description: "Reference-level impact analysis across EVERY notation: all models whose typed cross-model references (callActivity calls, businessRuleTask decides, …) point at the given model id (file stem, exact match) — the repo-wide reference index behind it also flags dangling references. Use for 'what breaks if I change or delete this model?'.",
1853
1863
  inputSchema: z.object({ id: z.string().describe("Target model id = file stem (from list_models), e.g. 'credit-check'") }),
1854
1864
  annotations: READ_ONLY
@@ -1873,6 +1883,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1873
1883
  const { repo: todosRepo, token: todosToken } = todos;
1874
1884
  const api = (todos.apiUrl ?? "https://api.github.com").replace(/\/$/, "");
1875
1885
  server.registerTool("list_todos", {
1886
+ title: "List open todos",
1876
1887
  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.",
1877
1888
  inputSchema: z.object({ process: z.string().optional().describe("Only todos anchored to this process id, e.g. order-to-cash") }),
1878
1889
  annotations: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@miragon/design-iq-mcp",
3
- "version": "5.0.0",
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.",
3
+ "version": "5.2.0",
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",
7
7
  "repository": {
@@ -40,19 +40,19 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@modelcontextprotocol/node": "2.1.0",
44
- "@modelcontextprotocol/server": "2.1.0",
45
- "fast-xml-parser": "5.11.1",
43
+ "@modelcontextprotocol/node": "2.1.1",
44
+ "@modelcontextprotocol/server": "2.3.0",
45
+ "fast-xml-parser": "5.11.2",
46
46
  "yaml": "2.9.1",
47
47
  "zod": "4.6.5"
48
48
  },
49
49
  "devDependencies": {
50
- "@modelcontextprotocol/client": "2.1.0",
50
+ "@modelcontextprotocol/client": "2.3.0",
51
51
  "tsdown": "0.23.0",
52
52
  "@designiq/contracts": "0.1.0",
53
53
  "@designiq/github-app": "0.1.0",
54
- "@designiq/mcp-kit": "0.1.0",
55
54
  "@designiq/http-kit": "0.1.0",
55
+ "@designiq/mcp-kit": "0.1.0",
56
56
  "@designiq/notations": "0.1.0"
57
57
  },
58
58
  "scripts": {