@cognium-ai/mcp-server 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -68,6 +68,11 @@ spec.
68
68
  > The engine has no native "partial" state; it is a boundary heuristic at
69
69
  > confidence 0.7 over the engine's already-filtered match set
70
70
  > (min confidence 0.3).
71
+ >
72
+ > **Empty spec:** if no requirements parse from `spec_dir` (missing, empty, or
73
+ > malformed `spec.md`), `alignment_score` is reported as **0** with an
74
+ > explanatory `summary` — never a misleading 100 — so a `>= N` gate fails
75
+ > safely instead of passing on a spec that was never read.
71
76
 
72
77
  ### `find_spec_drift`
73
78
 
@@ -107,14 +112,20 @@ Search file contents under a code root with a JavaScript regular expression.
107
112
  ```jsonc
108
113
  {
109
114
  "matches": [
110
- { "file": "src/cart.ts", "span": [3, 3], "snippet": "return price * quantity;" }
115
+ { "file": "src/cart.ts", "span": [7, 7], "snippet": "return unitPrice * quantity;" }
111
116
  ]
112
117
  }
113
118
  ```
114
119
 
115
120
  > `span` is **line-based** `[startLine, endLine]` (1-based), **not** character
116
- > offsets. Binary/large files (> 1 MiB) and common build/vendor directories are
117
- > skipped; results are capped at 1000 matches.
121
+ > offsets. Files larger than 1 MiB, files detected as binary (NUL byte in the
122
+ > leading window), and common build/vendor directories are skipped; results are
123
+ > capped at 1000 matches.
124
+ >
125
+ > The pattern is validated once up front (an invalid regex errors even over an
126
+ > empty tree). A 2 s wall-clock budget bounds total scanning between matches;
127
+ > it does not interrupt a single `exec`, so the 1 MiB per-file cap is the real
128
+ > bound against a catastrophic-backtracking pattern.
118
129
 
119
130
  ## Field mapping (engine → MCP boundary)
120
131
 
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,2EAA2E;AAC3E,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,SAAS,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAElE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,uBAAuB,CA6BlF;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,mBAAmB,CAqBtE"}
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,2EAA2E;AAC3E,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,SAAS,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAElE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,uBAAuB,CA2ClF;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,mBAAmB,CAqBtE"}
package/dist/mappers.js CHANGED
@@ -10,6 +10,18 @@
10
10
  export const PARTIAL_CONFIDENCE_THRESHOLD = 0.7;
11
11
  /** Map a `SpecGapResult` to the `verify_spec_conformance` output shape. */
