@elixium.ai/mcp-server 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +78 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -283,7 +283,7 @@ const normalizeLane = async (lane) => {
283
283
  const map = style === "upper" ? LANE_UPPER : LANE_TITLE;
284
284
  return map[key] || (style === "upper" ? lane.trim().toUpperCase() : lane.trim());
285
285
  };
286
- const buildIterationContext = (stories, user = null) => {
286
+ const buildIterationContext = (stories, user = null, infraProfile) => {
287
287
  const currentIteration = stories.filter((story) => normalizeLaneForComparison(story?.lane) === "current");
288
288
  const backlog = stories.filter((story) => normalizeLaneForComparison(story?.lane) === "backlog");
289
289
  // Cost summary across current iteration
@@ -294,7 +294,13 @@ const buildIterationContext = (stories, user = null) => {
294
294
  estimatedCount: withEstimates.length,
295
295
  unestimatedCount: iterationStories.length - withEstimates.length,
296
296
  };
297
- return { currentIteration, backlog, user, costSummary };
297
+ return {
298
+ currentIteration,
299
+ backlog,
300
+ user,
301
+ costSummary,
302
+ ...(infraProfile ? { infrastructureProfile: infraProfile } : {}),
303
+ };
298
304
  };
299
305
  const createServer = () => {
300
306
  const server = new Server({
@@ -520,7 +526,15 @@ const createServer = () => {
520
526
  description: "Optional constraints (e.g., budget limit, region, instance types)",
521
527
  },
522
528
  },
523
- required: ["storyId", "provider"],
529
+ required: ["storyId"],
530
+ },
531
+ },
532
+ {
533
+ name: "get_infrastructure_profile",
534
+ description: "Get the workspace infrastructure profile. Returns cloud provider, regions, compliance frameworks, existing services, and constraints. Use this to understand the team's environment before making infrastructure recommendations.",
535
+ inputSchema: {
536
+ type: "object",
537
+ properties: {},
524
538
  },
525
539
  },
526
540
  {
@@ -727,6 +741,13 @@ ${config.branchingDefaults ? `- Trunk-Based: ${config.branchingDefaults.trunkBas
727
741
  - Auto-Merge: ${config.branchingDefaults.autoMerge ? "Yes" : "No"}
728
742
  - Source: ${config.branchingDefaults.source}` : "Not configured (branch-based default)"}
729
743
 
744
+ ## Infrastructure Profile
745
+ ${config.infrastructureProfile?.provider ? `- Provider: ${config.infrastructureProfile.provider.toUpperCase()}
746
+ - Regions: ${config.infrastructureProfile.regions?.join(", ") || "Not set"}
747
+ - Compliance: ${config.infrastructureProfile.complianceFrameworks?.join(", ").toUpperCase() || "None"}
748
+ - Existing Services: ${config.infrastructureProfile.existingServices?.length || 0}
749
+ > Use \`get_infrastructure_profile\` for full details.` : "Not configured. Set up in Settings → Infrastructure."}
750
+
730
751
  > **Tip:** Features can be configured at workspace or board level. Board settings override workspace defaults.
731
752
  `;
732
753
  return {
@@ -782,9 +803,10 @@ ${config.branchingDefaults ? `- Trunk-Based: ${config.branchingDefaults.trunkBas
782
803
  const hasContextData = Array.isArray(currentIteration) &&
783
804
  Array.isArray(backlog) &&
784
805
  (currentIteration.length > 0 || backlog.length > 0);
806
+ const iterConfig = await fetchFeatureConfig();
785
807
  const context = hasContextData
786
- ? contextData
787
- : buildIterationContext(await fetchStories(), contextData?.user ?? null);
808
+ ? { ...contextData, ...(iterConfig.infrastructureProfile ? { infrastructureProfile: iterConfig.infrastructureProfile } : {}) }
809
+ : buildIterationContext(await fetchStories(), contextData?.user ?? null, iterConfig.infrastructureProfile);
788
810
  return {
789
811
  content: [
790
812
  { type: "text", text: JSON.stringify(context, null, 2) },
@@ -1105,11 +1127,22 @@ ${result.next_step}
1105
1127
  }
1106
1128
  case "estimate_cost": {
1107
1129
  const args = request.params.arguments;
1108
- const { storyId, provider, constraints } = args;
1130
+ const { storyId, constraints } = args;
1131
+ let { provider } = args;
1109
1132
  if (!storyId)
1110
1133
  throw new Error("storyId is required");
1134
+ // Default provider from infrastructure profile if not explicitly provided
1135
+ if (!provider) {
1136
+ const costConfig = await fetchFeatureConfig();
1137
+ const profileProvider = costConfig.infrastructureProfile?.provider;
1138
+ if (profileProvider) {
1139
+ // Map gov variants to commercial for cost estimation API
1140
+ const govMap = { "aws-gov": "aws", "azure-gov": "azure" };
1141
+ provider = govMap[profileProvider] || profileProvider;
1142
+ }
1143
+ }
1111
1144
  if (!provider)
1112
- throw new Error("provider is required");
1145
+ throw new Error("provider is required (set it explicitly or configure an infrastructure profile)");
1113
1146
  if (!["gcp", "aws", "azure", "self-hosted"].includes(provider)) {
1114
1147
  throw new Error("provider must be one of: gcp, aws, azure, self-hosted");
1115
1148
  }
@@ -1119,12 +1152,14 @@ ${result.next_step}
1119
1152
  if (!storyData.description) {
1120
1153
  throw new Error("Story needs a description before cost estimation");
1121
1154
  }
1122
- // Call the AI estimate-cost endpoint
1155
+ // Call the AI estimate-cost endpoint (with epicId/boardId for infra context)
1123
1156
  const estimateRes = await client.post("/ai/estimate-cost", {
1124
1157
  storyTitle: storyData.title,
1125
1158
  description: storyData.description,
1126
1159
  provider,
1127
1160
  ...(constraints ? { constraints } : {}),
1161
+ ...(storyData.epicId ? { epicId: storyData.epicId } : {}),
1162
+ ...(storyData.boardId ? { boardId: storyData.boardId } : {}),
1128
1163
  });
1129
1164
  const estimate = estimateRes.data;
1130
1165
  // Save the estimate to the story
@@ -1223,6 +1258,41 @@ ${unestimated.length === 0
1223
1258
  content: [{ type: "text", text: formattedResult.trim() }],
1224
1259
  };
1225
1260
  }
1261
+ case "get_infrastructure_profile": {
1262
+ const profileConfig = await fetchFeatureConfig();
1263
+ const profile = profileConfig.infrastructureProfile;
1264
+ if (!profile || !profile.provider) {
1265
+ return {
1266
+ content: [{
1267
+ type: "text",
1268
+ text: "# Infrastructure Profile\n\nNo infrastructure profile configured. Ask the workspace admin to set one up in **Settings → Infrastructure**.\n\nThis profile tells the AI about your cloud environment — provider, regions, compliance frameworks, and existing services — so cost estimates and recommendations are accurate.",
1269
+ }],
1270
+ };
1271
+ }
1272
+ const sections = ["# Workspace Infrastructure Profile\n"];
1273
+ sections.push(`**Cloud Provider:** ${profile.provider.toUpperCase()}`);
1274
+ if (profile.regions?.length) {
1275
+ sections.push(`**Regions:** ${profile.regions.join(", ")}`);
1276
+ }
1277
+ if (profile.complianceFrameworks?.length) {
1278
+ sections.push(`\n## Compliance Frameworks\n${profile.complianceFrameworks.map((f) => `- ${f.toUpperCase()}`).join("\n")}`);
1279
+ }
1280
+ if (profile.existingServices?.length) {
1281
+ sections.push(`\n## Existing Services\n| Service | Category | Specs |\n|---------|----------|-------|\n${profile.existingServices.map((s) => `| ${s.name} | ${s.category} | ${s.specs || "-"} |`).join("\n")}`);
1282
+ }
1283
+ if (profile.networkTopology) {
1284
+ sections.push(`\n## Network Topology\n${profile.networkTopology}`);
1285
+ }
1286
+ if (profile.additionalConstraints) {
1287
+ sections.push(`\n## Additional Constraints\n${profile.additionalConstraints}`);
1288
+ }
1289
+ if (profile.updatedAt) {
1290
+ sections.push(`\n---\n*Last updated: ${new Date(profile.updatedAt).toLocaleDateString()}*`);
1291
+ }
1292
+ return {
1293
+ content: [{ type: "text", text: sections.join("\n") }],
1294
+ };
1295
+ }
1226
1296
  default:
1227
1297
  throw new Error("Unknown tool");
1228
1298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elixium.ai/mcp-server",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "MCP Server for Elixium.ai",
6
6
  "publishConfig": {