@rolexjs/mcp-server 0.6.0 → 0.7.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/dist/index.js +81 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -21,6 +21,12 @@ import {
|
|
|
21
21
|
DESC_FINISH,
|
|
22
22
|
renderFeatures,
|
|
23
23
|
renderFeature,
|
|
24
|
+
renderStatusBar,
|
|
25
|
+
renderError,
|
|
26
|
+
next,
|
|
27
|
+
NEXT,
|
|
28
|
+
nextHire,
|
|
29
|
+
nextFinish,
|
|
24
30
|
bootstrap
|
|
25
31
|
} from "rolexjs";
|
|
26
32
|
import { LocalPlatform } from "@rolexjs/local-platform";
|
|
@@ -32,6 +38,7 @@ var platform = new LocalPlatform(rolexDir);
|
|
|
32
38
|
bootstrap(platform);
|
|
33
39
|
var rolex = new Rolex(platform);
|
|
34
40
|
var currentRole = null;
|
|
41
|
+
var currentRoleName = "";
|
|
35
42
|
var server = new FastMCP({
|
|
36
43
|
name: "Rolex MCP Server",
|
|
37
44
|
version: "0.1.0",
|
|
@@ -43,6 +50,15 @@ function requireRole() {
|
|
|
43
50
|
}
|
|
44
51
|
return currentRole;
|
|
45
52
|
}
|
|
53
|
+
function safeTool(toolName, fn) {
|
|
54
|
+
return async (args) => {
|
|
55
|
+
try {
|
|
56
|
+
return await fn(args);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new Error(renderError(toolName, error));
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
46
62
|
server.addTool({
|
|
47
63
|
name: "society",
|
|
48
64
|
description: DESC_SOCIETY,
|
|
@@ -54,17 +70,17 @@ server.addTool({
|
|
|
54
70
|
type: z.enum(["knowledge", "experience", "voice"]).optional().describe("Growth dimension for teach operation"),
|
|
55
71
|
dimensionName: z.string().optional().describe("Name for the knowledge being taught (e.g. 'distributed-systems')")
|
|
56
72
|
}),
|
|
57
|
-
execute: async ({ operation, name, source, roleId, type, dimensionName }) => {
|
|
73
|
+
execute: safeTool("society", async ({ operation, name, source, roleId, type, dimensionName }) => {
|
|
58
74
|
switch (operation) {
|
|
59
75
|
case "born": {
|
|
60
76
|
if (!name || !source) throw new Error("born requires: name, source");
|
|
61
77
|
const feature = rolex.born(name, source);
|
|
62
|
-
return `Role born: ${feature.name}
|
|
78
|
+
return next(`Role born: ${feature.name}`, NEXT.born);
|
|
63
79
|
}
|
|
64
80
|
case "found": {
|
|
65
81
|
if (!name) throw new Error("found requires: name");
|
|
66
82
|
rolex.found(name);
|
|
67
|
-
return `Organization founded: ${name}
|
|
83
|
+
return next(`Organization founded: ${name}`, NEXT.found);
|
|
68
84
|
}
|
|
69
85
|
case "directory": {
|
|
70
86
|
const dir = rolex.directory();
|
|
@@ -77,7 +93,15 @@ server.addTool({
|
|
|
77
93
|
lines.push(` - ${role.name} (team: ${role.team})`);
|
|
78
94
|
}
|
|
79
95
|
}
|
|
80
|
-
|
|
96
|
+
const unaffiliated = dir.roles.filter((r) => !r.team);
|
|
97
|
+
if (unaffiliated.length > 0) {
|
|
98
|
+
lines.push("");
|
|
99
|
+
lines.push("Unaffiliated:");
|
|
100
|
+
for (const role of unaffiliated) {
|
|
101
|
+
lines.push(` - ${role.name}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return lines.join("\n") || "No roles or organizations found.";
|
|
81
105
|
}
|
|
82
106
|
case "find": {
|
|
83
107
|
if (!name) throw new Error("find requires: name");
|
|
@@ -93,12 +117,12 @@ server.addTool({
|
|
|
93
117
|
if (!roleId || !type || !dimensionName || !source)
|
|
94
118
|
throw new Error("teach requires: roleId, type, dimensionName, source");
|
|
95
119
|
const feature = rolex.teach(roleId, type, dimensionName, source);
|
|
96
|
-
return `Taught ${type}: ${feature.name}
|
|
120
|
+
return next(`Taught ${type}: ${feature.name}`, NEXT.teach);
|
|
97
121
|
}
|
|
98
122
|
default:
|
|
99
123
|
throw new Error(`Unknown society operation: ${operation}`);
|
|
100
124
|
}
|
|
101
|
-
}
|
|
125
|
+
})
|
|
102
126
|
});
|
|
103
127
|
server.addTool({
|
|
104
128
|
name: "organization",
|
|
@@ -107,22 +131,22 @@ server.addTool({
|
|
|
107
131
|
operation: z.enum(["hire", "fire"]).describe("The organization operation to perform"),
|
|
108
132
|
name: z.string().describe("Role name to hire or fire")
|
|
109
133
|
}),
|
|
110
|
-
execute: async ({ operation, name }) => {
|
|
134
|
+
execute: safeTool("organization", async ({ operation, name }) => {
|
|
111
135
|
const dir = rolex.directory();
|
|
112
136
|
const org = rolex.find(dir.organizations[0].name);
|
|
113
137
|
switch (operation) {
|
|
114
138
|
case "hire": {
|
|
115
139
|
org.hire(name);
|
|
116
|
-
return `Role hired: ${name}
|
|
140
|
+
return next(`Role hired: ${name}`, nextHire(name));
|
|
117
141
|
}
|
|
118
142
|
case "fire": {
|
|
119
143
|
org.fire(name);
|
|
120
|
-
return `Role fired: ${name}
|
|
144
|
+
return next(`Role fired: ${name}`, NEXT.fire);
|
|
121
145
|
}
|
|
122
146
|
default:
|
|
123
147
|
throw new Error(`Unknown organization operation: ${operation}`);
|
|
124
148
|
}
|
|
125
|
-
}
|
|
149
|
+
})
|
|
126
150
|
});
|
|
127
151
|
server.addTool({
|
|
128
152
|
name: "identity",
|
|
@@ -130,11 +154,16 @@ server.addTool({
|
|
|
130
154
|
parameters: z.object({
|
|
131
155
|
roleId: z.string().describe("Role name (e.g. 'sean')")
|
|
132
156
|
}),
|
|
133
|
-
execute: async ({ roleId }) => {
|
|
157
|
+
execute: safeTool("identity", async ({ roleId }) => {
|
|
134
158
|
currentRole = rolex.role(roleId);
|
|
159
|
+
currentRoleName = roleId;
|
|
135
160
|
const features = currentRole.identity();
|
|
136
|
-
|
|
137
|
-
|
|
161
|
+
const { current } = currentRole.focus();
|
|
162
|
+
const statusBar = renderStatusBar(roleId, current);
|
|
163
|
+
return `${statusBar}
|
|
164
|
+
|
|
165
|
+
${renderFeatures(features)}`;
|
|
166
|
+
})
|
|
138
167
|
});
|
|
139
168
|
server.addTool({
|
|
140
169
|
name: "growup",
|
|
@@ -146,11 +175,11 @@ server.addTool({
|
|
|
146
175
|
name: z.string().describe("Name for this growth (used as filename, e.g. 'distributed-systems')"),
|
|
147
176
|
source: z.string().describe("Gherkin feature source text")
|
|
148
177
|
}),
|
|
149
|
-
execute: async ({ type, name, source }) => {
|
|
178
|
+
execute: safeTool("growup", async ({ type, name, source }) => {
|
|
150
179
|
const role = requireRole();
|
|
151
180
|
const feature = role.growup(type, name, source);
|
|
152
|
-
return `Growth added (${type}): ${feature.name}
|
|
153
|
-
}
|
|
181
|
+
return next(`Growth added (${type}): ${feature.name}`, NEXT.growup);
|
|
182
|
+
})
|
|
154
183
|
});
|
|
155
184
|
server.addTool({
|
|
156
185
|
name: "focus",
|
|
@@ -158,11 +187,15 @@ server.addTool({
|
|
|
158
187
|
parameters: z.object({
|
|
159
188
|
name: z.string().optional().describe("Optional goal name to switch focus to")
|
|
160
189
|
}),
|
|
161
|
-
execute: async ({ name }) => {
|
|
190
|
+
execute: safeTool("focus", async ({ name }) => {
|
|
162
191
|
const role = requireRole();
|
|
163
192
|
const { current, otherGoals } = role.focus(name);
|
|
164
|
-
|
|
165
|
-
|
|
193
|
+
const statusBar = renderStatusBar(currentRoleName, current);
|
|
194
|
+
if (!current && otherGoals.length === 0)
|
|
195
|
+
return `${statusBar}
|
|
196
|
+
|
|
197
|
+
No active goal. Use want() to set a new goal.`;
|
|
198
|
+
const parts = [statusBar];
|
|
166
199
|
if (current) {
|
|
167
200
|
parts.push(renderFeature(current));
|
|
168
201
|
if (current.plan) {
|
|
@@ -179,7 +212,7 @@ server.addTool({
|
|
|
179
212
|
}
|
|
180
213
|
}
|
|
181
214
|
return parts.join("\n\n");
|
|
182
|
-
}
|
|
215
|
+
})
|
|
183
216
|
});
|
|
184
217
|
server.addTool({
|
|
185
218
|
name: "want",
|
|
@@ -189,11 +222,11 @@ server.addTool({
|
|
|
189
222
|
source: z.string().describe("Gherkin feature source text for the goal"),
|
|
190
223
|
testable: z.boolean().optional().default(false).describe("Whether this goal's scenarios should become persistent automated verification")
|
|
191
224
|
}),
|
|
192
|
-
execute: async ({ name, source, testable }) => {
|
|
225
|
+
execute: safeTool("want", async ({ name, source, testable }) => {
|
|
193
226
|
const role = requireRole();
|
|
194
227
|
const goal = role.want(name, source, testable);
|
|
195
|
-
return `Goal created: ${goal.name}
|
|
196
|
-
}
|
|
228
|
+
return next(`Goal created: ${goal.name}`, NEXT.want);
|
|
229
|
+
})
|
|
197
230
|
});
|
|
198
231
|
server.addTool({
|
|
199
232
|
name: "plan",
|
|
@@ -201,11 +234,11 @@ server.addTool({
|
|
|
201
234
|
parameters: z.object({
|
|
202
235
|
source: z.string().describe("Gherkin feature source text for the plan")
|
|
203
236
|
}),
|
|
204
|
-
execute: async ({ source }) => {
|
|
237
|
+
execute: safeTool("plan", async ({ source }) => {
|
|
205
238
|
const role = requireRole();
|
|
206
239
|
const p = role.plan(source);
|
|
207
|
-
return `Plan created: ${p.name}
|
|
208
|
-
}
|
|
240
|
+
return next(`Plan created: ${p.name}`, NEXT.plan);
|
|
241
|
+
})
|
|
209
242
|
});
|
|
210
243
|
server.addTool({
|
|
211
244
|
name: "todo",
|
|
@@ -215,11 +248,11 @@ server.addTool({
|
|
|
215
248
|
source: z.string().describe("Gherkin feature source text for the task"),
|
|
216
249
|
testable: z.boolean().optional().default(false).describe("Whether this task's scenarios should become unit or integration tests")
|
|
217
250
|
}),
|
|
218
|
-
execute: async ({ name, source, testable }) => {
|
|
251
|
+
execute: safeTool("todo", async ({ name, source, testable }) => {
|
|
219
252
|
const role = requireRole();
|
|
220
253
|
const task = role.todo(name, source, testable);
|
|
221
|
-
return `Task created: ${task.name}
|
|
222
|
-
}
|
|
254
|
+
return next(`Task created: ${task.name}`, NEXT.todo);
|
|
255
|
+
})
|
|
223
256
|
});
|
|
224
257
|
server.addTool({
|
|
225
258
|
name: "achieve",
|
|
@@ -229,11 +262,12 @@ server.addTool({
|
|
|
229
262
|
"Optional Gherkin feature source capturing what was learned \u2014 auto-saved as experience growup"
|
|
230
263
|
)
|
|
231
264
|
}),
|
|
232
|
-
execute: async ({ experience }) => {
|
|
265
|
+
execute: safeTool("achieve", async ({ experience }) => {
|
|
233
266
|
const role = requireRole();
|
|
234
267
|
role.achieve(experience);
|
|
235
|
-
|
|
236
|
-
|
|
268
|
+
const msg = experience ? "Goal achieved. Experience captured." : "Goal achieved.";
|
|
269
|
+
return next(msg, NEXT.achieve);
|
|
270
|
+
})
|
|
237
271
|
});
|
|
238
272
|
server.addTool({
|
|
239
273
|
name: "abandon",
|
|
@@ -243,11 +277,12 @@ server.addTool({
|
|
|
243
277
|
"Optional Gherkin feature source capturing what was learned \u2014 auto-saved as experience growup"
|
|
244
278
|
)
|
|
245
279
|
}),
|
|
246
|
-
execute: async ({ experience }) => {
|
|
280
|
+
execute: safeTool("abandon", async ({ experience }) => {
|
|
247
281
|
const role = requireRole();
|
|
248
282
|
role.abandon(experience);
|
|
249
|
-
|
|
250
|
-
|
|
283
|
+
const msg = experience ? "Goal abandoned. Experience captured." : "Goal abandoned.";
|
|
284
|
+
return next(msg, NEXT.abandon);
|
|
285
|
+
})
|
|
251
286
|
});
|
|
252
287
|
server.addTool({
|
|
253
288
|
name: "reflect",
|
|
@@ -261,11 +296,14 @@ server.addTool({
|
|
|
261
296
|
),
|
|
262
297
|
knowledgeSource: z.string().describe("Gherkin feature source text for the knowledge")
|
|
263
298
|
}),
|
|
264
|
-
execute: async ({ experienceNames, knowledgeName, knowledgeSource }) => {
|
|
299
|
+
execute: safeTool("reflect", async ({ experienceNames, knowledgeName, knowledgeSource }) => {
|
|
265
300
|
const role = requireRole();
|
|
266
301
|
const feature = role.reflect(experienceNames, knowledgeName, knowledgeSource);
|
|
267
|
-
return
|
|
268
|
-
|
|
302
|
+
return next(
|
|
303
|
+
`Reflected: ${experienceNames.length} experience(s) \u2192 knowledge "${feature.name}"`,
|
|
304
|
+
NEXT.reflect
|
|
305
|
+
);
|
|
306
|
+
})
|
|
269
307
|
});
|
|
270
308
|
server.addTool({
|
|
271
309
|
name: "finish",
|
|
@@ -273,11 +311,13 @@ server.addTool({
|
|
|
273
311
|
parameters: z.object({
|
|
274
312
|
name: z.string().describe("Task name to mark as done")
|
|
275
313
|
}),
|
|
276
|
-
execute: async ({ name }) => {
|
|
314
|
+
execute: safeTool("finish", async ({ name }) => {
|
|
277
315
|
const role = requireRole();
|
|
278
316
|
role.finish(name);
|
|
279
|
-
|
|
280
|
-
|
|
317
|
+
const { current } = role.focus();
|
|
318
|
+
const remaining = current ? current.tasks.filter((t) => !t.tags?.some((tag) => tag.name === "@done")).length : -1;
|
|
319
|
+
return next(`Task finished: ${name}`, remaining >= 0 ? nextFinish(remaining) : NEXT.achieve);
|
|
320
|
+
})
|
|
281
321
|
});
|
|
282
322
|
server.start({
|
|
283
323
|
transportType: "stdio"
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @rolexjs/mcp-server\n *\n * MCP server for Rolex — Role-Driven Development.\n *\n * Tools:\n * society — Admin: born, found, directory, find, teach\n * organization — Admin: hire, fire\n * identity — Activate a role\n * growup/focus/want/plan/todo/achieve/abandon/finish — Role lifecycle\n *\n * Usage:\n * rolex-mcp [.rolex-dir]\n */\n\nimport { FastMCP } from \"fastmcp\";\nimport { z } from \"zod\";\nimport {\n Rolex,\n Organization,\n Role,\n INSTRUCTIONS,\n DESC_SOCIETY,\n DESC_ORGANIZATION,\n DESC_GROWUP,\n DESC_IDENTITY,\n DESC_FOCUS,\n DESC_WANT,\n DESC_PLAN,\n DESC_TODO,\n DESC_ACHIEVE,\n DESC_ABANDON,\n DESC_REFLECT,\n DESC_FINISH,\n renderFeatures,\n renderFeature,\n bootstrap,\n} from \"rolexjs\";\nimport { LocalPlatform } from \"@rolexjs/local-platform\";\n\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst DEFAULT_ROLEX_DIR = join(homedir(), \".rolex\");\nconst rolexDir = process.argv[2] || process.env.ROLEX_DIR || DEFAULT_ROLEX_DIR;\nconst platform = new LocalPlatform(rolexDir);\nbootstrap(platform);\nconst rolex = new Rolex(platform);\nlet currentRole: Role | null = null;\n\nconst server = new FastMCP({\n name: \"Rolex MCP Server\",\n version: \"0.1.0\",\n instructions: INSTRUCTIONS,\n});\n\n// ========== Helpers ==========\n\nfunction requireRole(): Role {\n if (!currentRole) {\n throw new Error(\"No active role. Call identity(roleId) first to activate a role.\");\n }\n return currentRole;\n}\n\n// ========== Society (folded) ==========\n\nserver.addTool({\n name: \"society\",\n description: DESC_SOCIETY,\n parameters: z.object({\n operation: z\n .enum([\"born\", \"found\", \"directory\", \"find\", \"teach\"])\n .describe(\"The society operation to perform\"),\n name: z\n .string()\n .optional()\n .describe(\"Role name (born/find/teach) or organization name (found)\"),\n source: z\n .string()\n .optional()\n .describe(\"Gherkin feature source (born: persona, teach: knowledge)\"),\n roleId: z.string().optional().describe(\"Target role name for teach operation\"),\n type: z\n .enum([\"knowledge\", \"experience\", \"voice\"])\n .optional()\n .describe(\"Growth dimension for teach operation\"),\n dimensionName: z\n .string()\n .optional()\n .describe(\"Name for the knowledge being taught (e.g. 'distributed-systems')\"),\n }),\n execute: async ({ operation, name, source, roleId, type, dimensionName }) => {\n switch (operation) {\n case \"born\": {\n if (!name || !source) throw new Error(\"born requires: name, source\");\n const feature = rolex.born(name, source);\n return `Role born: ${feature.name}`;\n }\n case \"found\": {\n if (!name) throw new Error(\"found requires: name\");\n rolex.found(name);\n return `Organization founded: ${name}`;\n }\n case \"directory\": {\n const dir = rolex.directory();\n const lines: string[] = [];\n for (const entry of dir.organizations) {\n const orgInstance = rolex.find(entry.name) as Organization;\n const info = orgInstance.info();\n lines.push(`Organization: ${info.name}`);\n for (const role of info.roles) {\n lines.push(` - ${role.name} (team: ${role.team})`);\n }\n }\n return lines.join(\"\\n\") || \"No organizations found.\";\n }\n case \"find\": {\n if (!name) throw new Error(\"find requires: name\");\n const result = rolex.find(name);\n if (result instanceof Organization) {\n const info = result.info();\n return `Organization: ${info.name} (${info.roles.length} roles)`;\n }\n const features = (result as Role).identity();\n return renderFeatures(features);\n }\n case \"teach\": {\n if (!roleId || !type || !dimensionName || !source)\n throw new Error(\"teach requires: roleId, type, dimensionName, source\");\n const feature = rolex.teach(roleId, type, dimensionName, source);\n return `Taught ${type}: ${feature.name}`;\n }\n default:\n throw new Error(`Unknown society operation: ${operation}`);\n }\n },\n});\n\n// ========== Organization (folded) ==========\n\nserver.addTool({\n name: \"organization\",\n description: DESC_ORGANIZATION,\n parameters: z.object({\n operation: z.enum([\"hire\", \"fire\"]).describe(\"The organization operation to perform\"),\n name: z.string().describe(\"Role name to hire or fire\"),\n }),\n execute: async ({ operation, name }) => {\n const dir = rolex.directory();\n const org = rolex.find(dir.organizations[0].name) as Organization;\n\n switch (operation) {\n case \"hire\": {\n org.hire(name);\n return `Role hired: ${name}`;\n }\n case \"fire\": {\n org.fire(name);\n return `Role fired: ${name}`;\n }\n default:\n throw new Error(`Unknown organization operation: ${operation}`);\n }\n },\n});\n\n// ========== Role Activation ==========\n\nserver.addTool({\n name: \"identity\",\n description: DESC_IDENTITY,\n parameters: z.object({\n roleId: z.string().describe(\"Role name (e.g. 'sean')\"),\n }),\n execute: async ({ roleId }) => {\n currentRole = rolex.role(roleId);\n const features = currentRole.identity();\n return renderFeatures(features);\n },\n});\n\n// ========== Role Tools ==========\n\nserver.addTool({\n name: \"growup\",\n description: DESC_GROWUP,\n parameters: z.object({\n type: z\n .enum([\"knowledge\", \"experience\", \"voice\"])\n .describe(\n \"Growth dimension: knowledge (what I know), experience (what I've lived), voice (how I'm perceived)\"\n ),\n name: z\n .string()\n .describe(\"Name for this growth (used as filename, e.g. 'distributed-systems')\"),\n source: z.string().describe(\"Gherkin feature source text\"),\n }),\n execute: async ({ type, name, source }) => {\n const role = requireRole();\n const feature = role.growup(type, name, source);\n return `Growth added (${type}): ${feature.name}`;\n },\n});\n\nserver.addTool({\n name: \"focus\",\n description: DESC_FOCUS,\n parameters: z.object({\n name: z.string().optional().describe(\"Optional goal name to switch focus to\"),\n }),\n execute: async ({ name }) => {\n const role = requireRole();\n const { current, otherGoals } = role.focus(name);\n if (!current && otherGoals.length === 0) return \"No active goal. Use want() to set a new goal.\";\n\n const parts: string[] = [];\n\n if (current) {\n parts.push(renderFeature(current));\n if (current.plan) {\n parts.push(renderFeature(current.plan));\n }\n for (const task of current.tasks) {\n parts.push(renderFeature(task));\n }\n }\n\n if (otherGoals.length > 0) {\n parts.push(\"Other active goals:\");\n for (const g of otherGoals) {\n parts.push(` - ${g.name}`);\n }\n }\n\n return parts.join(\"\\n\\n\");\n },\n});\n\nserver.addTool({\n name: \"want\",\n description: DESC_WANT,\n parameters: z.object({\n name: z.string().describe(\"Goal name (used as directory name, e.g. 'local-platform')\"),\n source: z.string().describe(\"Gherkin feature source text for the goal\"),\n testable: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether this goal's scenarios should become persistent automated verification\"),\n }),\n execute: async ({ name, source, testable }) => {\n const role = requireRole();\n const goal = role.want(name, source, testable);\n return `Goal created: ${goal.name}`;\n },\n});\n\nserver.addTool({\n name: \"plan\",\n description: DESC_PLAN,\n parameters: z.object({\n source: z.string().describe(\"Gherkin feature source text for the plan\"),\n }),\n execute: async ({ source }) => {\n const role = requireRole();\n const p = role.plan(source);\n return `Plan created: ${p.name}`;\n },\n});\n\nserver.addTool({\n name: \"todo\",\n description: DESC_TODO,\n parameters: z.object({\n name: z.string().describe(\"Task name (used as filename, e.g. 'implement-loader')\"),\n source: z.string().describe(\"Gherkin feature source text for the task\"),\n testable: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether this task's scenarios should become unit or integration tests\"),\n }),\n execute: async ({ name, source, testable }) => {\n const role = requireRole();\n const task = role.todo(name, source, testable);\n return `Task created: ${task.name}`;\n },\n});\n\nserver.addTool({\n name: \"achieve\",\n description: DESC_ACHIEVE,\n parameters: z.object({\n experience: z\n .string()\n .optional()\n .describe(\n \"Optional Gherkin feature source capturing what was learned — auto-saved as experience growup\"\n ),\n }),\n execute: async ({ experience }) => {\n const role = requireRole();\n role.achieve(experience);\n return experience ? \"Goal achieved. Experience captured.\" : \"Goal achieved.\";\n },\n});\n\nserver.addTool({\n name: \"abandon\",\n description: DESC_ABANDON,\n parameters: z.object({\n experience: z\n .string()\n .optional()\n .describe(\n \"Optional Gherkin feature source capturing what was learned — auto-saved as experience growup\"\n ),\n }),\n execute: async ({ experience }) => {\n const role = requireRole();\n role.abandon(experience);\n return experience ? \"Goal abandoned. Experience captured.\" : \"Goal abandoned.\";\n },\n});\n\nserver.addTool({\n name: \"reflect\",\n description: DESC_REFLECT,\n parameters: z.object({\n experienceNames: z\n .array(z.string())\n .describe(\n \"Names of experience files to distill (without .experience.identity.feature suffix)\"\n ),\n knowledgeName: z\n .string()\n .describe(\n \"Name for the resulting knowledge (used as filename, e.g. 'authentication-principles')\"\n ),\n knowledgeSource: z.string().describe(\"Gherkin feature source text for the knowledge\"),\n }),\n execute: async ({ experienceNames, knowledgeName, knowledgeSource }) => {\n const role = requireRole();\n const feature = role.reflect(experienceNames, knowledgeName, knowledgeSource);\n return `Reflected: ${experienceNames.length} experience(s) → knowledge \"${feature.name}\"`;\n },\n});\n\nserver.addTool({\n name: \"finish\",\n description: DESC_FINISH,\n parameters: z.object({\n name: z.string().describe(\"Task name to mark as done\"),\n }),\n execute: async ({ name }) => {\n const role = requireRole();\n role.finish(name);\n return `Task finished: ${name}`;\n },\n});\n\nserver.start({\n transportType: \"stdio\",\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @rolexjs/mcp-server\n *\n * MCP server for Rolex — Role-Driven Development.\n *\n * Tools:\n * society — Admin: born, found, directory, find, teach\n * organization — Admin: hire, fire\n * identity — Activate a role\n * growup/focus/want/plan/todo/achieve/abandon/finish — Role lifecycle\n *\n * Usage:\n * rolex-mcp [.rolex-dir]\n */\n\nimport { FastMCP } from \"fastmcp\";\nimport { z } from \"zod\";\nimport {\n Rolex,\n Organization,\n Role,\n INSTRUCTIONS,\n DESC_SOCIETY,\n DESC_ORGANIZATION,\n DESC_GROWUP,\n DESC_IDENTITY,\n DESC_FOCUS,\n DESC_WANT,\n DESC_PLAN,\n DESC_TODO,\n DESC_ACHIEVE,\n DESC_ABANDON,\n DESC_REFLECT,\n DESC_FINISH,\n renderFeatures,\n renderFeature,\n renderStatusBar,\n renderError,\n next,\n NEXT,\n nextHire,\n nextFinish,\n bootstrap,\n} from \"rolexjs\";\nimport { LocalPlatform } from \"@rolexjs/local-platform\";\n\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst DEFAULT_ROLEX_DIR = join(homedir(), \".rolex\");\nconst rolexDir = process.argv[2] || process.env.ROLEX_DIR || DEFAULT_ROLEX_DIR;\nconst platform = new LocalPlatform(rolexDir);\nbootstrap(platform);\nconst rolex = new Rolex(platform);\nlet currentRole: Role | null = null;\nlet currentRoleName: string = \"\";\n\nconst server = new FastMCP({\n name: \"Rolex MCP Server\",\n version: \"0.1.0\",\n instructions: INSTRUCTIONS,\n});\n\n// ========== Helpers ==========\n\nfunction requireRole(): Role {\n if (!currentRole) {\n throw new Error(\"No active role. Call identity(roleId) first to activate a role.\");\n }\n return currentRole;\n}\n\n/**\n * Wrap a tool execute function with unified error handling.\n * Catches errors and renders them as formatted markdown.\n */\nfunction safeTool<T>(\n toolName: string,\n fn: (args: T) => Promise<string>\n): (args: T) => Promise<string> {\n return async (args: T) => {\n try {\n return await fn(args);\n } catch (error) {\n throw new Error(renderError(toolName, error));\n }\n };\n}\n\n// ========== Society (folded) ==========\n\nserver.addTool({\n name: \"society\",\n description: DESC_SOCIETY,\n parameters: z.object({\n operation: z\n .enum([\"born\", \"found\", \"directory\", \"find\", \"teach\"])\n .describe(\"The society operation to perform\"),\n name: z\n .string()\n .optional()\n .describe(\"Role name (born/find/teach) or organization name (found)\"),\n source: z\n .string()\n .optional()\n .describe(\"Gherkin feature source (born: persona, teach: knowledge)\"),\n roleId: z.string().optional().describe(\"Target role name for teach operation\"),\n type: z\n .enum([\"knowledge\", \"experience\", \"voice\"])\n .optional()\n .describe(\"Growth dimension for teach operation\"),\n dimensionName: z\n .string()\n .optional()\n .describe(\"Name for the knowledge being taught (e.g. 'distributed-systems')\"),\n }),\n execute: safeTool(\"society\", async ({ operation, name, source, roleId, type, dimensionName }) => {\n switch (operation) {\n case \"born\": {\n if (!name || !source) throw new Error(\"born requires: name, source\");\n const feature = rolex.born(name, source);\n return next(`Role born: ${feature.name}`, NEXT.born);\n }\n case \"found\": {\n if (!name) throw new Error(\"found requires: name\");\n rolex.found(name);\n return next(`Organization founded: ${name}`, NEXT.found);\n }\n case \"directory\": {\n const dir = rolex.directory();\n const lines: string[] = [];\n\n // Organizations and their hired roles\n for (const entry of dir.organizations) {\n const orgInstance = rolex.find(entry.name) as Organization;\n const info = orgInstance.info();\n lines.push(`Organization: ${info.name}`);\n for (const role of info.roles) {\n lines.push(` - ${role.name} (team: ${role.team})`);\n }\n }\n\n // Unaffiliated roles (born but not hired)\n const unaffiliated = dir.roles.filter((r) => !r.team);\n if (unaffiliated.length > 0) {\n lines.push(\"\");\n lines.push(\"Unaffiliated:\");\n for (const role of unaffiliated) {\n lines.push(` - ${role.name}`);\n }\n }\n\n return lines.join(\"\\n\") || \"No roles or organizations found.\";\n }\n case \"find\": {\n if (!name) throw new Error(\"find requires: name\");\n const result = rolex.find(name);\n if (result instanceof Organization) {\n const info = result.info();\n return `Organization: ${info.name} (${info.roles.length} roles)`;\n }\n const features = (result as Role).identity();\n return renderFeatures(features);\n }\n case \"teach\": {\n if (!roleId || !type || !dimensionName || !source)\n throw new Error(\"teach requires: roleId, type, dimensionName, source\");\n const feature = rolex.teach(roleId, type, dimensionName, source);\n return next(`Taught ${type}: ${feature.name}`, NEXT.teach);\n }\n default:\n throw new Error(`Unknown society operation: ${operation}`);\n }\n }),\n});\n\n// ========== Organization (folded) ==========\n\nserver.addTool({\n name: \"organization\",\n description: DESC_ORGANIZATION,\n parameters: z.object({\n operation: z.enum([\"hire\", \"fire\"]).describe(\"The organization operation to perform\"),\n name: z.string().describe(\"Role name to hire or fire\"),\n }),\n execute: safeTool(\"organization\", async ({ operation, name }) => {\n const dir = rolex.directory();\n const org = rolex.find(dir.organizations[0].name) as Organization;\n\n switch (operation) {\n case \"hire\": {\n org.hire(name);\n return next(`Role hired: ${name}`, nextHire(name));\n }\n case \"fire\": {\n org.fire(name);\n return next(`Role fired: ${name}`, NEXT.fire);\n }\n default:\n throw new Error(`Unknown organization operation: ${operation}`);\n }\n }),\n});\n\n// ========== Role Activation ==========\n\nserver.addTool({\n name: \"identity\",\n description: DESC_IDENTITY,\n parameters: z.object({\n roleId: z.string().describe(\"Role name (e.g. 'sean')\"),\n }),\n execute: safeTool(\"identity\", async ({ roleId }) => {\n currentRole = rolex.role(roleId);\n currentRoleName = roleId;\n const features = currentRole.identity();\n const { current } = currentRole.focus();\n const statusBar = renderStatusBar(roleId, current);\n return `${statusBar}\\n\\n${renderFeatures(features)}`;\n }),\n});\n\n// ========== Role Tools ==========\n\nserver.addTool({\n name: \"growup\",\n description: DESC_GROWUP,\n parameters: z.object({\n type: z\n .enum([\"knowledge\", \"experience\", \"voice\"])\n .describe(\n \"Growth dimension: knowledge (what I know), experience (what I've lived), voice (how I'm perceived)\"\n ),\n name: z\n .string()\n .describe(\"Name for this growth (used as filename, e.g. 'distributed-systems')\"),\n source: z.string().describe(\"Gherkin feature source text\"),\n }),\n execute: safeTool(\"growup\", async ({ type, name, source }) => {\n const role = requireRole();\n const feature = role.growup(type, name, source);\n return next(`Growth added (${type}): ${feature.name}`, NEXT.growup);\n }),\n});\n\nserver.addTool({\n name: \"focus\",\n description: DESC_FOCUS,\n parameters: z.object({\n name: z.string().optional().describe(\"Optional goal name to switch focus to\"),\n }),\n execute: safeTool(\"focus\", async ({ name }) => {\n const role = requireRole();\n const { current, otherGoals } = role.focus(name);\n\n const statusBar = renderStatusBar(currentRoleName, current);\n\n if (!current && otherGoals.length === 0)\n return `${statusBar}\\n\\nNo active goal. Use want() to set a new goal.`;\n\n const parts: string[] = [statusBar];\n\n if (current) {\n parts.push(renderFeature(current));\n if (current.plan) {\n parts.push(renderFeature(current.plan));\n }\n for (const task of current.tasks) {\n parts.push(renderFeature(task));\n }\n }\n\n if (otherGoals.length > 0) {\n parts.push(\"Other active goals:\");\n for (const g of otherGoals) {\n parts.push(` - ${g.name}`);\n }\n }\n\n return parts.join(\"\\n\\n\");\n }),\n});\n\nserver.addTool({\n name: \"want\",\n description: DESC_WANT,\n parameters: z.object({\n name: z.string().describe(\"Goal name (used as directory name, e.g. 'local-platform')\"),\n source: z.string().describe(\"Gherkin feature source text for the goal\"),\n testable: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether this goal's scenarios should become persistent automated verification\"),\n }),\n execute: safeTool(\"want\", async ({ name, source, testable }) => {\n const role = requireRole();\n const goal = role.want(name, source, testable);\n return next(`Goal created: ${goal.name}`, NEXT.want);\n }),\n});\n\nserver.addTool({\n name: \"plan\",\n description: DESC_PLAN,\n parameters: z.object({\n source: z.string().describe(\"Gherkin feature source text for the plan\"),\n }),\n execute: safeTool(\"plan\", async ({ source }) => {\n const role = requireRole();\n const p = role.plan(source);\n return next(`Plan created: ${p.name}`, NEXT.plan);\n }),\n});\n\nserver.addTool({\n name: \"todo\",\n description: DESC_TODO,\n parameters: z.object({\n name: z.string().describe(\"Task name (used as filename, e.g. 'implement-loader')\"),\n source: z.string().describe(\"Gherkin feature source text for the task\"),\n testable: z\n .boolean()\n .optional()\n .default(false)\n .describe(\"Whether this task's scenarios should become unit or integration tests\"),\n }),\n execute: safeTool(\"todo\", async ({ name, source, testable }) => {\n const role = requireRole();\n const task = role.todo(name, source, testable);\n return next(`Task created: ${task.name}`, NEXT.todo);\n }),\n});\n\nserver.addTool({\n name: \"achieve\",\n description: DESC_ACHIEVE,\n parameters: z.object({\n experience: z\n .string()\n .optional()\n .describe(\n \"Optional Gherkin feature source capturing what was learned — auto-saved as experience growup\"\n ),\n }),\n execute: safeTool(\"achieve\", async ({ experience }) => {\n const role = requireRole();\n role.achieve(experience);\n const msg = experience ? \"Goal achieved. Experience captured.\" : \"Goal achieved.\";\n return next(msg, NEXT.achieve);\n }),\n});\n\nserver.addTool({\n name: \"abandon\",\n description: DESC_ABANDON,\n parameters: z.object({\n experience: z\n .string()\n .optional()\n .describe(\n \"Optional Gherkin feature source capturing what was learned — auto-saved as experience growup\"\n ),\n }),\n execute: safeTool(\"abandon\", async ({ experience }) => {\n const role = requireRole();\n role.abandon(experience);\n const msg = experience ? \"Goal abandoned. Experience captured.\" : \"Goal abandoned.\";\n return next(msg, NEXT.abandon);\n }),\n});\n\nserver.addTool({\n name: \"reflect\",\n description: DESC_REFLECT,\n parameters: z.object({\n experienceNames: z\n .array(z.string())\n .describe(\n \"Names of experience files to distill (without .experience.identity.feature suffix)\"\n ),\n knowledgeName: z\n .string()\n .describe(\n \"Name for the resulting knowledge (used as filename, e.g. 'authentication-principles')\"\n ),\n knowledgeSource: z.string().describe(\"Gherkin feature source text for the knowledge\"),\n }),\n execute: safeTool(\"reflect\", async ({ experienceNames, knowledgeName, knowledgeSource }) => {\n const role = requireRole();\n const feature = role.reflect(experienceNames, knowledgeName, knowledgeSource);\n return next(\n `Reflected: ${experienceNames.length} experience(s) → knowledge \"${feature.name}\"`,\n NEXT.reflect\n );\n }),\n});\n\nserver.addTool({\n name: \"finish\",\n description: DESC_FINISH,\n parameters: z.object({\n name: z.string().describe(\"Task name to mark as done\"),\n }),\n execute: safeTool(\"finish\", async ({ name }) => {\n const role = requireRole();\n role.finish(name);\n\n // Dynamic hint: check remaining tasks\n const { current } = role.focus();\n const remaining = current\n ? current.tasks.filter((t) => !t.tags?.some((tag) => tag.name === \"@done\")).length\n : -1;\n return next(`Task finished: ${name}`, remaining >= 0 ? nextFinish(remaining) : NEXT.achieve);\n }),\n});\n\nserver.start({\n transportType: \"stdio\",\n});\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rolexjs/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "MCP server for Rolex — expose RDD role management as MCP tools",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rolex",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"clean": "rm -rf dist"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"rolexjs": "^0.
|
|
45
|
-
"@rolexjs/local-platform": "^0.
|
|
44
|
+
"rolexjs": "^0.7.0",
|
|
45
|
+
"@rolexjs/local-platform": "^0.7.0",
|
|
46
46
|
"fastmcp": "^3.0.0",
|
|
47
47
|
"zod": "^3.25.0"
|
|
48
48
|
},
|