12
12
  export function toVerifyConformance(result) {
13
+ // Empty-spec guard: the engine returns specAlignmentScore=100 when zero
14
+ // requirements parse from spec_dir (a missing/empty/malformed spec). A
15
+ // consumer gating on `alignment_score >= N` would treat that as a pass.
16
+ // Surface it as a non-passing 0 with an explicit summary instead.
17
+ if (result.summary.totalRequirements === 0) {
18
+ return {
19
+ alignment_score: 0,
20
+ requirements: [],
21
+ summary: 'No requirements parsed from spec_dir — check the path and that ' +
22
+ 'spec.md uses "- REQ-NNN: ..." bullets.',
23
+ };
24
+ }
13
25
  const requirements = [];
14
26
  for (const match of result.coveredRequirements) {
15
27
  requirements.push({
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.js","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAkChD,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACvD,MAAM,YAAY,GAAwB,EAAE,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAC/C,YAAY,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE;YACxB,MAAM,EAAE,KAAK,CAAC,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAChF,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,eAAe,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,EAAE;YAC5B,MAAM,EAAE,WAAW;YACnB,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IACrF,MAAM,OAAO,GACX,GAAG,OAAO,IAAI,iBAAiB,0BAA0B,eAAe,MAAM;QAC9E,GAAG,YAAY,yBAAyB,CAAC;IAE3C,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,kBAAkB;QAC1C,YAAY;QACZ,OAAO;KACR,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,MAAqB;IAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,QAAQ,CAAC,YAAY;YAC/B,gBAAgB,EAAE,QAAQ,CAAC,UAAU;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACrD,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,WAAW,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,EAAE;YACZ,gBAAgB,EAAE,SAAS,CAAC,MAAM,IAAI,aAAa,EAAE,KAAK,WAAW,EAAE;SACxE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"mappers.js","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAkChD,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACvD,wEAAwE;IACxE,uEAAuE;IACvE,wEAAwE;IACxE,kEAAkE;IAClE,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO;YACL,eAAe,EAAE,CAAC;YAClB,YAAY,EAAE,EAAE;YAChB,OAAO,EACL,iEAAiE;gBACjE,wCAAwC;SAC3C,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAwB,EAAE,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAC/C,YAAY,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE;YACxB,MAAM,EAAE,KAAK,CAAC,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAChF,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,eAAe,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,EAAE;YAC5B,MAAM,EAAE,WAAW;YACnB,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IACrF,MAAM,OAAO,GACX,GAAG,OAAO,IAAI,iBAAiB,0BAA0B,eAAe,MAAM;QAC9E,GAAG,YAAY,yBAAyB,CAAC;IAE3C,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,kBAAkB;QAC1C,YAAY;QACZ,OAAO;KACR,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,MAAqB;IAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,QAAQ,CAAC,YAAY;YAC/B,gBAAgB,EAAE,QAAQ,CAAC,UAAU;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACrD,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,WAAW,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,EAAE;YACZ,gBAAgB,EAAE,SAAS,CAAC,MAAM,IAAI,aAAa,EAAE,KAAK,WAAW,EAAE;SACxE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,WAAW,IAAI,SAAS,CAWvC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,WAAW,IAAI,SAAS,CAYvC"}
package/dist/server.js CHANGED
@@ -5,14 +5,16 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { registerVerifySpecConformance } from './tools/verify-spec-conformance.js';
6
6
  import { registerFindSpecDrift } from './tools/find-spec-drift.js';
7
7
  import { registerFindPattern } from './tools/find-pattern.js';
8
+ import { registerFindCredentialExposure } from './tools/find-credential-exposure.js';
8
9
  export function buildServer() {
9
10
  const server = new McpServer({
10
11
  name: 'cognium-mcp',
11
- version: '0.1.0',
12
+ version: '0.2.0',
12
13
  });
13
14
  registerVerifySpecConformance(server);
14
15
  registerFindSpecDrift(server);
15
16
  registerFindPattern(server);
17
+ registerFindCredentialExposure(server);
16
18
  return server;
17
19
  }
18
20
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAEvC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `find_credential_exposure` MCP tool (Pillar I, Workflow #1).
3
+ *
4
+ * Scans a code root for hardcoded credentials (API keys, tokens, passwords,
5
+ * private keys) using circle-ir's ScanSecretsPass for SAST detection and
6
+ * circle-ir-ai's secret scanner for git history scanning.
7
+ *
8
+ * Architecture:
9
+ * - SAST detection: Delegated to circle-ir's ScanSecretsPass (no duplication)
10
+ * - Git history: circle-ir-ai scans commits (cross-commit analysis)
11
+ * - Output: Common Pillar I findings envelope for cognium-code integration
12
+ *
13
+ * @see https://github.com/cogniumhq/cognium-ai/issues/78
14
+ */
15
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
16
+ export declare function registerFindCredentialExposure(server: McpServer): void;
17
+ //# sourceMappingURL=find-credential-exposure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-credential-exposure.d.ts","sourceRoot":"","sources":["../../src/tools/find-credential-exposure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuJzE,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4DtE"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * `find_credential_exposure` MCP tool (Pillar I, Workflow #1).
3
+ *
4
+ * Scans a code root for hardcoded credentials (API keys, tokens, passwords,
5
+ * private keys) using circle-ir's ScanSecretsPass for SAST detection and
6
+ * circle-ir-ai's secret scanner for git history scanning.
7
+ *
8
+ * Architecture:
9
+ * - SAST detection: Delegated to circle-ir's ScanSecretsPass (no duplication)
10
+ * - Git history: circle-ir-ai scans commits (cross-commit analysis)
11
+ * - Output: Common Pillar I findings envelope for cognium-code integration
12
+ *
13
+ * @see https://github.com/cogniumhq/cognium-ai/issues/78
14
+ */
15
+ import { z } from 'zod';
16
+ import { scanForSecrets } from 'circle-ir-ai';
17
+ /** Hard cap on findings returned. */
18
+ const MAX_FINDINGS = 500;
19
+ const inputSchema = {
20
+ code_root: z.string().describe('Absolute path to the code root to scan'),
21
+ include_git_history: z.boolean().optional().default(false).describe('Scan git history for secrets (default: false)'),
22
+ severity_floor: z.enum(['info', 'low', 'medium', 'high', 'critical']).optional().default('low').describe('Minimum severity to report (default: low)'),
23
+ };
24
+ const findingSchema = z.object({
25
+ kind: z.literal('CREDENTIAL_EXPOSURE'),
26
+ severity: z.enum(['low', 'medium', 'high', 'critical']),
27
+ location: z.object({
28
+ file: z.string(),
29
+ span: z.tuple([z.number(), z.number()]),
30
+ }),
31
+ evidence: z.object({
32
+ rule_id: z.string(),
33
+ match_snippet: z.string(),
34
+ confidence: z.number(),
35
+ }),
36
+ suggested_action: z.string(),
37
+ });
38
+ const outputSchema = {
39
+ findings: z.array(findingSchema),
40
+ summary: z.object({
41
+ total: z.number(),
42
+ by_severity: z.object({
43
+ critical: z.number(),
44
+ high: z.number(),
45
+ medium: z.number(),
46
+ low: z.number(),
47
+ }),
48
+ truncated: z.boolean(),
49
+ }),
50
+ };
51
+ /**
52
+ * Map severity to suggested action
53
+ */
54
+ function getSuggestedAction(secret) {
55
+ const category = secret.category.toLowerCase();
56
+ const isActive = secret.presentInHead;
57
+ if (!isActive) {
58
+ return 'Secret found in git history only. Consider rotating and cleaning history with git-filter-repo or BFG.';
59
+ }
60
+ switch (category) {
61
+ case 'aws':
62
+ return 'Rotate the AWS access key immediately via IAM console and move to AWS Secrets Manager or environment variables.';
63
+ case 'github':
64
+ return 'Revoke the token at https://github.com/settings/tokens and use GITHUB_TOKEN or repository secrets instead.';
65
+ case 'openai':
66
+ return 'Revoke the key at https://platform.openai.com/api-keys and load from environment variables.';
67
+ case 'anthropic':
68
+ return 'Revoke the key in the Anthropic Console and load from environment variables.';
69
+ case 'stripe':
70
+ return 'Rotate in the Stripe Dashboard and use environment variables or a secrets manager.';
71
+ case 'slack':
72
+ return 'Revoke the token in Slack workspace settings and use environment variables.';
73
+ case 'gcp':
74
+ return 'Restrict or revoke in Google Cloud Console and use service account keys or Workload Identity.';
75
+ case 'private-key':
76
+ return 'Remove immediately, rotate the keypair, and never commit private keys to source control.';
77
+ case 'jwt':
78
+ return 'JWTs carry whatever scope they were minted with. Rotate signing keys and remove the token.';
79
+ case 'npm':
80
+ return 'Revoke at https://www.npmjs.com/settings/<user>/tokens and use NPM_TOKEN environment variable.';
81
+ case 'high-entropy':
82
+ return 'If this is a credential, move to environment variables or a secrets manager. If sample data, add to .gitignore.';
83
+ default:
84
+ return 'Rotate this credential immediately and move to environment variables or a secrets manager.';
85
+ }
86
+ }
87
+ /**
88
+ * Map severity order for filtering
89
+ */
90
+ const SEVERITY_ORDER = {
91
+ info: 0,
92
+ low: 1,
93
+ medium: 2,
94
+ high: 3,
95
+ critical: 4,
96
+ };
97
+ /**
98
+ * Convert DetectedSecret to CredentialFinding
99
+ */
100
+ function secretToFinding(secret, codeRoot) {
101
+ // Make file path relative to code_root
102
+ let relativePath = secret.file;
103
+ if (relativePath.startsWith(codeRoot)) {
104
+ relativePath = relativePath.slice(codeRoot.length);
105
+ if (relativePath.startsWith('/')) {
106
+ relativePath = relativePath.slice(1);
107
+ }
108
+ }
109
+ return {
110
+ kind: 'CREDENTIAL_EXPOSURE',
111
+ severity: secret.severity === 'low' ? 'low' : secret.severity,
112
+ location: {
113
+ file: relativePath,
114
+ span: [secret.line, secret.line], // Single line span
115
+ },
116
+ evidence: {
117
+ rule_id: secret.patternId,
118
+ match_snippet: secret.match, // Already redacted by scanner
119
+ confidence: secret.llmConfidence ?? (secret.category === 'high-entropy' ? 0.7 : 0.95),
120
+ },
121
+ suggested_action: getSuggestedAction(secret),
122
+ };
123
+ }
124
+ export function registerFindCredentialExposure(server) {
125
+ server.registerTool('find_credential_exposure', {
126
+ title: 'Find Credential Exposure',
127
+ description: 'Scan a code root for hardcoded credentials (API keys, tokens, passwords, ' +
128
+ 'private keys). Uses SAST pattern matching and optional git history scanning. ' +
129
+ 'Returns findings with severity, location, and remediation guidance.',
130
+ inputSchema,
131
+ outputSchema,
132
+ }, async ({ code_root, include_git_history, severity_floor }) => {
133
+ // Map severity_floor to scanner's minSeverity
134
+ const minSeverity = severity_floor === 'info' ? undefined :
135
+ severity_floor === 'low' ? 'low' :
136
+ severity_floor === 'medium' ? 'medium' :
137
+ severity_floor === 'high' ? 'high' :
138
+ severity_floor === 'critical' ? 'critical' :
139
+ 'low';
140
+ const scanResult = await scanForSecrets(code_root, {
141
+ scanHistory: include_git_history,
142
+ minSeverity,
143
+ maxCommits: 100, // Reasonable limit for git history
144
+ });
145
+ // Filter by severity floor and convert to findings
146
+ const floorValue = SEVERITY_ORDER[severity_floor ?? 'low'];
147
+ const filteredSecrets = scanResult.secrets.filter((s) => SEVERITY_ORDER[s.severity] >= floorValue);
148
+ // Convert to findings format, respecting MAX_FINDINGS
149
+ const truncated = filteredSecrets.length > MAX_FINDINGS;
150
+ const findings = filteredSecrets
151
+ .slice(0, MAX_FINDINGS)
152
+ .map((s) => secretToFinding(s, code_root));
153
+ const result = {
154
+ findings,
155
+ summary: {
156
+ total: filteredSecrets.length,
157
+ by_severity: {
158
+ critical: filteredSecrets.filter((s) => s.severity === 'critical').length,
159
+ high: filteredSecrets.filter((s) => s.severity === 'high').length,
160
+ medium: filteredSecrets.filter((s) => s.severity === 'medium').length,
161
+ low: filteredSecrets.filter((s) => s.severity === 'low').length,
162
+ },
163
+ truncated,
164
+ },
165
+ };
166
+ return {
167
+ content: [{ type: 'text', text: JSON.stringify(result) }],
168
+ structuredContent: result,
169
+ };
170
+ });
171
+ }
172
+ //# sourceMappingURL=find-credential-exposure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-credential-exposure.js","sourceRoot":"","sources":["../../src/tools/find-credential-exposure.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"find-pattern.d.ts","sourceRoot":"","sources":["../../src/tools/find-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoCzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6D3D"}
1
+ {"version":3,"file":"find-pattern.d.ts","sourceRoot":"","sources":["../../src/tools/find-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqDzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsE3D"}
@@ -13,6 +13,16 @@ import { z } from 'zod';
13
13
  import { walkFiles } from '../walk.js';
14
14
  /** Hard cap on total matches returned across all files. */
15
15
  const MAX_MATCHES = 1000;
16
+ /**
17
+ * Wall-clock budget for the whole search, checked between regex `exec` calls
18
+ * (i.e. between matches and between files). A caller/LLM-supplied regex can
19
+ * trigger catastrophic backtracking; this bounds how long we keep scanning.
20
+ *
21
+ * It does NOT interrupt a single `exec` mid-flight — JS regex is synchronous
22
+ * and uninterruptible — so the per-file 1 MiB size cap in `walk.ts` is the
23
+ * real bound on the worst-case cost of one match attempt.
24
+ */
25
+ const TIME_BUDGET_MS = 2000;
16
26
  const inputSchema = {
17
27
  pattern: z.string().describe('JavaScript regular expression (applied with the global flag)'),
18
28
  code_root: z.string().describe('Path to the code root to search'),
@@ -33,6 +43,11 @@ function lineAt(text, end) {
33
43
  }
34
44
  return line;
35
45
  }
46
+ /** Heuristic binary detection: a NUL byte in the leading window. */
47
+ function looksBinary(content) {
48
+ const window = content.length < 8192 ? content : content.slice(0, 8192);
49
+ return window.includes('\u0000');
50
+ }
36
51
  export function registerFindPattern(server) {
37
52
  server.registerTool('find_pattern', {
38
53
  title: 'Find Pattern',
@@ -42,10 +57,20 @@ export function registerFindPattern(server) {
42
57
  inputSchema,
43
58
  outputSchema,
44
59
  }, async ({ pattern, code_root }) => {
60
+ // Validate the pattern once, up front — fail fast even when the code
61
+ // root contains no files (the old per-file compile silently returned
62
+ // an empty result for an invalid regex over an empty tree).
63
+ try {
64
+ new RegExp(pattern, 'g');
65
+ }
66
+ catch (err) {
67
+ throw new Error(`Invalid regular expression: ${err.message}`);
68
+ }
45
69
  const matches = [];
46
70
  const files = walkFiles(code_root);
71
+ const deadline = Date.now() + TIME_BUDGET_MS;
47
72
  for (const file of files) {
48
- if (matches.length >= MAX_MATCHES)
73
+ if (matches.length >= MAX_MATCHES || Date.now() > deadline)
49
74
  break;
50
75
  let content;
51
76
  try {
@@ -54,14 +79,12 @@ export function registerFindPattern(server) {
54
79
  catch {
55
80
  continue;
56
81
  }
82
+ // Skip binaries: the size cap alone lets sub-1-MiB binaries through,
83
+ // and reading them as UTF-8 yields garbage matches.
84
+ if (looksBinary(content))
85
+ continue;
57
86
  // Fresh regex per file so lastIndex state never leaks across files.
58
- let re;
59
- try {
60
- re = new RegExp(pattern, 'g');
61
- }
62
- catch (err) {
63
- throw new Error(`Invalid regular expression: ${err.message}`);
64
- }
87
+ const re = new RegExp(pattern, 'g');
65
88
  let m;
66
89
  while ((m = re.exec(content)) !== null) {
67
90
  const startLine = lineAt(content, m.index);
@@ -74,7 +97,7 @@ export function registerFindPattern(server) {
74
97
  span: [startLine, endLine],
75
98
  snippet,
76
99
  });
77
- if (matches.length >= MAX_MATCHES)
100
+ if (matches.length >= MAX_MATCHES || Date.now() > deadline)
78
101
  break;
79
102
  // Guard against zero-width matches looping forever.
80
103
  if (m.index === re.lastIndex)
@@ -1 +1 @@
1
- {"version":3,"file":"find-pattern.js","sourceRoot":"","sources":["../../src/tools/find-pattern.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find-pattern.js","sourceRoot":"","sources":["../../src/tools/find-pattern.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cognium-ai/mcp-server",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server exposing Cognium spec-conformance, spec-drift, and pattern-search tools over stdio",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "@modelcontextprotocol/sdk": "^1.29.0",
48
48
  "circle-ir": "^3.23.3",
49
- "circle-ir-ai": "^2.7.19",
49
+ "circle-ir-ai": "^2.8.0",
50
50
  "minimatch": "^10.2.5",
51
51
  "zod": "^3.25.0"
52
52
  },