@cubis/foundry 0.3.59 → 0.3.61

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/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.3.61] - 2026-03-05
6
+
7
+ ### Fixed
8
+
9
+ - Extended MCP startup reliability fixes across all supported platforms:
10
+ - project/global Postman MCP runtime targets now prefer static Authorization headers when managed keys are available
11
+ - Stitch header generation now also supports managed static key injection for runtime startup reliability.
12
+ - Unified default managed credential aliases across install paths:
13
+ - Postman default env alias is now `POSTMAN_API_KEY_DEFAULT`
14
+ - Stitch default env alias is now `STITCH_API_KEY_DEFAULT`
15
+ - aligns non-wizard installs with wizard persistence behavior across platforms.
16
+
17
+ ## [0.3.60] - 2026-03-05
18
+
19
+ ### Fixed
20
+
21
+ - Fixed `cbx mcp serve` runtime failure from global npm installs by including required MCP runtime dependencies in the main package (`@modelcontextprotocol/sdk`, `zod`).
22
+ - Improved Codex global Postman MCP startup reliability:
23
+ - after registration, CBX now patches Codex MCP config to use static Authorization headers when a managed Postman key is available
24
+ - avoids startup failures caused by missing shell-exported `POSTMAN_API_KEY_DEFAULT`.
25
+
5
26
  ## [0.3.59] - 2026-03-05
6
27
 
7
28
  ### Added
package/dist/cli/core.js CHANGED
@@ -134,7 +134,7 @@ const CODEX_WORKFLOW_SKILL_PREFIX = "workflow-";
134
134
  const CODEX_AGENT_SKILL_PREFIX = "agent-";
135
135
  const TERMINAL_VERIFIER_PROVIDERS = ["codex", "gemini"];
136
136
  const DEFAULT_TERMINAL_VERIFIER = "codex";
