@nimblebrain/mpak-sdk
Advanced tools
+51
-13
@@ -1058,5 +1058,14 @@ "use strict"; | ||
| * 2. stored `config.json` value — from `MpakConfigManager` | ||
| * 3. `default` from the manifest | ||
| * 4. missing required → collected and thrown as `MpakConfigError` | ||
| * 3. host process env via manifest-declared alias — see {@link envAliasesForField} | ||
| * 4. `default` from the manifest | ||
| * 5. missing required → collected and thrown as `MpakConfigError` | ||
| * | ||
| * Tier 3 (env alias) reads the bundle's existing `server.mcp_config.env` | ||
| * declaration in reverse. A bundle that maps a field to a spawn env var, | ||
| * e.g. `"NEWSAPI_API_KEY": "${user_config.api_key}"`, implicitly says | ||
| * "the `api_key` field is about the NEWSAPI_API_KEY env var." At resolve | ||
| * time we honor that: if the host process has NEWSAPI_API_KEY set | ||
| * (non-empty), its value satisfies the field. No new schema field, no | ||
| * host-specific convention — the mapping is already declared. | ||
| * | ||
| * @param overrides Optional pre-resolved values that take precedence over stored config. | ||
@@ -1071,2 +1080,3 @@ * An empty object is treated the same as omitting the argument. | ||
| const storedConfig = this.configManager.getPackageConfig(packageName) ?? {}; | ||
| const envAliases = buildEnvAliasMap(manifest); | ||
| const result = {}; | ||
@@ -1081,14 +1091,26 @@ const missingFields = []; | ||
| result[fieldName] = storedValue; | ||
| } else if (fieldData.default !== void 0 && fieldData.default !== null) { | ||
| result[fieldName] = String(fieldData.default); | ||
| } else if (fieldData.required) { | ||
| const field = { | ||
| key: fieldName, | ||
| title: fieldData.title ?? fieldName, | ||
| sensitive: fieldData.sensitive ?? false | ||
| }; | ||
| if (fieldData.description !== void 0) { | ||
| field.description = fieldData.description; | ||
| } else { | ||
| let envValue; | ||
| for (const envVar of envAliases.get(fieldName) ?? []) { | ||
| const v = process.env[envVar]; | ||
| if (typeof v === "string" && v.length > 0) { | ||
| envValue = v; | ||
| break; | ||
| } | ||
| } | ||
| missingFields.push(field); | ||
| if (envValue !== void 0) { | ||
| result[fieldName] = envValue; | ||
| } else if (fieldData.default !== void 0 && fieldData.default !== null) { | ||
| result[fieldName] = String(fieldData.default); | ||
| } else if (fieldData.required) { | ||
| const field = { | ||
| key: fieldName, | ||
| title: fieldData.title ?? fieldName, | ||
| sensitive: fieldData.sensitive ?? false | ||
| }; | ||
| if (fieldData.description !== void 0) { | ||
| field.description = fieldData.description; | ||
| } | ||
| missingFields.push(field); | ||
| } | ||
| } | ||
@@ -1189,2 +1211,18 @@ } | ||
| }; | ||
| function buildEnvAliasMap(manifest) { | ||
| const map = /* @__PURE__ */ new Map(); | ||
| const entries = manifest.server?.mcp_config?.env; | ||
| if (!entries) return map; | ||
| const wholeSubstitution = /^\$\{user_config\.([A-Za-z_][A-Za-z0-9_]*)\}$/; | ||
| for (const [envVar, template] of Object.entries(entries)) { | ||
| if (typeof template !== "string") continue; | ||
| const match = wholeSubstitution.exec(template); | ||
| if (!match) continue; | ||
| const fieldName = match[1]; | ||
| const existing = map.get(fieldName); | ||
| if (existing) existing.push(envVar); | ||
| else map.set(fieldName, [envVar]); | ||
| } | ||
| return map; | ||
| } | ||
@@ -1191,0 +1229,0 @@ // src/utils.ts |
+11
-2
@@ -502,5 +502,14 @@ import { BundleSearchParamsInput, BundleSearchResponse, BundleDetail, VersionsResponse, VersionDetail, PlatformInfo, DownloadInfo, SkillSearchParamsInput, SkillSearchResponse, SkillDetail, SkillDownloadInfo, CacheMetadata, McpbManifest, CachedBundleInfo } from '@nimblebrain/mpak-schemas'; | ||
| * 2. stored `config.json` value — from `MpakConfigManager` | ||
| * 3. `default` from the manifest | ||
| * 4. missing required → collected and thrown as `MpakConfigError` | ||
| * 3. host process env via manifest-declared alias — see {@link envAliasesForField} | ||
| * 4. `default` from the manifest | ||
| * 5. missing required → collected and thrown as `MpakConfigError` | ||
| * | ||
| * Tier 3 (env alias) reads the bundle's existing `server.mcp_config.env` | ||
| * declaration in reverse. A bundle that maps a field to a spawn env var, | ||
| * e.g. `"NEWSAPI_API_KEY": "${user_config.api_key}"`, implicitly says | ||
| * "the `api_key` field is about the NEWSAPI_API_KEY env var." At resolve | ||
| * time we honor that: if the host process has NEWSAPI_API_KEY set | ||
| * (non-empty), its value satisfies the field. No new schema field, no | ||
| * host-specific convention — the mapping is already declared. | ||
| * | ||
| * @param overrides Optional pre-resolved values that take precedence over stored config. | ||
@@ -507,0 +516,0 @@ * An empty object is treated the same as omitting the argument. |
+11
-2
@@ -502,5 +502,14 @@ import { BundleSearchParamsInput, BundleSearchResponse, BundleDetail, VersionsResponse, VersionDetail, PlatformInfo, DownloadInfo, SkillSearchParamsInput, SkillSearchResponse, SkillDetail, SkillDownloadInfo, CacheMetadata, McpbManifest, CachedBundleInfo } from '@nimblebrain/mpak-schemas'; | ||
| * 2. stored `config.json` value — from `MpakConfigManager` | ||
| * 3. `default` from the manifest | ||
| * 4. missing required → collected and thrown as `MpakConfigError` | ||
| * 3. host process env via manifest-declared alias — see {@link envAliasesForField} | ||
| * 4. `default` from the manifest | ||
| * 5. missing required → collected and thrown as `MpakConfigError` | ||
| * | ||
| * Tier 3 (env alias) reads the bundle's existing `server.mcp_config.env` | ||
| * declaration in reverse. A bundle that maps a field to a spawn env var, | ||
| * e.g. `"NEWSAPI_API_KEY": "${user_config.api_key}"`, implicitly says | ||
| * "the `api_key` field is about the NEWSAPI_API_KEY env var." At resolve | ||
| * time we honor that: if the host process has NEWSAPI_API_KEY set | ||
| * (non-empty), its value satisfies the field. No new schema field, no | ||
| * host-specific convention — the mapping is already declared. | ||
| * | ||
| * @param overrides Optional pre-resolved values that take precedence over stored config. | ||
@@ -507,0 +516,0 @@ * An empty object is treated the same as omitting the argument. |
+51
-13
@@ -1020,5 +1020,14 @@ // src/mpakSDK.ts | ||
| * 2. stored `config.json` value — from `MpakConfigManager` | ||
| * 3. `default` from the manifest | ||
| * 4. missing required → collected and thrown as `MpakConfigError` | ||
| * 3. host process env via manifest-declared alias — see {@link envAliasesForField} | ||
| * 4. `default` from the manifest | ||
| * 5. missing required → collected and thrown as `MpakConfigError` | ||
| * | ||
| * Tier 3 (env alias) reads the bundle's existing `server.mcp_config.env` | ||
| * declaration in reverse. A bundle that maps a field to a spawn env var, | ||
| * e.g. `"NEWSAPI_API_KEY": "${user_config.api_key}"`, implicitly says | ||
| * "the `api_key` field is about the NEWSAPI_API_KEY env var." At resolve | ||
| * time we honor that: if the host process has NEWSAPI_API_KEY set | ||
| * (non-empty), its value satisfies the field. No new schema field, no | ||
| * host-specific convention — the mapping is already declared. | ||
| * | ||
| * @param overrides Optional pre-resolved values that take precedence over stored config. | ||
@@ -1033,2 +1042,3 @@ * An empty object is treated the same as omitting the argument. | ||
| const storedConfig = this.configManager.getPackageConfig(packageName) ?? {}; | ||
| const envAliases = buildEnvAliasMap(manifest); | ||
| const result = {}; | ||
@@ -1043,14 +1053,26 @@ const missingFields = []; | ||
| result[fieldName] = storedValue; | ||
| } else if (fieldData.default !== void 0 && fieldData.default !== null) { | ||
| result[fieldName] = String(fieldData.default); | ||
| } else if (fieldData.required) { | ||
| const field = { | ||
| key: fieldName, | ||
| title: fieldData.title ?? fieldName, | ||
| sensitive: fieldData.sensitive ?? false | ||
| }; | ||
| if (fieldData.description !== void 0) { | ||
| field.description = fieldData.description; | ||
| } else { | ||
| let envValue; | ||
| for (const envVar of envAliases.get(fieldName) ?? []) { | ||
| const v = process.env[envVar]; | ||
| if (typeof v === "string" && v.length > 0) { | ||
| envValue = v; | ||
| break; | ||
| } | ||
| } | ||
| missingFields.push(field); | ||
| if (envValue !== void 0) { | ||
| result[fieldName] = envValue; | ||
| } else if (fieldData.default !== void 0 && fieldData.default !== null) { | ||
| result[fieldName] = String(fieldData.default); | ||
| } else if (fieldData.required) { | ||
| const field = { | ||
| key: fieldName, | ||
| title: fieldData.title ?? fieldName, | ||
| sensitive: fieldData.sensitive ?? false | ||
| }; | ||
| if (fieldData.description !== void 0) { | ||
| field.description = fieldData.description; | ||
| } | ||
| missingFields.push(field); | ||
| } | ||
| } | ||
@@ -1151,2 +1173,18 @@ } | ||
| }; | ||
| function buildEnvAliasMap(manifest) { | ||
| const map = /* @__PURE__ */ new Map(); | ||
| const entries = manifest.server?.mcp_config?.env; | ||
| if (!entries) return map; | ||
| const wholeSubstitution = /^\$\{user_config\.([A-Za-z_][A-Za-z0-9_]*)\}$/; | ||
| for (const [envVar, template] of Object.entries(entries)) { | ||
| if (typeof template !== "string") continue; | ||
| const match = wholeSubstitution.exec(template); | ||
| if (!match) continue; | ||
| const fieldName = match[1]; | ||
| const existing = map.get(fieldName); | ||
| if (existing) existing.push(envVar); | ||
| else map.set(fieldName, [envVar]); | ||
| } | ||
| return map; | ||
| } | ||
@@ -1153,0 +1191,0 @@ // src/utils.ts |
+1
-1
| { | ||
| "name": "@nimblebrain/mpak-sdk", | ||
| "version": "0.3.0", | ||
| "version": "0.4.0", | ||
| "description": "TypeScript SDK for mpak registry - MCPB bundles and Agent Skills", | ||
@@ -5,0 +5,0 @@ "author": "NimbleBrain Inc <engineering@mpak.dev>", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
325992
3.74%3104
2.82%11
22.22%