@markdy/mcp-server 0.8.25

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hoang Yell (https://hoangyell.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @markdy/mcp-server
2
+
3
+ Official **Model Context Protocol (MCP)** server for Markdy — the animated diagram-as-code DSL.
4
+
5
+ Equip Claude Desktop, Cursor, Google Antigravity, and autonomous AI agents with tools to parse, validate, transpile, explain, and craft animated Markdy architecture diagrams.
6
+
7
+ ---
8
+
9
+ ## 🛠️ Provided Tools
10
+
11
+ 1. `validate_markdy_code`
12
+ - Validates syntax and executes Well-Architected governance rules (layer boundaries, cycle detection, gateway checks).
13
+ - Generates structured diagnostic hints and AI repair prompts.
14
+
15
+ 2. `transpile_to_markdy`
16
+ - Converts Mermaid, Docker Compose, Kubernetes manifests, or Terraform state into animated MarkdyScript scenes.
17
+
18
+ 3. `explain_architecture`
19
+ - Parses a MarkdyScript AST to output structural topology summaries, component role counts, and governance health.
20
+
21
+ 4. `generate_markdy_prompt`
22
+ - Generates optimal system prompt constraints and instructions for LLMs.
23
+
24
+ ---
25
+
26
+ ## 🚀 Configuration
27
+
28
+ ### Claude Desktop (`claude_desktop_config.json`)
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "markdy": {
34
+ "command": "npx",
35
+ "args": ["-y", "@markdy/mcp-server"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### Cursor (`.cursor/mcp.json`)
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "markdy": {
47
+ "command": "npx",
48
+ "args": ["-y", "@markdy/mcp-server"]
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ---
55
+
56
+ ## License
57
+
58
+ MIT © [Hoang Yell](https://hoangyell.com)
@@ -0,0 +1,28 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+
3
+ /**
4
+ * packages/mcp-server/src/tools.ts
5
+ * MCP Tool definitions and execution handlers for Markdy.
6
+ */
7
+ interface ToolResult {
8
+ [x: string]: unknown;
9
+ content: Array<{
10
+ type: "text";
11
+ text: string;
12
+ }>;
13
+ isError?: boolean;
14
+ }
15
+ declare function handleValidateMarkdy(code: string, checkArchitecture?: boolean): ToolResult;
16
+ declare function handleTranspileToMarkdy(source: string, format: "mermaid" | "docker-compose" | "k8s" | "terraform", title?: string): ToolResult;
17
+ declare function handleExplainArchitecture(code: string): ToolResult;
18
+ declare function handleGenerateMarkdyPrompt(userGoal: string): ToolResult;
19
+
20
+ /**
21
+ * packages/mcp-server/src/index.ts
22
+ * MCP Server for Markdy Diagram Engine.
23
+ */
24
+
25
+ declare function createMarkdyMcpServer(): Server;
26
+ declare function startMcpServer(): Promise<void>;
27
+
28
+ export { createMarkdyMcpServer, handleExplainArchitecture, handleGenerateMarkdyPrompt, handleTranspileToMarkdy, handleValidateMarkdy, startMcpServer };
package/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import {
7
+ CallToolRequestSchema,
8
+ ListToolsRequestSchema
9
+ } from "@modelcontextprotocol/sdk/types.js";
10
+
11
+ // src/tools.ts
12
+ import {
13
+ parse,
14
+ validateArchitecture,
15
+ analyzeAndBuildRepairPrompt
16
+ } from "@markdy/core";
17
+ import {
18
+ transpileMermaidToMarkdy,
19
+ transpileDockerComposeToMarkdy,
20
+ transpileKubernetesManifestsToMarkdy,
21
+ transpileTerraformStateToMarkdy
22
+ } from "@markdy/compat";
23
+ function handleValidateMarkdy(code, checkArchitecture = true) {
24
+ try {
25
+ const ast = parse(code);
26
+ const diagnostics = ast.diagnostics ?? [];
27
+ const archViolations = checkArchitecture ? validateArchitecture(ast) : [];
28
+ const lines = [];
29
+ lines.push(`\u2705 Markdy Syntax Valid: ${Object.keys(ast.nodes).length} nodes, ${ast.edges.length} static edges, ${ast.beats.length} beats.`);
30
+ if (diagnostics.length > 0) {
31
+ lines.push("\n\u26A0\uFE0F Diagnostics & Suggestions:");
32
+ for (const d of diagnostics) {
33
+ lines.push(`- line ${d.line}: [${d.severity}] ${d.message}`);
34
+ }
35
+ }
36
+ if (archViolations.length > 0) {
37
+ lines.push("\n\u{1F6E1}\uFE0F Architecture Rule Violations:");
38
+ for (const v of archViolations) {
39
+ lines.push(`- [${v.severity.toUpperCase()}] ${v.ruleName} (line ${v.line ?? 1}): ${v.message}`);
40
+ }
41
+ }
42
+ return {
43
+ content: [{ type: "text", text: lines.join("\n") }]
44
+ };
45
+ } catch (error) {
46
+ const repairPrompt = analyzeAndBuildRepairPrompt(code);
47
+ return {
48
+ isError: true,
49
+ content: [
50
+ {
51
+ type: "text",
52
+ text: `\u274C Parse Error: ${error.message}
53
+
54
+ Suggested AI Healing Prompt:
55
+ ${repairPrompt}`
56
+ }
57
+ ]
58
+ };
59
+ }
60
+ }
61
+ function handleTranspileToMarkdy(source, format, title = "Imported Scene") {
62
+ try {
63
+ let markdyCode = "";
64
+ switch (format) {
65
+ case "mermaid":
66
+ markdyCode = transpileMermaidToMarkdy(source, title).code;
67
+ break;
68
+ case "docker-compose":
69
+ markdyCode = transpileDockerComposeToMarkdy(source, title);
70
+ break;
71
+ case "k8s":
72
+ markdyCode = transpileKubernetesManifestsToMarkdy(source, title);
73
+ break;
74
+ case "terraform":
75
+ markdyCode = transpileTerraformStateToMarkdy(source, title);
76
+ break;
77
+ default:
78
+ throw new Error(`Unsupported ingestion format: ${format}`);
79
+ }
80
+ parse(markdyCode);
81
+ return {
82
+ content: [
83
+ {
84
+ type: "text",
85
+ text: markdyCode
86
+ }
87
+ ]
88
+ };
89
+ } catch (error) {
90
+ return {
91
+ isError: true,
92
+ content: [{ type: "text", text: `Transpilation failed: ${error.message}` }]
93
+ };
94
+ }
95
+ }
96
+ function handleExplainArchitecture(code) {
97
+ try {
98
+ const ast = parse(code);
99
+ const nodeCount = Object.keys(ast.nodes).length;
100
+ const edgeCount = ast.edges.length;
101
+ const groupCount = Object.keys(ast.groups).length;
102
+ const beatsCount = ast.beats.length;
103
+ const rolesSummary = /* @__PURE__ */ new Map();
104
+ for (const n of Object.values(ast.nodes)) {
105
+ rolesSummary.set(n.kind, (rolesSummary.get(n.kind) ?? 0) + 1);
106
+ }
107
+ const roleBreakdown = Array.from(rolesSummary.entries()).map(([k, count]) => ` - ${k}: ${count}`).join("\n");
108
+ const violations = validateArchitecture(ast);
109
+ const explanation = [
110
+ `### Architecture Overview: ${ast.meta.title || "Untitled Diagram"}`,
111
+ `- **Layout:** ${ast.meta.direction || "LR"}`,
112
+ `- **Theme:** ${ast.meta.theme || "paper"}`,
113
+ `- **Components:** ${nodeCount} nodes across ${groupCount} groups`,
114
+ `- **Interactions:** ${edgeCount} static connections, ${beatsCount} dynamic beats`,
115
+ "",
116
+ `#### Component Kinds:`,
117
+ roleBreakdown,
118
+ "",
119
+ `#### Governance & Well-Architected Health:`,
120
+ violations.length === 0 ? "\u2705 No architectural violations detected across Well-Architected rule presets." : `\u26A0\uFE0F Detected ${violations.length} governance issue(s):
121
+ ` + violations.map((v) => `- [${v.ruleName}] ${v.message}`).join("\n")
122
+ ].join("\n");
123
+ return {
124
+ content: [{ type: "text", text: explanation }]
125
+ };
126
+ } catch (error) {
127
+ return {
128
+ isError: true,
129
+ content: [{ type: "text", text: `Explain failed: ${error.message}` }]
130
+ };
131
+ }
132
+ }
133
+ function handleGenerateMarkdyPrompt(userGoal) {
134
+ const prompt = [
135
+ `You are an expert system architecture designer specializing in MarkdyScript DSL.`,
136
+ `Goal: ${userGoal}`,
137
+ ``,
138
+ `### Instructions:`,
139
+ `1. Use MarkdyScript 0.8+ syntax. Start with: \`scene "<Title>" theme=paper layout=LR\``,
140
+ `2. Define nodes using semantic types (e.g. \`browser client\`, \`gateway api_gw\`, \`service auth_svc\`, \`database pg_db\`, \`cache redis\`, \`queue kafka\`).`,
141
+ `3. Organize components in \`group <id> "<Label>": <members...>\` boundaries.`,
142
+ `4. Define animated traffic steps in \`beat <id> "<Description>":\``,
143
+ `5. Animate flows with \`show $nodes\`, \`client -> api_gw "request"\`, and \`api_gw -> auth_svc "verify"\`.`,
144
+ `6. Keep syntax clean and output ONLY valid MarkdyScript.`
145
+ ].join("\n");
146
+ return {
147
+ content: [{ type: "text", text: prompt }]
148
+ };
149
+ }
150
+
151
+ // src/index.ts
152
+ function createMarkdyMcpServer() {
153
+ const server = new Server(
154
+ {
155
+ name: "markdy-mcp-server",
156
+ version: "0.8.20"
157
+ },
158
+ {
159
+ capabilities: {
160
+ tools: {}
161
+ }
162
+ }
163
+ );
164
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
165
+ return {
166
+ tools: [
167
+ {
168
+ name: "validate_markdy_code",
169
+ description: "Validates MarkdyScript syntax, detects architectural rule violations, and outputs diagnostics and healing suggestions.",
170
+ inputSchema: {
171
+ type: "object",
172
+ properties: {
173
+ code: { type: "string", description: "The MarkdyScript diagram code to validate." },
174
+ checkArchitecture: { type: "boolean", description: "Whether to run Well-Architected governance rule checks." }
175
+ },
176
+ required: ["code"]
177
+ }
178
+ },
179
+ {
180
+ name: "transpile_to_markdy",
181
+ description: "Converts external infrastructure or diagram code (Mermaid, Docker Compose, Kubernetes manifests, or Terraform state) into animated MarkdyScript scenes.",
182
+ inputSchema: {
183
+ type: "object",
184
+ properties: {
185
+ source: { type: "string", description: "The source code or content to transpile." },
186
+ format: {
187
+ type: "string",
188
+ enum: ["mermaid", "docker-compose", "k8s", "terraform"],
189
+ description: "The source format."
190
+ },
191
+ title: { type: "string", description: "Optional title for the resulting scene." }
192
+ },
193
+ required: ["source", "format"]
194
+ }
195
+ },
196
+ {
197
+ name: "explain_architecture",
198
+ description: "Analyzes a MarkdyScript AST and generates a structured summary of components, topology, and governance health.",
199
+ inputSchema: {
200
+ type: "object",
201
+ properties: {
202
+ code: { type: "string", description: "The MarkdyScript code to analyze." }
203
+ },
204
+ required: ["code"]
205
+ }
206
+ },
207
+ {
208
+ name: "generate_markdy_prompt",
209
+ description: "Generates optimal LLM system prompts and grammar constraints for building high-quality Markdy architecture animations.",
210
+ inputSchema: {
211
+ type: "object",
212
+ properties: {
213
+ userGoal: { type: "string", description: "The architecture or flow description the user wants to visualize." }
214
+ },
215
+ required: ["userGoal"]
216
+ }
217
+ }
218
+ ]
219
+ };
220
+ });
221
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
222
+ const { name, arguments: args } = request.params;
223
+ const safeArgs = args || {};
224
+ switch (name) {
225
+ case "validate_markdy_code":
226
+ return handleValidateMarkdy(
227
+ String(safeArgs.code ?? ""),
228
+ safeArgs.checkArchitecture !== false
229
+ );
230
+ case "transpile_to_markdy":
231
+ return handleTranspileToMarkdy(
232
+ String(safeArgs.source ?? ""),
233
+ safeArgs.format,
234
+ safeArgs.title ? String(safeArgs.title) : void 0
235
+ );
236
+ case "explain_architecture":
237
+ return handleExplainArchitecture(String(safeArgs.code ?? ""));
238
+ case "generate_markdy_prompt":
239
+ return handleGenerateMarkdyPrompt(String(safeArgs.userGoal ?? ""));
240
+ default:
241
+ throw new Error(`Unknown tool: ${name}`);
242
+ }
243
+ });
244
+ return server;
245
+ }
246
+ async function startMcpServer() {
247
+ const server = createMarkdyMcpServer();
248
+ const transport = new StdioServerTransport();
249
+ await server.connect(transport);
250
+ }
251
+ if (process.argv[1] && process.argv[1].endsWith("index.js")) {
252
+ startMcpServer().catch((err) => {
253
+ console.error("Fatal MCP Server Error:", err);
254
+ process.exit(1);
255
+ });
256
+ }
257
+ export {
258
+ createMarkdyMcpServer,
259
+ handleExplainArchitecture,
260
+ handleGenerateMarkdyPrompt,
261
+ handleTranspileToMarkdy,
262
+ handleValidateMarkdy,
263
+ startMcpServer
264
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@markdy/mcp-server",
3
+ "version": "0.8.25",
4
+ "description": "Model Context Protocol server for Markdy diagram validation, transpilation, and generation.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "markdy-mcp": "./dist/index.js"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.6.1",
19
+ "@markdy/compat": "0.8.25",
20
+ "@markdy/core": "0.8.25"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^25.9.5",
24
+ "tsup": "^8.5.1",
25
+ "typescript": "^5.9.3",
26
+ "vitest": "^4.1.7"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup",
30
+ "test": "vitest run",
31
+ "typecheck": "tsc --noEmit"
32
+ }
33
+ }