137
- const POSTMAN_API_KEY_ENV_VAR = "POSTMAN_API_KEY";
137
+ const POSTMAN_API_KEY_ENV_VAR = "POSTMAN_API_KEY_DEFAULT";
138
138
  const POSTMAN_MODE_TO_URL = Object.freeze({
139
139
  minimal: "https://mcp.postman.com/minimal",
140
140
  code: "https://mcp.postman.com/code",
@@ -151,7 +151,7 @@ const FOUNDRY_MCP_SERVER_ID = "cubis-foundry";
151
151
  const FOUNDRY_MCP_COMMAND = "cbx";
152
152
  const STITCH_SKILL_ID = "stitch";
153
153
  const STITCH_MCP_SERVER_ID = "StitchMCP";
154
- const STITCH_API_KEY_ENV_VAR = "STITCH_API_KEY";
154
+ const STITCH_API_KEY_ENV_VAR = "STITCH_API_KEY_DEFAULT";
155
155
  const STITCH_MCP_URL = "https://stitch.googleapis.com/mcp";
156
156
  const POSTMAN_WORKSPACE_MANUAL_CHOICE = "__postman_workspace_manual__";
157
157
  const CBX_CONFIG_FILENAME = "cbx_config.json";
@@ -1028,6 +1028,79 @@ function parseTomlSections(content) {
1028
1028
  }
1029
1029
  return sections;
1030
1030
  }
1031
+ function escapeTomlBasicString(value) {
1032
+ return String(value ?? "")
1033
+ .replace(/\\/g, "\\\\")
1034
+ .replace(/"/g, '\\"');
1035
+ }
1036
+ async function patchCodexPostmanHttpHeaders({ configPath, mcpUrl, bearerToken, dryRun = false, }) {
1037
+ const warnings = [];
1038
+ const normalizedToken = normalizePostmanApiKey(bearerToken);
1039
+ if (!normalizedToken) {
1040
+ return {
1041
+ action: "skipped",
1042
+ warnings: [
1043
+ "Postman API key is unavailable in current environment. Kept bearer_token_env_var wiring in Codex config.",
1044
+ ],
1045
+ };
1046
+ }
1047
+ const configExists = await pathExists(configPath);
1048
+ const original = configExists ? await readFile(configPath, "utf8") : "";
1049
+ const lines = original.split(/\r?\n/);
1050
+ const nextLines = [];
1051
+ const headerLine = `http_headers = { Authorization = "Bearer ${escapeTomlBasicString(normalizedToken)}" }`;
1052
+ const serverHeader = "[mcp_servers.postman]";
1053
+ let inPostmanSection = false;
1054
+ let postmanSectionFound = false;
1055
+ let insertedHeaders = false;
1056
+ const flushPostmanHeaderIfNeeded = () => {
1057
+ if (inPostmanSection && !insertedHeaders) {
1058
+ nextLines.push(headerLine);
1059
+ insertedHeaders = true;
1060
+ }
1061
+ };
1062
+ for (const line of lines) {
1063
+ const sectionMatch = line.match(/^\s*\[([^\]]+)\]\s*$/);
1064
+ if (sectionMatch) {
1065
+ flushPostmanHeaderIfNeeded();
1066
+ const sectionName = sectionMatch[1].trim();
1067
+ inPostmanSection = sectionName === "mcp_servers.postman";
1068
+ if (inPostmanSection) {
1069
+ postmanSectionFound = true;
1070
+ insertedHeaders = false;
1071
+ }
1072
+ nextLines.push(line);
1073
+ continue;
1074
+ }
1075
+ if (inPostmanSection) {
1076
+ if (/^\s*(bearer_token_env_var|http_headers|env_http_headers)\s*=/.test(line)) {
1077
+ continue;
1078
+ }
1079
+ }
1080
+ nextLines.push(line);
1081
+ }
1082
+ flushPostmanHeaderIfNeeded();
1083
+ if (!postmanSectionFound) {
1084
+ if (nextLines.length > 0 && nextLines[nextLines.length - 1].trim() !== "") {
1085
+ nextLines.push("");
1086
+ }
1087
+ nextLines.push(serverHeader);
1088
+ nextLines.push(`url = "${escapeTomlBasicString(mcpUrl || POSTMAN_MCP_URL)}"`);
1089
+ nextLines.push(headerLine);
1090
+ }
1091
+ const next = `${nextLines.join("\n").replace(/\n+$/g, "")}\n`;
1092
+ if (next === original) {
1093
+ return { action: "unchanged", warnings };
1094
+ }
1095
+ if (!dryRun) {
1096
+ await mkdir(path.dirname(configPath), { recursive: true });
1097
+ await writeFile(configPath, next, "utf8");
1098
+ }
1099
+ return {
1100
+ action: dryRun ? "would-patch" : "patched",
1101
+ warnings,
1102
+ };
1103
+ }
1031
1104
  function parsePubspecDependencyNames(content) {
1032
1105
  const packages = new Set();
1033
1106
  let currentSection = null;
@@ -3528,24 +3601,32 @@ function resolvePostmanMcpDefinitionPath({ platform, scope, cwd = process.cwd(),
3528
3601
  function resolveStitchMcpDefinitionPath({ scope, cwd = process.cwd() }) {
3529
3602
  return path.join(resolveMcpRootPath({ scope, cwd }), "antigravity", "stitch.json");
3530
3603
  }
3531
- function buildPostmanAuthHeader({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR }) {
3604
+ function buildPostmanAuthHeader({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, }) {
3605
+ const normalizedApiKey = normalizePostmanApiKey(apiKey);
3606
+ if (normalizedApiKey) {
3607
+ return `Bearer ${normalizedApiKey}`;
3608
+ }
3532
3609
  return `Bearer \${${apiKeyEnvVar}}`;
3533
3610
  }
3534
- function buildStitchApiHeader({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR }) {
3611
+ function buildStitchApiHeader({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, apiKey = null, }) {
3612
+ const normalizedApiKey = normalizePostmanApiKey(apiKey);
3613
+ if (normalizedApiKey) {
3614
+ return `X-Goog-Api-Key: ${normalizedApiKey}`;
3615
+ }
3535
3616
  return `X-Goog-Api-Key: \${${apiKeyEnvVar}}`;
3536
3617
  }
3537
- function buildPostmanMcpDefinition({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, mcpUrl = POSTMAN_MCP_URL, }) {
3618
+ function buildPostmanMcpDefinition({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, mcpUrl = POSTMAN_MCP_URL, }) {
3538
3619
  return {
3539
3620
  schemaVersion: 1,
3540
3621
  server: POSTMAN_SKILL_ID,
3541
3622
  transport: "http",
3542
3623
  url: mcpUrl,
3543
3624
  headers: {
3544
- Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
3625
+ Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
3545
3626
  },
3546
3627
  };
3547
3628
  }
3548
- function buildStitchMcpDefinition({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, mcpUrl = STITCH_MCP_URL, }) {
3629
+ function buildStitchMcpDefinition({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, apiKey = null, mcpUrl = STITCH_MCP_URL, }) {
3549
3630
  return {
3550
3631
  schemaVersion: 1,
3551
3632
  server: STITCH_MCP_SERVER_ID,
@@ -3556,17 +3637,17 @@ function buildStitchMcpDefinition({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, mcpUr
3556
3637
  "mcp-remote",
3557
3638
  mcpUrl,
3558
3639
  "--header",
3559
- buildStitchApiHeader({ apiKeyEnvVar }),
3640
+ buildStitchApiHeader({ apiKeyEnvVar, apiKey }),
3560
3641
  ],
3561
3642
  env: {},
3562
3643
  };
3563
3644
  }
3564
- function buildVsCodePostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, mcpUrl = POSTMAN_MCP_URL, }) {
3645
+ function buildVsCodePostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, mcpUrl = POSTMAN_MCP_URL, }) {
3565
3646
  return {
3566
3647
  type: "sse",
3567
3648
  url: mcpUrl,
3568
3649
  headers: {
3569
- Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
3650
+ Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
3570
3651
  },
3571
3652
  };
3572
3653
  }
@@ -3584,12 +3665,12 @@ function buildVsCodeFoundryServer({ scope = "auto" } = {}) {
3584
3665
  env: {},
3585
3666
  };
3586
3667
  }
3587
- function buildCopilotCliPostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, mcpUrl = POSTMAN_MCP_URL, }) {
3668
+ function buildCopilotCliPostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, mcpUrl = POSTMAN_MCP_URL, }) {
3588
3669
  return {
3589
3670
  type: "http",
3590
3671
  url: mcpUrl,
3591
3672
  headers: {
3592
- Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
3673
+ Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
3593
3674
  },
3594
3675
  tools: ["*"],
3595
3676
  };
@@ -3603,11 +3684,11 @@ function buildCopilotCliFoundryServer({ scope = "auto" } = {}) {
3603
3684
  tools: ["*"],
3604
3685
  };
3605
3686
  }
3606
- function buildGeminiPostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, mcpUrl = POSTMAN_MCP_URL, }) {
3687
+ function buildGeminiPostmanServer({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, mcpUrl = POSTMAN_MCP_URL, }) {
3607
3688
  return {
3608
3689
  httpUrl: mcpUrl,
3609
3690
  headers: {
3610
- Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
3691
+ Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
3611
3692
  },
3612
3693
  };
3613
3694
  }
@@ -3618,7 +3699,7 @@ function buildGeminiFoundryServer({ scope = "auto" } = {}) {
3618
3699
  env: {},
3619
3700
  };
3620
3701
  }
