@endiagram/mcp 0.1.16 → 0.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 +24 -18
- package/dist/index.js +39 -20
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @endiagram/mcp
|
|
2
2
|
|
|
3
|
-
MCP server for [EN Diagram](https://endiagram.com) — structural analysis powered by
|
|
4
|
-
|
|
5
|
-
Write your system in plain text. Get back structural facts: bottlenecks, blast radius, flow landmarks, concurrency groups, and more. No AI inside the computation — every result is deterministic.
|
|
3
|
+
MCP server for [EN Diagram](https://endiagram.com) — deterministic structural analysis powered by graph theory. Every result is backed by a named mathematical theorem. No AI inside the computation.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
@@ -80,25 +78,34 @@ smithery mcp add dushyant30suthar/endiagram
|
|
|
80
78
|
|
|
81
79
|
| Tool | Description |
|
|
82
80
|
|------|-------------|
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `detail` | Deep structural analysis — concurrency, flow landmarks, resilience, dominator tree, min-cuts |
|
|
86
|
-
| `distance` | Shortest path between two nodes with subsystem crossing annotations |
|
|
87
|
-
| `diff` | Structural diff between two systems — topology, role, and subsystem changes |
|
|
88
|
-
| `trace` | Follow directed flow from node A to node B with role and subsystem annotations |
|
|
89
|
-
| `extract` | Extract a named subsystem as standalone EN source code |
|
|
90
|
-
| `impact` | Blast radius — remove a node and see what disconnects |
|
|
91
|
-
| `evolve` | Dry-run architectural changes — apply a patch and see the structural delta |
|
|
92
|
-
| `between` | Betweenness centrality — what fraction of all shortest paths flow through a node |
|
|
81
|
+
| `analyze` | System overview: shape, node roles, single points of failure, failure threshold, flow hotspots |
|
|
82
|
+
| `detail` | Concurrency, critical path, flow landmarks, resilience, dependency chains, dominator tree |
|
|
93
83
|
| `categorize` | Auto-discover subsystem boundaries from dependency structure |
|
|
94
|
-
| `
|
|
84
|
+
| `distance` | Structural distance between two nodes with the path between them |
|
|
85
|
+
| `diff` | Compare two systems — what changed structurally |
|
|
86
|
+
| `trace` | Follow directed flow from A to B, optional defense node coverage check |
|
|
87
|
+
| `between` | How much of the system flows through a specific node |
|
|
88
|
+
| `extract` | Extract a subsystem as standalone EN source |
|
|
89
|
+
| `impact` | What changes if a node is removed, includes propagation |
|
|
90
|
+
| `evolve` | Dry-run a structural change before making it |
|
|
91
|
+
| `compose` | Merge two systems into one by linking shared entities |
|
|
92
|
+
| `conserve` | Structural invariants, deadlock analysis, complexity, resilience |
|
|
93
|
+
| `render` | SVG diagram |
|
|
95
94
|
|
|
96
95
|
## EN Syntax
|
|
97
96
|
|
|
97
|
+
One statement per line:
|
|
98
|
+
|
|
98
99
|
```
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
actor do: action needs: input1, input2 yields: output1, output2
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Shared names between yields and needs create connections automatically:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
customer do: place order needs: menu yields: order
|
|
107
|
+
kitchen do: prepare food needs: order yields: meal
|
|
108
|
+
waiter do: deliver needs: meal yields: served customer
|
|
102
109
|
```
|
|
103
110
|
|
|
104
111
|
Learn more at [endiagram.com](https://endiagram.com).
|
|
@@ -106,4 +113,3 @@ Learn more at [endiagram.com](https://endiagram.com).
|
|
|
106
113
|
## License
|
|
107
114
|
|
|
108
115
|
MIT
|
|
109
|
-
|
package/dist/index.js
CHANGED
|
@@ -27,13 +27,22 @@ async function callApi(toolName, args) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
const
|
|
30
|
+
const EN_INSTRUCTIONS = `EN Diagram is a deterministic structural analysis engine. No AI inside — all results are backed by named mathematical theorems.
|
|
31
|
+
|
|
32
|
+
To describe a system, write one statement per line:
|
|
33
|
+
actor do: action needs: input1, input2 yields: output1, output2
|
|
34
|
+
|
|
35
|
+
Shared names between yields and needs create connections automatically. Multi-word names work fine. Use commas to separate multiple inputs or outputs.
|
|
36
|
+
|
|
37
|
+
The engine computes structural truth from the description — the tool outputs are raw mathematical findings. Translate them into clear, practical insights relevant to what the user is trying to achieve.
|
|
38
|
+
|
|
39
|
+
How to use these tools effectively: model the system first, then explore. The first tool call reveals the structure — but the real insights come from following up. A node labeled HUB that should be simple? Dig into it with between or impact. A surprising subsystem boundary? Extract it and analyze deeper. An unexpected dependency chain? Trace it. A proposed change? Evolve it and diff. The tools are designed to chain — each finding opens a question that another tool can answer. Don't stop at one call. Explore, tinker, compare, and let the math surface what no one expected.`;
|
|
31
40
|
const server = new McpServer({
|
|
32
41
|
name: "endiagram",
|
|
33
|
-
version: "0.
|
|
42
|
+
version: "0.2.0",
|
|
34
43
|
});
|
|
35
|
-
// ---
|
|
36
|
-
server.tool("
|
|
44
|
+
// --- analyze ---
|
|
45
|
+
server.tool("analyze", EN_INSTRUCTIONS + " This tool gives the system overview: shape, node roles, single points of failure, failure threshold, flow hotspots.", {
|
|
37
46
|
source: z.string().describe("EN source code describing the system"),
|
|
38
47
|
invariants: z
|
|
39
48
|
.string()
|
|
@@ -55,7 +64,7 @@ server.tool("analyze_system", "Structural signal. You describe the system, the t
|
|
|
55
64
|
};
|
|
56
65
|
});
|
|
57
66
|
// --- detail ---
|
|
58
|
-
server.tool("detail", "
|
|
67
|
+
server.tool("detail", "Concurrency, critical path, flow landmarks, resilience, dependency chains, dominator tree.", {
|
|
59
68
|
source: z.string().describe("EN source code describing the system"),
|
|
60
69
|
}, async ({ source }) => {
|
|
61
70
|
const result = await callApi("detail", { source });
|
|
@@ -65,7 +74,7 @@ server.tool("detail", "The depth layer. Run after analyze_system to get the full
|
|
|
65
74
|
};
|
|
66
75
|
});
|
|
67
76
|
// --- categorize ---
|
|
68
|
-
server.tool("categorize", "Auto-
|
|
77
|
+
server.tool("categorize", "Auto-discover subsystem boundaries from dependency structure.", {
|
|
69
78
|
source: z.string().describe("EN source code describing the system"),
|
|
70
79
|
}, async ({ source }) => {
|
|
71
80
|
const result = await callApi("categorize", { source });
|
|
@@ -75,7 +84,7 @@ server.tool("categorize", "Auto-organize a flat list into named groups. You give
|
|
|
75
84
|
};
|
|
76
85
|
});
|
|
77
86
|
// --- distance ---
|
|
78
|
-
server.tool("distance", "Structural
|
|
87
|
+
server.tool("distance", "Structural distance between two nodes with the path between them.", {
|
|
79
88
|
source: z.string().describe("EN source code describing the system"),
|
|
80
89
|
from: z.string().describe("Starting node name"),
|
|
81
90
|
to: z.string().describe("Target node name"),
|
|
@@ -87,7 +96,7 @@ server.tool("distance", "Structural ruler. Computes shortest path between any tw
|
|
|
87
96
|
};
|
|
88
97
|
});
|
|
89
98
|
// --- diff ---
|
|
90
|
-
server.tool("diff", "
|
|
99
|
+
server.tool("diff", "Compare two systems. What changed structurally.", {
|
|
91
100
|
source_a: z.string().describe("EN source code for the first system"),
|
|
92
101
|
source_b: z.string().describe("EN source code for the second system"),
|
|
93
102
|
}, async ({ source_a, source_b }) => {
|
|
@@ -98,7 +107,7 @@ server.tool("diff", "Structural diff between two systems. Computes both graphs i
|
|
|
98
107
|
};
|
|
99
108
|
});
|
|
100
109
|
// --- trace ---
|
|
101
|
-
server.tool("trace", "Follow
|
|
110
|
+
server.tool("trace", "Follow directed flow from A to B. Optional: check if defense nodes cover all paths.", {
|
|
102
111
|
source: z.string().describe("EN source code describing the system"),
|
|
103
112
|
from: z.string().describe("Starting node name"),
|
|
104
113
|
to: z.string().describe("Target node name"),
|
|
@@ -119,9 +128,9 @@ server.tool("trace", "Follow the flow -- data, materials, authority, money, risk
|
|
|
119
128
|
};
|
|
120
129
|
});
|
|
121
130
|
// --- between ---
|
|
122
|
-
server.tool("between", "
|
|
131
|
+
server.tool("between", "How much of the system flows through a specific node.", {
|
|
123
132
|
source: z.string().describe("EN source code describing the system"),
|
|
124
|
-
node: z.string().describe("Node
|
|
133
|
+
node: z.string().describe("Node name"),
|
|
125
134
|
}, async ({ source, node }) => {
|
|
126
135
|
const result = await callApi("between", { source, node });
|
|
127
136
|
return {
|
|
@@ -130,7 +139,7 @@ server.tool("between", "Quantify coupling. Computes betweenness centrality for a
|
|
|
130
139
|
};
|
|
131
140
|
});
|
|
132
141
|
// --- extract ---
|
|
133
|
-
server.tool("extract", "
|
|
142
|
+
server.tool("extract", "Extract a subsystem as standalone EN source. Feed back into other tools.", {
|
|
134
143
|
source: z.string().describe("EN source code describing the system"),
|
|
135
144
|
subsystem: z.string().describe("Name of the subsystem to extract"),
|
|
136
145
|
}, async ({ source, subsystem }) => {
|
|
@@ -141,9 +150,9 @@ server.tool("extract", "Fractal zoom. Extract a named subsystem as standalone EN
|
|
|
141
150
|
};
|
|
142
151
|
});
|
|
143
152
|
// --- impact ---
|
|
144
|
-
server.tool("impact", "
|
|
153
|
+
server.tool("impact", "What changes if a node is removed. Includes how far the effect propagates.", {
|
|
145
154
|
source: z.string().describe("EN source code describing the system"),
|
|
146
|
-
node: z.string().describe("Node to remove
|
|
155
|
+
node: z.string().describe("Node to remove"),
|
|
147
156
|
}, async ({ source, node }) => {
|
|
148
157
|
const result = await callApi("impact", { source, node });
|
|
149
158
|
return {
|
|
@@ -152,7 +161,7 @@ server.tool("impact", "Blast radius calculator. Remove a node and see what break
|
|
|
152
161
|
};
|
|
153
162
|
});
|
|
154
163
|
// --- evolve ---
|
|
155
|
-
server.tool("evolve", "Dry-run
|
|
164
|
+
server.tool("evolve", "Dry-run a structural change before making it.", {
|
|
156
165
|
source: z.string().describe("EN source code describing the current system"),
|
|
157
166
|
patch: z.string().describe("EN source code patch to apply"),
|
|
158
167
|
}, async ({ source, patch }) => {
|
|
@@ -163,7 +172,7 @@ server.tool("evolve", "Dry-run for architectural changes. Apply a patch to a sys
|
|
|
163
172
|
};
|
|
164
173
|
});
|
|
165
174
|
// --- compose ---
|
|
166
|
-
server.tool("compose", "Merge two
|
|
175
|
+
server.tool("compose", "Merge two systems into one by linking shared entities.", {
|
|
167
176
|
source_a: z.string().describe("EN source code for the first system"),
|
|
168
177
|
source_b: z.string().describe("EN source code for the second system"),
|
|
169
178
|
links: z
|
|
@@ -176,17 +185,27 @@ server.tool("compose", "Merge two EN graphs into one. Takes two separate system
|
|
|
176
185
|
isError: result.isError,
|
|
177
186
|
};
|
|
178
187
|
});
|
|
179
|
-
// ---
|
|
180
|
-
server.tool("
|
|
188
|
+
// --- conserve ---
|
|
189
|
+
server.tool("conserve", "Structural invariants, deadlock analysis, complexity, and resilience.", {
|
|
190
|
+
source: z.string().describe("EN source code describing the system"),
|
|
191
|
+
}, async ({ source }) => {
|
|
192
|
+
const result = await callApi("conserve", { source });
|
|
193
|
+
return {
|
|
194
|
+
content: [{ type: "text", text: result.text }],
|
|
195
|
+
isError: result.isError,
|
|
196
|
+
};
|
|
197
|
+
});
|
|
198
|
+
// --- render ---
|
|
199
|
+
server.tool("render", "SVG diagram. Only when user asks to visualize.", {
|
|
181
200
|
source: z.string().describe("EN source code describing the system"),
|
|
182
201
|
theme: z
|
|
183
202
|
.enum(["dark", "light"])
|
|
184
203
|
.optional()
|
|
185
|
-
.describe("Color theme
|
|
204
|
+
.describe("Color theme"),
|
|
186
205
|
quality: z
|
|
187
206
|
.enum(["small", "mid", "max"])
|
|
188
207
|
.optional()
|
|
189
|
-
.describe("Output quality
|
|
208
|
+
.describe("Output quality"),
|
|
190
209
|
}, async ({ source, theme, quality }) => {
|
|
191
210
|
const result = await callApi("render", { source, theme, quality });
|
|
192
211
|
return {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@endiagram/mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for EN Diagram — structural analysis
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MCP server for EN Diagram — deterministic structural analysis backed by named theorems",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"zod": "^3.23.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"
|
|
26
|
-
"
|
|
25
|
+
"@types/node": "^20.0.0",
|
|
26
|
+
"typescript": "^5.9.3"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|