@kaddo/mcp 3.126.1 → 3.128.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.
Files changed (2) hide show
  1. package/dist/index.js +124 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2619,6 +2619,29 @@ var RESOURCE_TYPES = [
2619
2619
  "other"
2620
2620
  ];
2621
2621
  var INTERFACE_TYPES = ["cli", "mcp", "api", "sql", "sdk", "iac", "console", "other"];
2622
+ var REDACTED_COORDINATE = "\u2022\u2022\u2022\u2022 (hidden \u2014 store as an authentication reference)";
2623
+ var SECRET_KEY_RE = /(pass(word|phrase)?|secret|token|api[_-]?key|\bkey\b|credential|private|auth[_-]?token|access[_-]?key)/i;
2624
+ var SECRET_VALUE_PATTERNS = [
2625
+ /\b(AKIA|ASIA)[A-Z0-9]{8,}/,
2626
+ // AWS access key id
2627
+ /\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/,
2628
+ // GitHub tokens
2629
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}/,
2630
+ // Slack tokens
2631
+ /\bsk-[A-Za-z0-9]{16,}/,
2632
+ // OpenAI-style secret keys
2633
+ /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\./,
2634
+ // JWT
2635
+ /\w+=[^;\s]{6,}/,
2636
+ // key=value credential fragments
2637
+ /^[A-Za-z0-9+/]{40,}={0,2}$/
2638
+ // long opaque base64 blob
2639
+ ];
2640
+ function looksLikeSecretCoordinate(key, value) {
2641
+ if (SECRET_KEY_RE.test(key)) return true;
2642
+ const v = value.trim();
2643
+ return SECRET_VALUE_PATTERNS.some((re) => re.test(v));
2644
+ }
2622
2645
  function str(v) {
2623
2646
  return typeof v === "string" && v.trim() ? v.trim() : null;
2624
2647
  }
@@ -2647,6 +2670,29 @@ function parseInterfaces(v) {
2647
2670
  }
2648
2671
  return out;
2649
2672
  }
2673
+ function parseConnectionProfiles(v) {
2674
+ if (!Array.isArray(v)) return [];
2675
+ const out = [];
2676
+ for (const raw of v) {
2677
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
2678
+ const o2 = raw;
2679
+ const coords = [];
2680
+ const rawCoords = o2.coordinates;
2681
+ if (rawCoords && typeof rawCoords === "object" && !Array.isArray(rawCoords)) {
2682
+ for (const [key, val] of Object.entries(rawCoords)) {
2683
+ const k2 = key.trim();
2684
+ const value = val == null ? "" : String(val).trim();
2685
+ if (!k2 || !value) continue;
2686
+ coords.push({ key: k2, value: looksLikeSecretCoordinate(k2, value) ? REDACTED_COORDINATE : value });
2687
+ }
2688
+ }
2689
+ const environment = str(o2.environment);
2690
+ const iface = str(o2.interface);
2691
+ if (!environment && !iface && coords.length === 0) continue;
2692
+ out.push({ environment, interface: iface, coordinates: coords });
2693
+ }
2694
+ return out;
2695
+ }
2650
2696
  function parseBoundaries(v) {
2651
2697
  if (!v || typeof v !== "object" || Array.isArray(v)) return {};
2652
2698
  const out = {};
@@ -2695,6 +2741,7 @@ function toDetail(filePath, relPath, raw) {
2695
2741
  const a2 = parseAuth(fm.authentication);
2696
2742
  return { authRefs: a2.refs, authMode: a2.mode };
2697
2743
  })(),
2744
+ connectionProfiles: parseConnectionProfiles(fm.connection_profiles),
2698
2745
  markdownBody: body
2699
2746
  };
2700
2747
  }
@@ -13897,6 +13944,29 @@ function suggestInitiativesForExternalItem(dir, integration, externalId) {
13897
13944
  );
13898
13945
  }
13899
13946
  var RESOURCE_ARTIFACT_TYPE2 = "project-resource";
13947
+ var REDACTED_COORDINATE2 = "\u2022\u2022\u2022\u2022 (hidden \u2014 store as an authentication reference)";
13948
+ var SECRET_KEY_RE2 = /(pass(word|phrase)?|secret|token|api[_-]?key|\bkey\b|credential|private|auth[_-]?token|access[_-]?key)/i;
13949
+ var SECRET_VALUE_PATTERNS2 = [
13950
+ /\b(AKIA|ASIA)[A-Z0-9]{8,}/,
13951
+ // AWS access key id
13952
+ /\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/,
13953
+ // GitHub tokens
13954
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}/,
13955
+ // Slack tokens
13956
+ /\bsk-[A-Za-z0-9]{16,}/,
13957
+ // OpenAI-style secret keys
13958
+ /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\./,
13959
+ // JWT
13960
+ /\w+=[^;\s]{6,}/,
13961
+ // key=value credential fragments
13962
+ /^[A-Za-z0-9+/]{40,}={0,2}$/
13963
+ // long opaque base64 blob
13964
+ ];
13965
+ function looksLikeSecretCoordinate2(key, value) {
13966
+ if (SECRET_KEY_RE2.test(key)) return true;
13967
+ const v = value.trim();
13968
+ return SECRET_VALUE_PATTERNS2.some((re) => re.test(v));
13969
+ }
13900
13970
  function str3(v) {
13901
13971
  return typeof v === "string" && v.trim() ? v.trim() : null;
13902
13972
  }