3621
- function buildGeminiStitchServer({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, mcpUrl = STITCH_MCP_URL, }) {
3702
+ function buildGeminiStitchServer({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, apiKey = null, mcpUrl = STITCH_MCP_URL, }) {
3622
3703
  return {
3623
3704
  command: "npx",
3624
3705
  args: [
@@ -3626,7 +3707,7 @@ function buildGeminiStitchServer({ apiKeyEnvVar = STITCH_API_KEY_ENV_VAR, mcpUrl
3626
3707
  "mcp-remote",
3627
3708
  mcpUrl,
3628
3709
  "--header",
3629
- buildStitchApiHeader({ apiKeyEnvVar }),
3710
+ buildStitchApiHeader({ apiKeyEnvVar, apiKey }),
3630
3711
  ],
3631
3712
  env: {},
3632
3713
  };
@@ -4040,6 +4121,8 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4040
4121
  const workspaceRoot = findWorkspaceRoot(cwd);
4041
4122
  const warnings = [];
4042
4123
  const foundryScope = mcpScope === "global" ? "global" : "project";
4124
+ const resolvedPostmanApiKey = normalizePostmanApiKey(process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR]);
4125
+ const resolvedStitchApiKey = normalizePostmanApiKey(process.env[stitchApiKeyEnvVar || STITCH_API_KEY_ENV_VAR]);
4043
4126
  if (platform === "antigravity") {
4044
4127
  const settingsPath = mcpScope === "global"
4045
4128
  ? path.join(os.homedir(), ".gemini", "settings.json")
@@ -4056,6 +4139,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4056
4139
  if (includePostmanMcp) {
4057
4140
  mcpServers[POSTMAN_SKILL_ID] = buildGeminiPostmanServer({
4058
4141
  apiKeyEnvVar,
4142
+ apiKey: resolvedPostmanApiKey,
4059
4143
  mcpUrl,
4060
4144
  });
4061
4145
  }
@@ -4070,6 +4154,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4070
4154
  if (includeStitchMcp) {
4071
4155
  mcpServers[STITCH_MCP_SERVER_ID] = buildGeminiStitchServer({
4072
4156
  apiKeyEnvVar: stitchApiKeyEnvVar,
4157
+ apiKey: resolvedStitchApiKey,
4073
4158
  mcpUrl: stitchMcpUrl,
4074
4159
  });
4075
4160
  }
@@ -4103,6 +4188,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4103
4188
  if (includePostmanMcp) {
4104
4189
  mcpServers[POSTMAN_SKILL_ID] = buildCopilotCliPostmanServer({
4105
4190
  apiKeyEnvVar,
4191
+ apiKey: resolvedPostmanApiKey,
4106
4192
  mcpUrl,
4107
4193
  });
4108
4194
  }
@@ -4125,6 +4211,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4125
4211
  if (includePostmanMcp) {
4126
4212
  servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
4127
4213
  apiKeyEnvVar,
4214
+ apiKey: resolvedPostmanApiKey,
4128
4215
  mcpUrl,
4129
4216
  });
4130
4217
  }
@@ -4164,6 +4251,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4164
4251
  if (includePostmanMcp) {
4165
4252
  servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
4166
4253
  apiKeyEnvVar,
4254
+ apiKey: resolvedPostmanApiKey,
4167
4255
  mcpUrl,
4168
4256
  });
4169
4257
  }
