@elixium.ai/mcp-server 0.1.2 → 0.1.4

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 CHANGED
@@ -7,6 +7,48 @@ const API_KEY = process.env.ELIXIUM_API_KEY;
7
7
  const API_URL = process.env.ELIXIUM_API_URL || "https://elixium.ai/api";
8
8
  const BOARD_SLUG = process.env.ELIXIUM_BOARD_SLUG;
9
9
  const LANE_STYLE_ENV = process.env.ELIXIUM_LANE_STYLE;
10
+ import * as fs from "fs";
11
+ import * as path from "path";
12
+ import { fileURLToPath } from "url";
13
+ // Handle init command
14
+ if (process.argv.includes("init")) {
15
+ const targetDir = path.join(process.cwd(), ".agent", "workflows");
16
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+ // In source, templates are at ../templates. In dist, they are copied to dist/templates?
18
+ // We need to ensure package.json copies them correctly or we read from source.
19
+ // For 'npx run', it runs from installed node_modules.
20
+ // Let's assume structure:
21
+ // node_modules/@elixium.ai/mcp-server/
22
+ // dist/index.js
23
+ // templates/workflows/...
24
+ // When running with ts-node src/index.ts, __dirname is .../mcp-server/src
25
+ // Templates are at .../mcp-server/templates
26
+ // So we need to go up one level from src
27
+ const templateDir = path.resolve(__dirname, "..", "templates", "workflows");
28
+ console.log(`Initializing Elixium Agent Workflows...`);
29
+ console.log(`Target: ${targetDir}`);
30
+ if (!fs.existsSync(targetDir)) {
31
+ fs.mkdirSync(targetDir, { recursive: true });
32
+ }
33
+ const files = [
34
+ "manage-board.md",
35
+ "implement-story.md",
36
+ "load-board-context.md",
37
+ ];
38
+ files.forEach(file => {
39
+ const src = path.join(templateDir, file);
40
+ const dest = path.join(targetDir, file);
41
+ if (fs.existsSync(src)) {
42
+ fs.copyFileSync(src, dest);
43
+ console.log(`✓ Created ${file}`);
44
+ }
45
+ else {
46
+ console.error(`Error: Could not find template for ${file} at ${src}`);
47
+ }
48
+ });
49
+ console.log(`\nWorkflows initialized successfully!`);
50
+ process.exit(0);
51
+ }
10
52
  if (!API_KEY) {
11
53
  console.error("Error: ELIXIUM_API_KEY environment variable is required");
12
54
  process.exit(1);
@@ -183,6 +225,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
183
225
  type: "string",
184
226
  description: "Description of the story",
185
227
  },
228
+ acceptanceCriteria: {
229
+ type: "string",
230
+ description: "Acceptance criteria in Given/When/Then format",
231
+ },
186
232
  lane: {
187
233
  type: "string",
188
234
  description: "Lane to add the story to (case-insensitive)",
@@ -332,6 +378,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
332
378
  type: "string",
333
379
  description: "Learning outcome summary",
334
380
  },
381
+ acceptanceCriteria: {
382
+ type: "string",
383
+ description: "Acceptance criteria in Given/When/Then format",
384
+ },
335
385
  },
336
386
  required: ["storyId"],
337
387
  },
@@ -437,13 +487,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
437
487
  }
