@miragon/design-iq-mcp 5.0.0-rc.0 → 5.0.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,11 +1,13 @@
1
1
  # @miragon/design-iq-mcp
2
2
 
3
- designIQ's read-only MCP server: it exposes a BPM content repo's processes to any MCP client
4
- (Claude Code, Claude Desktop, IDEs, ...). A content repo is a root `designiq.yml` naming its
5
- models folder (`models:`, legacy alias `processes:`; the legacy file name `bpmiq.yml` is still
6
- read); a model IS a file with a registered notation extension there (a process its `.bpmn`),
7
- and the process view — name, roles (BPMN lanes), steps, gateways, flow, and sub-process
8
- calls — is **derived from the BPMN** on the fly. Tools:
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
6
+ content repo is a root `designiq.yml` naming its models folder (`models:`, legacy alias
7
+ `processes:`; the legacy file name `bpmiq.yml` is still read); a model IS a file with a
8
+ registered notation extension there (a process its `.bpmn`). Views are **derived from the
9
+ models** on the fly; BPMN gets the richest one — name, roles (BPMN lanes), steps, gateways,
10
+ flow, and sub-process calls. Tools:
9
11
  `list_models`, `list_processes`, `get_process`, `get_view`, `get_model`, `enumerate_paths`,
10
12
  `find_cycles`, `who_owns`, `which_processes_use`, `which_models_use`. Read-only by
11
13
  construction: the tools only ever read files, and all of them carry `readOnlyHint`.
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-V_22sqM1.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-Df9L1Tf-.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-V_22sqM1.js";
2
+ import { n as createMcpServer, r as todosConfigFromEnv, t as DEFAULT_ROOT } from "./tools-Df9L1Tf-.js";
3
3
  import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
@@ -1583,6 +1583,20 @@ function todosConfigFromEnv(env) {
1583
1583
  apiUrl: env.GITHUB_API_URL
1584
1584
  } : void 0;
1585
1585
  }
1586
+ /** "a, b and c" */
1587
+ const andList = (items) => items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
1588
+ /** every registered notation with its file extensions */
1589
+ const NOTATION_FILES = andList(NOTATIONS.map((n) => `${n.label} (${n.extensions.join("/")})`));
1590
+ function readOnlyInstructions(on) {
1591
+ return [
1592
+ "designIQ is a Git-native workspace where teams model their business and their architecture together, live; this server reads one checkout of such a repository and never writes.",
1593
+ `The repository keeps its models as files under the folder its designiq.yml names, one model per file with the file stem as its id, in these notations: ${NOTATION_FILES}.`,
1594
+ "Start with `list_models` to see which models it holds.",
1595
+ "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).",
1596
+ "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." : "."),
1597
+ "Live editing, the modeler widgets and release as a pull request are on the designIQ Live Host, not here."
1598
+ ].join(" ");
1599
+ }
1586
1600
  /** Build a fully configured, read-only MCP server over the repo at `root`. */
1587
1601
  function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1588
1602
  const config = () => loadContentConfig(root);
@@ -1621,10 +1635,11 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1621
1635
  const unknownProcess = async (id) => fail(`Unknown process '${id}'. Available: ${(await processes()).map((p) => p.id).join(", ") || "(none)"}.`);