@@ -4223,6 +4311,19 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4223
4311
  "--bearer-token-env-var",
4224
4312
  apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR,
4225
4313
  ], { cwd });
4314
+ const postmanToken = normalizePostmanApiKey(process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR]);
4315
+ const postmanPatch = await patchCodexPostmanHttpHeaders({
4316
+ configPath: codexConfigPath,
4317
+ mcpUrl,
4318
+ bearerToken: postmanToken,
4319
+ dryRun: false,
4320
+ });
4321
+ if (postmanPatch.action === "patched") {
4322
+ warnings.push("Codex Postman MCP config patched to static Authorization header for startup reliability.");
4323
+ }
4324
+ if (postmanPatch.warnings?.length) {
4325
+ warnings.push(...postmanPatch.warnings);
4326
+ }
4226
4327
  }
4227
4328
  catch (error) {
4228
4329
  warnings.push(`Failed to register Postman MCP via Codex CLI. Ensure 'codex' is installed and rerun. (${error.message})`);
@@ -4627,6 +4728,7 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
4627
4728
  });
4628
4729
  const mcpDefinitionContent = `${JSON.stringify(buildPostmanMcpDefinition({
4629
4730
  apiKeyEnvVar: effectiveApiKeyEnvVar,
4731
+ apiKey: envApiKey,
4630
4732
  mcpUrl: effectiveMcpUrl,
4631
4733
  }), null, 2)}\n`;
4632
4734
  mcpDefinitionResult = await writeGeneratedArtifact({
@@ -4644,6 +4746,7 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
4644
4746
  });
4645
4747
  const stitchMcpDefinitionContent = `${JSON.stringify(buildStitchMcpDefinition({
4646
4748
  apiKeyEnvVar: effectiveStitchApiKeyEnvVar,
4749
+ apiKey: envStitchApiKey,
4647
4750
  mcpUrl: effectiveStitchMcpUrl,
4648
4751
  }), null, 2)}\n`;
4649
4752
  stitchMcpDefinitionResult = await writeGeneratedArtifact({
@@ -4758,6 +4861,8 @@ async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dr
4758
4861
  const stitchEnabled = Boolean(stitchState);
4759
4862
  const stitchApiKeyEnvVar = normalizePostmanApiKey(stitchState?.apiKeyEnvVar) || STITCH_API_KEY_ENV_VAR;
4760
4863
  const stitchMcpUrl = stitchState?.mcpUrl || STITCH_MCP_URL;
4864
+ const resolvedPostmanApiKey = normalizePostmanApiKey(process.env[postmanApiKeyEnvVar]);
4865
+ const resolvedStitchApiKey = normalizePostmanApiKey(process.env[stitchApiKeyEnvVar]);
4761
4866
  const mcpDefinitionPath = resolvePostmanMcpDefinitionPath({
4762
4867
  platform,
4763
4868
  scope: mcpScope,
@@ -4765,6 +4870,7 @@ async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dr
4765
4870
  });
4766
4871
  const mcpDefinitionContent = `${JSON.stringify(buildPostmanMcpDefinition({
4767
4872
  apiKeyEnvVar: postmanApiKeyEnvVar,
4873
+ apiKey: resolvedPostmanApiKey,
4768
4874
  mcpUrl: postmanMcpUrl,
4769
4875
  }), null, 2)}\n`;
4770
4876
  const mcpDefinitionResult = await writeGeneratedArtifact({
@@ -4781,6 +4887,7 @@ async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dr
4781
4887
  });
4782
4888
  const stitchMcpDefinitionContent = `${JSON.stringify(buildStitchMcpDefinition({
4783
4889
  apiKeyEnvVar: stitchApiKeyEnvVar,
4890
+ apiKey: resolvedStitchApiKey,
4784
4891
  mcpUrl: stitchMcpUrl,
4785
4892
  }), null, 2)}\n`;
4786
4893
  stitchMcpDefinitionResult = await writeGeneratedArtifact({