@creately/rdm-mcp 0.1.0 → 0.2.1
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/package.json +5 -2
- package/src/index.ts +6 -2
- package/src/tools/rdm_guide.ts +76 -0
- package/src/tools/rdm_schema.ts +73 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creately/rdm-mcp",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "MCP server for RDM — parse, validate, render, and manipulate diagrams via AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
16
|
-
"@creately/rdm-core": "
|
|
16
|
+
"@creately/rdm-core": ">=0.3.0"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
17
20
|
},
|
|
18
21
|
"license": "MIT",
|
|
19
22
|
"repository": {
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RDM MCP Server
|
|
3
3
|
*
|
|
4
|
-
* Provides
|
|
4
|
+
* Provides 9 tools for agents to interact with RDM diagrams:
|
|
5
|
+
* rdm_guide — Complete generation guide with syntax and examples
|
|
5
6
|
* rdm_read — Full .rdm text (rich context)
|
|
6
7
|
* rdm_summary — Lightweight: node count, types, relationships
|
|
7
8
|
* rdm_write — Write/update .rdm file
|
|
@@ -33,8 +34,10 @@ import { rdmValidateTool, executeRdmValidate } from './tools/rdm_validate.js';
|
|
|
33
34
|
import { rdmSchemaTool, executeRdmSchema } from './tools/rdm_schema.js';
|
|
34
35
|
import { rdmFromCsvTool, executeRdmFromCsv } from './tools/rdm_from_csv.js';
|
|
35
36
|
import { rdmInitTool, executeRdmInit } from './tools/rdm_init.js';
|
|
37
|
+
import { rdmGuideTool, executeRdmGuide } from './tools/rdm_guide.js';
|
|
36
38
|
|
|
37
39
|
const ALL_TOOLS = [
|
|
40
|
+
rdmGuideTool,
|
|
38
41
|
rdmReadTool,
|
|
39
42
|
rdmSummaryTool,
|
|
40
43
|
rdmWriteTool,
|
|
@@ -46,6 +49,7 @@ const ALL_TOOLS = [
|
|
|
46
49
|
];
|
|
47
50
|
|
|
48
51
|
const TOOL_EXECUTORS: Record<string, (args: Record<string, unknown>) => Promise<unknown>> = {
|
|
52
|
+
rdm_guide: executeRdmGuide,
|
|
49
53
|
rdm_read: executeRdmRead,
|
|
50
54
|
rdm_summary: executeRdmSummary,
|
|
51
55
|
rdm_write: executeRdmWrite,
|
|
@@ -58,7 +62,7 @@ const TOOL_EXECUTORS: Record<string, (args: Record<string, unknown>) => Promise<
|
|
|
58
62
|
|
|
59
63
|
async function main() {
|
|
60
64
|
const server = new Server(
|
|
61
|
-
{ name: 'rdm-mcp', version: '0.
|
|
65
|
+
{ name: 'rdm-mcp', version: '0.2.0' },
|
|
62
66
|
{ capabilities: { tools: {} } }
|
|
63
67
|
);
|
|
64
68
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rdm_guide — Returns the RDM generation guide for agents.
|
|
3
|
+
*
|
|
4
|
+
* Provides the complete syntax guide, domain types, and examples
|
|
5
|
+
* so agents can generate valid RDM without needing a local CLAUDE.md.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { resolve, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
let cachedGuide: string | null = null;
|
|
13
|
+
|
|
14
|
+
function loadGuide(): string {
|
|
15
|
+
if (cachedGuide) return cachedGuide;
|
|
16
|
+
|
|
17
|
+
// Try to load CLAUDE.md from the repo root (3 levels up from tools/)
|
|
18
|
+
const toolDir = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const candidates = [
|
|
20
|
+
resolve(toolDir, '../../../../CLAUDE.md'),
|
|
21
|
+
resolve(toolDir, '../../../CLAUDE.md'),
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
for (const path of candidates) {
|
|
25
|
+
try {
|
|
26
|
+
cachedGuide = readFileSync(path, 'utf-8');
|
|
27
|
+
return cachedGuide;
|
|
28
|
+
} catch {
|
|
29
|
+
// continue
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Fallback inline guide
|
|
34
|
+
cachedGuide = `# RDM Generation Guide
|
|
35
|
+
|
|
36
|
+
RDM (Rich Diagram Markup) is a text-based format for diagrams.
|
|
37
|
+
|
|
38
|
+
## Supported Types
|
|
39
|
+
- genogram — Family trees with clinical data
|
|
40
|
+
- orgchart — Organizational hierarchies
|
|
41
|
+
- flowchart — Simple step-by-step flows
|
|
42
|
+
- process — BPMN workflows with events and gateways
|
|
43
|
+
- table — Grid diagrams (SWOT, kanban, RACI, BMC, etc.)
|
|
44
|
+
|
|
45
|
+
## Basic Structure
|
|
46
|
+
\`\`\`
|
|
47
|
+
---
|
|
48
|
+
type: <diagram-type>
|
|
49
|
+
title: "<Title>"
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
<block-keyword> <Name> {
|
|
53
|
+
<declarations>
|
|
54
|
+
}
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
Use rdm_schema tool to get detailed syntax for each domain type.
|
|
58
|
+
Use rdm_validate to check your generated files.
|
|
59
|
+
`;
|
|
60
|
+
return cachedGuide;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const rdmGuideTool = {
|
|
64
|
+
name: 'rdm_guide',
|
|
65
|
+
description:
|
|
66
|
+
'Get the complete RDM generation guide with syntax templates and examples for all diagram types. ' +
|
|
67
|
+
'Call this first when you need to generate RDM diagrams.',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object' as const,
|
|
70
|
+
properties: {},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export async function executeRdmGuide(_args: Record<string, unknown>): Promise<unknown> {
|
|
75
|
+
return { guide: loadGuide() };
|
|
76
|
+
}
|
package/src/tools/rdm_schema.ts
CHANGED
|
@@ -80,12 +80,14 @@ const SCHEMAS: Record<string, DomainSchema> = {
|
|
|
80
80
|
},
|
|
81
81
|
process: {
|
|
82
82
|
domain: 'process',
|
|
83
|
-
description: 'Business process and
|
|
83
|
+
description: 'Business process, workflow, and BPMN diagrams with tasks, gateways, and flows.',
|
|
84
84
|
nodeTypes: {
|
|
85
85
|
task: {
|
|
86
86
|
fields: [
|
|
87
|
-
{ name: 'type', type: 'enum', values: ['task', 'start', 'end', '
|
|
87
|
+
{ name: 'type', type: 'enum', values: ['task', 'start', 'end', 'gateway', 'start-event', 'end-event', 'intermediate-event', 'timer-event', 'message-event', 'exclusive-gateway', 'parallel-gateway', 'inclusive-gateway', 'user-task', 'service-task', 'script-task', 'send-task', 'receive-task', 'sub-process', 'data-object', 'data-store'], required: true },
|
|
88
|
+
{ name: 'label', type: 'string', description: 'Display label for the node' },
|
|
88
89
|
{ name: 'assignee', type: 'string', description: 'Role or person responsible' },
|
|
90
|
+
{ name: 'trigger', type: 'enum', values: ['message', 'timer', 'error', 'signal', 'conditional', 'terminate'], description: 'Event trigger type (for events)' },
|
|
89
91
|
{ name: 'duration', type: 'number', description: 'Duration in days' },
|
|
90
92
|
{ name: 'sla', type: 'number', description: 'SLA deadline in days' },
|
|
91
93
|
{ name: 'priority', type: 'enum', values: ['low', 'medium', 'high', 'critical'] },
|
|
@@ -94,17 +96,81 @@ const SCHEMAS: Record<string, DomainSchema> = {
|
|
|
94
96
|
},
|
|
95
97
|
relationships: [
|
|
96
98
|
{ syntax: 'task1 -> task2', description: 'Sequential flow' },
|
|
97
|
-
{ syntax: 'task1 -> task2
|
|
99
|
+
{ syntax: 'task1 -> task2 { label: "Yes" }', description: 'Labeled flow (for gateways)' },
|
|
100
|
+
{ syntax: 'task1 -> task2 { type: "message" }', description: 'Message flow (cross-pool)' },
|
|
98
101
|
],
|
|
99
|
-
structure: 'process Name {\n
|
|
100
|
-
example: '---\ntype: process\ntitle: "
|
|
102
|
+
structure: 'process Name {\n node_id { type: "node-type", label: "Display" }\n source -> target\n source -> target { label: "Condition" }\n}',
|
|
103
|
+
example: '---\ntype: process\ntitle: "Payment"\n---\n\nprocess Payment {\n start { type: "start-event", trigger: "message" }\n validate { type: "service-task", label: "Validate" }\n check { type: "exclusive-gateway", label: "Valid?" }\n pay { type: "service-task", label: "Process" }\n done { type: "end-event" }\n\n start -> validate\n validate -> check\n check -> pay { label: "Yes" }\n pay -> done\n}',
|
|
104
|
+
},
|
|
105
|
+
flowchart: {
|
|
106
|
+
domain: 'flowchart',
|
|
107
|
+
description: 'Simple flowchart diagrams with steps, decisions, and flows.',
|
|
108
|
+
nodeTypes: {
|
|
109
|
+
step: {
|
|
110
|
+
fields: [
|
|
111
|
+
{ name: 'type', type: 'enum', values: ['process', 'decision', 'start', 'end', 'subprocess', 'document', 'database'] },
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
relationships: [
|
|
116
|
+
{ syntax: 'flow source -> target', description: 'Sequential flow' },
|
|
117
|
+
{ syntax: 'flow source -> target { label: "Yes" }', description: 'Labeled flow' },
|
|
118
|
+
],
|
|
119
|
+
structure: 'flowchart Name {\n start begin "Start"\n step id "Label" { type: process }\n end done "End"\n flow begin -> id\n flow id -> done\n}',
|
|
120
|
+
example: '---\ntype: flowchart\ntitle: "Approval"\n---\n\nflowchart Approval {\n start begin "Start"\n step submit "Submit Request" { type: process }\n step check "Approved?" { type: decision }\n end done "Done"\n\n flow begin -> submit\n flow submit -> check\n flow check -> done { label: "Yes" }\n}',
|
|
121
|
+
},
|
|
122
|
+
table: {
|
|
123
|
+
domain: 'table',
|
|
124
|
+
description: 'Grid-based diagrams: SWOT, kanban, retro, RACI, business model canvas, comparison matrices, and custom tables.',
|
|
125
|
+
nodeTypes: {
|
|
126
|
+
sticky: { fields: [
|
|
127
|
+
{ name: 'cell', type: 'string', description: 'Cell label to place this item in', required: true },
|
|
128
|
+
{ name: 'assignee', type: 'string' },
|
|
129
|
+
{ name: 'color', type: 'string' },
|
|
130
|
+
] },
|
|
131
|
+
card: { fields: [
|
|
132
|
+
{ name: 'cell', type: 'string', description: 'Cell label to place this item in', required: true },
|
|
133
|
+
{ name: 'assignee', type: 'string' },
|
|
134
|
+
{ name: 'points', type: 'number' },
|
|
135
|
+
{ name: 'priority', type: 'enum', values: ['low', 'medium', 'high', 'critical'] },
|
|
136
|
+
] },
|
|
137
|
+
text: { fields: [
|
|
138
|
+
{ name: 'cell', type: 'string', required: true },
|
|
139
|
+
] },
|
|
140
|
+
},
|
|
141
|
+
relationships: [],
|
|
142
|
+
structure: '@type table\n@title "Title"\n\ntable <schema> "Display Name" { layout: stack }\n\nsticky id "Content" { cell: "Cell Name" }',
|
|
143
|
+
example: '@type table\n@title "Product SWOT"\n\ntable swot "SWOT Analysis" { layout: stack }\n\nsticky s1 "Strong brand" { cell: "Strengths" }\nsticky w1 "Limited budget" { cell: "Weaknesses" }\nsticky o1 "AI trend" { cell: "Opportunities" }\nsticky t1 "Regulations" { cell: "Threats" }',
|
|
144
|
+
},
|
|
145
|
+
'change-summary': {
|
|
146
|
+
domain: 'change-summary',
|
|
147
|
+
description: 'Architecture change impact diagrams showing modules, decisions, and notes.',
|
|
148
|
+
nodeTypes: {
|
|
149
|
+
module: { fields: [
|
|
150
|
+
{ name: 'status', type: 'enum', values: ['new', 'modified', 'affected', 'deleted'] },
|
|
151
|
+
{ name: 'files', type: 'array', description: 'List of affected file paths' },
|
|
152
|
+
{ name: 'description', type: 'string' },
|
|
153
|
+
] },
|
|
154
|
+
note: { fields: [
|
|
155
|
+
{ name: 'description', type: 'string' },
|
|
156
|
+
] },
|
|
157
|
+
decision: { fields: [
|
|
158
|
+
{ name: 'risk', type: 'enum', values: ['high', 'medium', 'low'] },
|
|
159
|
+
{ name: 'description', type: 'string' },
|
|
160
|
+
] },
|
|
161
|
+
},
|
|
162
|
+
relationships: [
|
|
163
|
+
{ syntax: 'module1 -> module2 : dependency', description: 'Module dependency' },
|
|
164
|
+
],
|
|
165
|
+
structure: 'change-summary Name {\n module id "Name" { status: modified, files: ["path"] }\n note id "Text"\n decision id "Text" { risk: medium }\n id1 -> id2 : dependency\n}',
|
|
166
|
+
example: '---\ntype: change-summary\ntitle: "Auth Refactor"\n---\n\nchange-summary AuthRefactor {\n module auth "Auth Service" { status: modified, files: ["src/auth/service.ts"] }\n module users "User Model" { status: affected }\n decision d1 "Switch to JWT" { risk: medium }\n auth -> users : dependency\n}',
|
|
101
167
|
},
|
|
102
168
|
};
|
|
103
169
|
|
|
104
170
|
export const rdmSchemaTool = {
|
|
105
171
|
name: 'rdm_schema',
|
|
106
172
|
description:
|
|
107
|
-
'Get the RDM schema for a diagram domain
|
|
173
|
+
'Get the RDM schema for a diagram domain. ' +
|
|
108
174
|
'Returns valid node types, fields, relationships, and syntax examples. ' +
|
|
109
175
|
'Use this before generating RDM to ensure correct syntax.',
|
|
110
176
|
inputSchema: {
|
|
@@ -112,7 +178,7 @@ export const rdmSchemaTool = {
|
|
|
112
178
|
properties: {
|
|
113
179
|
domain: {
|
|
114
180
|
type: 'string',
|
|
115
|
-
enum: ['genogram', 'orgchart', 'process'],
|
|
181
|
+
enum: ['genogram', 'orgchart', 'process', 'flowchart', 'table', 'change-summary'],
|
|
116
182
|
description: 'The diagram domain to get schema for',
|
|
117
183
|
},
|
|
118
184
|
},
|