1622
1636
  const server = new McpServer({
1623
1637
  name: "designiq-mcp",
1638
+ title: "designIQ content repo (read-only)",
1624
1639
  version: "0.2.0"
1625
- });
1640
+ }, { instructions: readOnlyInstructions({ todos: todos !== void 0 }) });
1626
1641
  server.registerTool("list_models", {
1627
- description: "List EVERY model file of the repository, grouped by notation (bpmn, dmn, wardley, team-topology, …) — the registry-wide superset of list_processes. 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.",
1642
+ 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.`,
1628
1643
  annotations: READ_ONLY
1629
1644
  }, safe(async () => {
1630
1645
  const cfg = config();
@@ -1654,7 +1669,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1654
1669
  return ok({ models: grouped });
1655
1670
  }));
1656
1671
  server.registerTool("list_processes", {
1657
- description: "List all modeled business 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 to get a portfolio overview or to find a process id before calling get_process, get_model, who_owns or enumerate_paths.",
1672
+ 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.",
1658
1673
  annotations: READ_ONLY
1659
1674
  }, safe(async () => {
1660
1675
  if (!config()) return notAContentRepo();
@@ -1677,7 +1692,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1677
1692
  }));
1678
1693
  }));
1679
1694
  server.registerTool("get_process", {
1680
- description: "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.",
1695
+ 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.",
1681
1696
  inputSchema: z.object({ id: z.string().describe("Process id = the .bpmn file name without extension, e.g. order-to-cash") }),
1682
1697
  annotations: READ_ONLY
1683
1698
  }, safe(async ({ id }) => {
@@ -1711,7 +1726,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1711
1726
  }) : graph;
1712
1727
  }));
1713
1728
  server.registerTool("get_view", {
1714
- 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 (process view, decision tables, …). The notation-agnostic sibling of get_process: works for every notation with extract+derive capabilities (${NOTATIONS.filter((n) => hasDeriver(n.id)).map((n) => n.id).join(", ")}).`,
1729
+ 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(", ")}).`,
1715
1730
  inputSchema: z.object({
1716
1731
  id: z.string().describe("Model id = file stem (from list_models), e.g. tea-shop"),
1717
1732
  notation: z.string().optional().describe("registry notation id — disambiguates a stem shared across notations")
@@ -1778,7 +1793,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1778
1793
  });
1779
1794
  }));
1780
1795
  server.registerTool("who_owns", {
1781
- description: "Resolve ownership of a process from its BPMN 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.",
1796
+ 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.",
1782
1797
  inputSchema: z.object({ id: z.string().describe("Process id, e.g. order-to-cash") }),
1783
1798
  annotations: READ_ONLY
1784
1799
  }, safe(async ({ id }) => {
@@ -1800,7 +1815,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1800
1815
  });
1801
1816
  }));
1802
1817
  server.registerTool("which_processes_use", {
1803
- description: "Impact analysis across the portfolio: 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'.",
1818
+ 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.",
1804
1819
  inputSchema: z.object({ query: z.string().describe("Case-insensitive substring, e.g. 'invoice-handling', 'Billing', 'credit'") }),
1805
1820
  annotations: READ_ONLY
1806
1821
  }, safe(async ({ query }) => {
@@ -1834,7 +1849,7 @@ function createMcpServer(root = DEFAULT_ROOT, todos, contributions = []) {
1834
1849
  return ok(hits);
1835
1850
  }));
1836
1851
  server.registerTool("which_models_use", {
1837
- 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. The registry-wide sibling of which_processes_use; use for 'what breaks if I change or delete this model?'.",
1852
+ 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?'.",
1838
1853
  inputSchema: z.object({ id: z.string().describe("Target model id = file stem (from list_models), e.g. 'credit-check'") }),
1839
1854
  annotations: READ_ONLY
1840
1855
  }, safe(async ({ id }) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@miragon/design-iq-mcp",
3
- "version": "5.0.0-rc.0",
4
- "description": "Read-only MCP server exposing a BPM content repo's processes — discovered from designiq.yml, derived from the BPMN — to any MCP client.",
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.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -10,9 +10,15 @@
10
10
  "directory": "packages/mcp"
11
11
  },
12
12
  "keywords": [
13
+ "modeling",
14
+ "architecture",
13
15
  "bpm",
14
16
  "bpmn",
15
17
  "dmn",
18
+ "wardley-maps",
19
+ "team-topologies",
20
+ "event-storming",
21
+ "context-maps",
16
22
  "mcp",
17
23
  "model-context-protocol",
18
24
  "process-documentation"
@@ -44,9 +50,9 @@
44
50
  "@modelcontextprotocol/client": "2.1.0",
45
51
  "tsdown": "0.23.0",
46
52
  "@designiq/contracts": "0.1.0",
47
- "@designiq/http-kit": "0.1.0",
48
53
  "@designiq/github-app": "0.1.0",
49
54
  "@designiq/mcp-kit": "0.1.0",
55
+ "@designiq/http-kit": "0.1.0",
50
56
  "@designiq/notations": "0.1.0"
51
57
  },
52
58
  "scripts": {