438
488
  case "update_story": {
439
489
  const args = request.params.arguments;
440
- const { storyId, lane, ...rest } = args;
490
+ const { storyId, lane, state, ...rest } = args;
441
491
  if (!storyId) {
442
492
  throw new Error("storyId is required");
443
493
  }
494
+ // Guardrail: Block AI from setting accepted/rejected states (human-in-the-loop)
495
+ const blockedStates = ["accepted", "rejected"];
496
+ if (state && blockedStates.includes(state.toLowerCase())) {
497
+ throw new Error(`Cannot set state to "${state}". Acceptance decisions require human review.`);
498
+ }
444
499
  const normalizedLane = await normalizeLane(lane);
445
500
  const payload = Object.fromEntries(Object.entries({
446
501
  ...rest,
502
+ ...(state ? { state } : {}),
447
503
  ...(normalizedLane ? { lane: normalizedLane } : {}),
448
504
  }).filter(([, value]) => value !== undefined));
449
505
  const response = await client.patch(`/stories/${storyId}`, payload);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elixium.ai/mcp-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "MCP Server for Elixium.ai",
6
6
  "publishConfig": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "dist",
11
+ "templates",
11
12
  "README.md",
12
13
  "package.json"
13
14
  ],
@@ -30,4 +31,4 @@
30
31
  "ts-node": "^10.9.0",
31
32
  "typescript": "^5.3.0"
32
33
  }
33
- }
34
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: How to implement an Elixium story using the agent and MCP
3
+ ---
4
+
5
+ Follow this workflow when a developer selects a story for implementation.
6
+
7
+ ### 1. Identify & Prepare the Story
8
+ - Ask the developer which story they want to work on, or list the stories in the **Current** lane using `mcp_elixium_list_stories`.
9
+ - Once a story is selected, run the `mcp_elixium_prepare_implementation` tool.
10
+
11
+ ### 2. Review the Brief
12
+ - The tool will output an **Implementation Brief** containing:
13
+ - **Acceptance Criteria**
14
+ - **Assumptions / Learning Goals**
15
+ - **Guardrail Warnings** (e.g., if the story is in the wrong lane)
16
+
17
+ ### 3. Propose & Confirm
18
+ - Review the brief and add a **Proposal**: "Here’s the smallest change that will validate it: [Describe minimal slice]"
19
+ - Only after the developer confirms the plan should the agent transition to `EXECUTION` mode.
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Load Elixium board context at the start of a session
3
+ ---
4
+
5
+ Use this workflow at the beginning of a session or when the user asks about board context.
6
+
7
+ > [!IMPORTANT]
8
+ > **ALWAYS** use the `mcp_elixium_*` tools. **NEVER** call the Elixium API directly.
9
+
10
+ ### 1. Load context
11
+ - Call `mcp_elixium_get_iteration_context` immediately.
12
+ - Cache the `current` and `backlog` stories for the rest of the session.
13
+
14
+ ### 2. Keep context fresh
15
+ - Re-run `mcp_elixium_get_iteration_context` if the user asks for the “latest” state
16
+ or if the session has been idle for ~10 minutes.
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: How to manage the product backlog and board using Elixium MCP
3
+ ---
4
+
5
+ Use this workflow for any project management requests (creating stories, checking status, adding epics).
6
+
7
+ > [!IMPORTANT]
8
+ > **ALWAYS** use the `mcp_elixium_*` tools. **NEVER** try to write scripts to interact with the API directly.
9
+ > The MCP server is your authenticated, context-aware interface to the board.
10
+
11
+ ### 1. View the Board
12
+ - Use `mcp_elixium_list_stories` to see the current state of the board.
13
+ - Use `mcp_elixium_list_epics` to see high-level initiatives.
14
+
15
+ ### 2. Create Stories
16
+ - **New Features**: Use `mcp_elixium_create_story` with `lane: "Backlog"` (or `Icebox` for ideas).
17
+ - **Assumptions**: Use `mcp_elixium_create_hypothesis` for risky ideas that need validation first.
18
+ - **Epics**: Use `mcp_elixium_create_epic` for large initiatives.
19
+
20
+ ### 3. Update Status
21
+ - Use `mcp_elixium_update_story` to move cards (e.g., `lane: "Current"`, `lane: "Done"`).
22
+ - **Do not** set state to `accepted` or `rejected`. Only humans can accept stories.
23
+
24
+ ### 4. Continuous Context
25
+ - Use `mcp_elixium_get_iteration_context` when planning a coding session to see exactly what is in scope for the Current iteration.