@@ -13925,6 +13995,29 @@ function parseInterfaces2(v) {
13925
13995
  }
13926
13996
  return out;
13927
13997
  }
13998
+ function parseConnectionProfiles2(v) {
13999
+ if (!Array.isArray(v)) return [];
14000
+ const out = [];
14001
+ for (const raw of v) {
14002
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
14003
+ const o2 = raw;
14004
+ const coords = [];
14005
+ const rawCoords = o2.coordinates;
14006
+ if (rawCoords && typeof rawCoords === "object" && !Array.isArray(rawCoords)) {
14007
+ for (const [key, val] of Object.entries(rawCoords)) {
14008
+ const k2 = key.trim();
14009
+ const value = val == null ? "" : String(val).trim();
14010
+ if (!k2 || !value) continue;
14011
+ coords.push({ key: k2, value: looksLikeSecretCoordinate2(k2, value) ? REDACTED_COORDINATE2 : value });
14012
+ }
14013
+ }
14014
+ const environment = str3(o2.environment);
14015
+ const iface = str3(o2.interface);
14016
+ if (!environment && !iface && coords.length === 0) continue;
14017
+ out.push({ environment, interface: iface, coordinates: coords });
14018
+ }
14019
+ return out;
14020
+ }
13928
14021
  function parseBoundaries2(v) {
13929
14022
  if (!v || typeof v !== "object" || Array.isArray(v)) return {};
13930
14023
  const out = {};
@@ -13973,6 +14066,7 @@ function toDetail2(filePath, relPath, raw) {
13973
14066
  const a2 = parseAuth2(fm.authentication);
13974
14067
  return { authRefs: a2.refs, authMode: a2.mode };
13975
14068
  })(),
14069
+ connectionProfiles: parseConnectionProfiles2(fm.connection_profiles),
13976
14070
  markdownBody: body
13977
14071
  };
13978
14072
  }
@@ -21442,6 +21536,20 @@ function validateResource(dir, input) {
21442
21536
  findings.push({ level: "warning", message: `Unknown access interface type "${i.type}".` });
21443
21537
  }
21444
21538
  }
21539
+ for (const p of input.connectionProfiles ?? []) {
21540
+ const where = p.environment ? ` in environment "${p.environment}"` : "";
21541
+ for (const c of p.coordinates ?? []) {
21542
+ const key = (c?.key ?? "").trim();
21543
+ const value = (c?.value ?? "").trim();
21544
+ if (!key || !value) continue;
21545
+ if (looksLikeSecretCoordinate(key, value)) {
21546
+ findings.push({
21547
+ level: "error",
21548
+ message: `Connection coordinate "${key}"${where} looks like a secret value. Store credentials as authentication references, not connection coordinates.`
21549
+ });
21550
+ }
21551
+ }
21552
+ }
21445
21553
  const mapped = loadMappedModules(dir).map((m2) => m2.id);
21446
21554
  if (mapped.length > 0) {
21447
21555
  const refs = /* @__PURE__ */ new Set();
@@ -21468,6 +21576,22 @@ function buildFrontmatter(id, input, base = {}) {
21468
21576
  if (input.modules != null) data.modules = input.modules;
21469
21577
  if (input.accessInterfaces != null) data.access_interfaces = input.accessInterfaces;
21470
21578
  if (input.accessBoundaries != null) data.access_boundaries = input.accessBoundaries;
21579
+ if (input.connectionProfiles != null) {
21580
+ data.connection_profiles = input.connectionProfiles.map((p) => {
21581
+ const coordinates = {};
21582
+ for (const c of p.coordinates ?? []) {
21583
+ const key = (c?.key ?? "").trim();
21584
+ const value = (c?.value ?? "").trim();
21585
+ if (!key || !value || looksLikeSecretCoordinate(key, value)) continue;
21586
+ coordinates[key] = value;
21587
+ }
21588
+ const entry = {};
21589
+ if (p.environment?.trim()) entry.environment = p.environment.trim();
21590
+ if (p.interface?.trim()) entry.interface = p.interface.trim();
21591
+ if (Object.keys(coordinates).length) entry.coordinates = coordinates;
21592
+ return entry;
21593
+ }).filter((e) => Object.keys(e).length > 0);
21594
+ }
21471
21595
  if (input.authentication != null) {
21472
21596
  const mode = input.authentication.mode;
21473
21597
  const refs = sanitizeRefs(input.authentication.refs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.126.1",
3
+ "version": "3.128.0",
4
4
  "description": "MCP server for Kaddo project knowledge: read-only resources/tools/prompts plus safe derived generation under .kaddo/.",
5
5
  "license": "MIT",
6
6
  "repository": {