@cognium-ai/mcp-server 4.16.4 → 4.17.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 (67) hide show
  1. package/CHANGELOG.md +1820 -0
  2. package/README.md +27 -257
  3. package/dist/deprecation.d.ts +5 -0
  4. package/dist/deprecation.d.ts.map +1 -0
  5. package/dist/deprecation.js +7 -0
  6. package/dist/deprecation.js.map +1 -0
  7. package/dist/index.d.ts +18 -12
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +27 -19
  10. package/dist/index.js.map +1 -1
  11. package/dist/server.d.ts +15 -3
  12. package/dist/server.d.ts.map +1 -1
  13. package/dist/server.js +26 -31
  14. package/dist/server.js.map +1 -1
  15. package/package.json +6 -7
  16. package/dist/analysis.d.ts +0 -25
  17. package/dist/analysis.d.ts.map +0 -1
  18. package/dist/analysis.js +0 -45
  19. package/dist/analysis.js.map +0 -1
  20. package/dist/mappers.d.ts +0 -41
  21. package/dist/mappers.d.ts.map +0 -1
  22. package/dist/mappers.js +0 -69
  23. package/dist/mappers.js.map +0 -1
  24. package/dist/tools/check-license-compliance.d.ts +0 -11
  25. package/dist/tools/check-license-compliance.d.ts.map +0 -1
  26. package/dist/tools/check-license-compliance.js +0 -125
  27. package/dist/tools/check-license-compliance.js.map +0 -1
  28. package/dist/tools/find-credential-exposure.d.ts +0 -17
  29. package/dist/tools/find-credential-exposure.d.ts.map +0 -1
  30. package/dist/tools/find-credential-exposure.js +0 -185
  31. package/dist/tools/find-credential-exposure.js.map +0 -1
  32. package/dist/tools/find-excessive-permissions.d.ts +0 -16
  33. package/dist/tools/find-excessive-permissions.d.ts.map +0 -1
  34. package/dist/tools/find-excessive-permissions.js +0 -144
  35. package/dist/tools/find-excessive-permissions.js.map +0 -1
  36. package/dist/tools/find-install-script-risk.d.ts +0 -11
  37. package/dist/tools/find-install-script-risk.d.ts.map +0 -1
  38. package/dist/tools/find-install-script-risk.js +0 -115
  39. package/dist/tools/find-install-script-risk.js.map +0 -1
  40. package/dist/tools/find-pattern.d.ts +0 -13
  41. package/dist/tools/find-pattern.d.ts.map +0 -1
  42. package/dist/tools/find-pattern.js +0 -114
  43. package/dist/tools/find-pattern.js.map +0 -1
  44. package/dist/tools/find-spec-drift.d.ts +0 -10
  45. package/dist/tools/find-spec-drift.d.ts.map +0 -1
  46. package/dist/tools/find-spec-drift.js +0 -41
  47. package/dist/tools/find-spec-drift.js.map +0 -1
  48. package/dist/tools/find-stale-dependencies.d.ts +0 -14
  49. package/dist/tools/find-stale-dependencies.d.ts.map +0 -1
  50. package/dist/tools/find-stale-dependencies.js +0 -177
  51. package/dist/tools/find-stale-dependencies.js.map +0 -1
  52. package/dist/tools/find-typosquats.d.ts +0 -11
  53. package/dist/tools/find-typosquats.d.ts.map +0 -1
  54. package/dist/tools/find-typosquats.js +0 -141
  55. package/dist/tools/find-typosquats.js.map +0 -1
  56. package/dist/tools/layer-bom.d.ts +0 -15
  57. package/dist/tools/layer-bom.d.ts.map +0 -1
  58. package/dist/tools/layer-bom.js +0 -98
  59. package/dist/tools/layer-bom.js.map +0 -1
  60. package/dist/tools/verify-spec-conformance.d.ts +0 -9
  61. package/dist/tools/verify-spec-conformance.d.ts.map +0 -1
  62. package/dist/tools/verify-spec-conformance.js +0 -49
  63. package/dist/tools/verify-spec-conformance.js.map +0 -1
  64. package/dist/walk.d.ts +0 -33
  65. package/dist/walk.d.ts.map +0 -1
  66. package/dist/walk.js +0 -83
  67. package/dist/walk.js.map +0 -1
@@ -1,144 +0,0 @@
1
- /**
2
- * find_excessive_permissions MCP tool (Pillar I, Batch 2).
3
- *
4
- * Analyzes MCP server configurations for overly broad or dangerous permissions.
5
- * Supports: skill bundle (mcp.json), Claude Desktop, Cursor configs.
6
- *
7
- * Auto-detection heuristic:
8
- * - Files named mcp.json, .mcp.json, mcp-config.json → skill bundle format
9
- * - claude_desktop_config.json → Claude Desktop format
10
- * - .cursor/mcp.json → Cursor format
11
- *
12
- * @see https://github.com/cogniumhq/cognium-ai/issues/80
13
- */
14
- import { z } from 'zod';
15
- import { excessivePermissionsPass } from 'circle-ir-ai';
16
- import { loadCircleIR } from '../analysis.js';
17
- const MAX_FINDINGS = 500;
18
- const SEVERITY_ORDER = {
19
- info: 0,
20
- low: 1,
21
- medium: 2,
22
- high: 3,
23
- critical: 4,
24
- };
25
- const inputSchema = {
26
- code_root: z.string().describe('Absolute path to the code root to scan'),
27
- severity_floor: z.enum(['info', 'low', 'medium', 'high', 'critical']).optional().default('low').describe('Minimum severity to report (default: low)'),
28
- deep_analysis: z.boolean().optional().default(true).describe('Run CircleIR analysis to detect undisclosed capabilities (default: true)'),
29
- };
30
- const outputSchema = {
31
- findings: z.array(z.object({
32
- kind: z.literal('EXCESSIVE_PERMISSION'),
33
- severity: z.enum(['low', 'medium', 'high', 'critical']),
34
- location: z.object({
35
- file: z.string(),
36
- span: z.tuple([z.number(), z.number()]),
37
- }),
38
- evidence: z.object({
39
- rule_id: z.string(),
40
- config_file: z.string(),
41
- permission_type: z.string(),
42
- value: z.string(),
43
- }),
44
- suggested_action: z.string(),
45
- })),
46
- summary: z.object({
47
- total: z.number(),
48
- by_severity: z.object({
49
- critical: z.number(),
50
- high: z.number(),
51
- medium: z.number(),
52
- low: z.number(),
53
- }),
54
- truncated: z.boolean(),
55
- }),
56
- detection_info: z.object({
57
- config_files_checked: z.array(z.string()),
58
- auto_detection_heuristic: z.string(),
59
- deep_analysis_performed: z.boolean(),
60
- files_analyzed: z.number().optional(),
61
- }),
62
- };
63
- const SUGGESTED_ACTIONS = {
64
- 'perm-broad-filesystem': 'Restrict filesystem access to specific directories needed by the tool. Avoid /home, /Users, or ~ wildcards.',
65
- 'perm-secret-env-exposure': 'Remove sensitive environment variables from MCP config. Use secrets management instead.',
66
- 'perm-unrestricted-network': 'Restrict network access to specific hosts/ports needed by the tool.',
67
- 'perm-dangerous-command': 'Review and restrict allowed commands. Avoid shell interpreters and system utilities.',
68
- 'perm-write-sensitive-path': 'Restrict write access to user-specific directories. Avoid system paths.',
69
- };
70
- function trustFindingToMcp(f) {
71
- const meta = f.meta;
72
- return {
73
- kind: 'EXCESSIVE_PERMISSION',
74
- severity: f.severity === 'info' ? 'low' : f.severity,
75
- location: {
76
- file: f.location?.file ?? 'mcp.json',
77
- span: [f.location?.line ?? 1, f.location?.line ?? 1],
78
- },
79
- evidence: {
80
- rule_id: f.ruleId,
81
- config_file: f.location?.file ?? 'mcp.json',
82
- permission_type: meta.permissionType ?? 'unknown',
83
- value: meta.value ?? '',
84
- },
85
- suggested_action: SUGGESTED_ACTIONS[f.ruleId] ?? 'Review this permission for security risks and apply least-privilege principle.',
86
- };
87
- }
88
- export function registerFindExcessivePermissions(server) {
89
- server.registerTool('find_excessive_permissions', {
90
- title: 'Find Excessive Permissions',
91
- description: 'Analyze MCP server configurations for overly broad permissions. ' +
92
- 'Detects: broad filesystem paths (/home, /Users, ~), secret env var exposure, ' +
93
- 'unrestricted network access, dangerous command allowlisting. ' +
94
- 'Auto-detects config format (skill bundle, Claude Desktop, Cursor).',
95
- inputSchema,
96
- outputSchema,
97
- }, async ({ code_root, severity_floor, deep_analysis }) => {
98
- // Run CircleIR analysis for deep capability detection
99
- let circleIRResults;
100
- if (deep_analysis !== false) {
101
- try {
102
- const { results } = await loadCircleIR(code_root);
103
- circleIRResults = results;
104
- }
105
- catch {
106
- // CircleIR analysis failed, continue with static-only analysis
107
- }
108
- }
109
- const result = await excessivePermissionsPass(code_root, { circleIRResults });
110
- const floorValue = SEVERITY_ORDER[severity_floor ?? 'low'];
111
- const filtered = result.findings.filter((f) => SEVERITY_ORDER[f.severity] >= floorValue);
112
- const truncated = filtered.length > MAX_FINDINGS;
113
- const findings = filtered.slice(0, MAX_FINDINGS).map(trustFindingToMcp);
114
- const output = {
115
- findings,
116
- summary: {
117
- total: filtered.length,
118
- by_severity: {
119
- critical: filtered.filter((f) => f.severity === 'critical').length,
120
- high: filtered.filter((f) => f.severity === 'high').length,
121
- medium: filtered.filter((f) => f.severity === 'medium').length,
122
- low: filtered.filter((f) => f.severity === 'low').length,
123
- },
124
- truncated,
125
- },
126
- detection_info: {
127
- config_files_checked: [
128
- 'mcp.json', '.mcp.json', 'mcp-config.json',
129
- 'claude_desktop_config.json', '.cursor/mcp.json',
130
- ],
131
- auto_detection_heuristic: 'Files named mcp.json/.mcp.json/mcp-config.json use skill bundle format. ' +
132
- 'claude_desktop_config.json uses Claude Desktop format. ' +
133
- '.cursor/mcp.json uses Cursor format.',
134
- deep_analysis_performed: !!circleIRResults,
135
- files_analyzed: circleIRResults?.length,
136
- },
137
- };
138
- return {
139
- content: [{ type: 'text', text: JSON.stringify(output) }],
140
- structuredContent: output,
141
- };
142
- });
143
- }
144
- //# sourceMappingURL=find-excessive-permissions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-excessive-permissions.js","sourceRoot":"","sources":["../../src/tools/find-excessive-permissions.ts"],"names":[],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- /**
2
- * find_install_script_risk MCP tool (Pillar I, Batch 2).
3
- *
4
- * Analyzes npm package.json lifecycle scripts for suspicious patterns.
5
- * Scope: npm lifecycle scripts only (preinstall, install, postinstall, prepare, etc.)
6
- *
7
- * @see https://github.com/cogniumhq/cognium-ai/issues/80
8
- */
9
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
- export declare function registerFindInstallScriptRisk(server: McpServer): void;
11
- //# sourceMappingURL=find-install-script-risk.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-install-script-risk.d.ts","sourceRoot":"","sources":["../../src/tools/find-install-script-risk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgGzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2CrE"}
@@ -1,115 +0,0 @@
1
- /**
2
- * find_install_script_risk MCP tool (Pillar I, Batch 2).
3
- *
4
- * Analyzes npm package.json lifecycle scripts for suspicious patterns.
5
- * Scope: npm lifecycle scripts only (preinstall, install, postinstall, prepare, etc.)
6
- *
7
- * @see https://github.com/cogniumhq/cognium-ai/issues/80
8
- */
9
- import { z } from 'zod';
10
- import { maliciousInstallScriptPass } from 'circle-ir-ai';
11
- const MAX_FINDINGS = 500;
12
- const MAX_SNIPPET_LENGTH = 200;
13
- const SEVERITY_ORDER = {
14
- info: 0,
15
- low: 1,
16
- medium: 2,
17
- high: 3,
18
- critical: 4,
19
- };
20
- const inputSchema = {
21
- code_root: z.string().describe('Absolute path to the code root to scan'),
22
- severity_floor: z.enum(['info', 'low', 'medium', 'high', 'critical']).optional().default('low').describe('Minimum severity to report (default: low)'),
23
- };
24
- const outputSchema = {
25
- findings: z.array(z.object({
26
- kind: z.literal('MALICIOUS_INSTALL_SCRIPT'),
27
- severity: z.enum(['low', 'medium', 'high', 'critical']),
28
- location: z.object({
29
- file: z.string(),
30
- span: z.tuple([z.number(), z.number()]),
31
- }),
32
- evidence: z.object({
33
- rule_id: z.string(),
34
- script_name: z.string(),
35
- script_content: z.string(),
36
- pattern_matched: z.string(),
37
- }),
38
- suggested_action: z.string(),
39
- })),
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
- const SUGGESTED_ACTIONS = {
52
- 'install-script-piped-download': 'Remove piped download execution. If external resources are needed, download explicitly and verify checksums.',
53
- 'install-script-eval-exec': 'Remove dynamic code execution. Use static scripts instead of eval/exec patterns.',
54
- 'install-script-base64-decode': 'Remove base64 obfuscation. Install scripts should be readable and auditable.',
55
- 'install-script-env-exfil': 'Remove environment variable access that could leak secrets. Document required env vars instead.',
56
- 'install-script-network-download': 'Avoid network downloads in install scripts. Bundle dependencies or use npm dependencies.',
57
- 'install-script-hidden-file-write': 'Avoid writing to hidden files/directories. Use explicit, documented paths.',
58
- };
59
- function truncate(str, max) {
60
- if (str.length <= max)
61
- return str;
62
- return str.slice(0, max - 3) + '...';
63
- }
64
- function trustFindingToMcp(f) {
65
- const meta = f.meta;
66
- return {
67
- kind: 'MALICIOUS_INSTALL_SCRIPT',
68
- severity: f.severity === 'info' ? 'low' : f.severity,
69
- location: {
70
- file: f.location?.file ?? 'package.json',
71
- span: [f.location?.line ?? 1, f.location?.line ?? 1],
72
- },
73
- evidence: {
74
- rule_id: f.ruleId,
75
- script_name: meta.scriptName ?? 'unknown',
76
- script_content: truncate(meta.scriptContent ?? '', MAX_SNIPPET_LENGTH),
77
- pattern_matched: f.ruleId,
78
- },
79
- suggested_action: SUGGESTED_ACTIONS[f.ruleId] ?? 'Review this install script for security risks.',
80
- };
81
- }
82
- export function registerFindInstallScriptRisk(server) {
83
- server.registerTool('find_install_script_risk', {
84
- title: 'Find Install Script Risk',
85
- description: 'Analyze npm package.json lifecycle scripts (preinstall, install, postinstall, prepare) ' +
86
- 'for suspicious patterns: piped downloads, eval/exec, base64 decoding, env exfiltration, ' +
87
- 'network downloads, hidden file writes. npm lifecycle scripts only.',
88
- inputSchema,
89
- outputSchema,
90
- }, async ({ code_root, severity_floor }) => {
91
- const result = await maliciousInstallScriptPass(code_root, {});
92
- const floorValue = SEVERITY_ORDER[severity_floor ?? 'low'];
93
- const filtered = result.findings.filter((f) => SEVERITY_ORDER[f.severity] >= floorValue);
94
- const truncated = filtered.length > MAX_FINDINGS;
95
- const findings = filtered.slice(0, MAX_FINDINGS).map(trustFindingToMcp);
96
- const output = {
97
- findings,
98
- summary: {
99
- total: filtered.length,
100
- by_severity: {
101
- critical: filtered.filter((f) => f.severity === 'critical').length,
102
- high: filtered.filter((f) => f.severity === 'high').length,
103
- medium: filtered.filter((f) => f.severity === 'medium').length,
104
- low: filtered.filter((f) => f.severity === 'low').length,
105
- },
106
- truncated,
107
- },
108
- };
109
- return {
110
- content: [{ type: 'text', text: JSON.stringify(output) }],
111
- structuredContent: output,
112
- };
113
- });
114
- }
115
- //# sourceMappingURL=find-install-script-risk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-install-script-risk.js","sourceRoot":"","sources":["../../src/tools/find-install-script-risk.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * `find_pattern` MCP tool (stretch).
3
- *
4
- * Runs a JavaScript regular expression over the text contents of files under
5
- * a code root and returns the matches with a line-based span and a snippet.
6
- *
7
- * NOTE: `span` is `[startLine, endLine]` (1-based, line-based — NOT character
8
- * offsets). Documented in README; adaptable to char offsets additively if a
9
- * consumer needs them.
10
- */
11
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
12
- export declare function registerFindPattern(server: McpServer): void;
13
- //# sourceMappingURL=find-pattern.d.ts.map
@@ -1 +0,0 @@
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"}
@@ -1,114 +0,0 @@
1
- /**
2
- * `find_pattern` MCP tool (stretch).
3
- *
4
- * Runs a JavaScript regular expression over the text contents of files under
5
- * a code root and returns the matches with a line-based span and a snippet.
6
- *
7
- * NOTE: `span` is `[startLine, endLine]` (1-based, line-based — NOT character
8
- * offsets). Documented in README; adaptable to char offsets additively if a
9
- * consumer needs them.
10
- */
11
- import * as fs from 'fs';
12
- import { z } from 'zod';
13
- import { walkFiles } from '../walk.js';
14
- /** Hard cap on total matches returned across all files. */
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;
26
- const inputSchema = {
27
- pattern: z.string().describe('JavaScript regular expression (applied with the global flag)'),
28
- code_root: z.string().describe('Path to the code root to search'),
29
- };
30
- const outputSchema = {
31
- matches: z.array(z.object({
32
- file: z.string(),
33
- span: z.tuple([z.number(), z.number()]),
34
- snippet: z.string(),
35
- })),
36
- };
37
- /** Count newlines in `text` before byte index `end`. */
38
- function lineAt(text, end) {
39
- let line = 1;
40
- for (let i = 0; i < end && i < text.length; i++) {
41
- if (text[i] === '\n')
42
- line++;
43
- }
44
- return line;
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
- }
51
- export function registerFindPattern(server) {
52
- server.registerTool('find_pattern', {
53
- title: 'Find Pattern',
54
- description: 'Search file contents under a code root with a JavaScript regular ' +
55
- 'expression. Returns matches with a 1-based line span [start, end] and ' +
56
- 'a trimmed snippet. Skips binary/large files and common excludes.',
57
- inputSchema,
58
- outputSchema,
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
- }
69
- const matches = [];
70
- const files = walkFiles(code_root);
71
- const deadline = Date.now() + TIME_BUDGET_MS;
72
- for (const file of files) {
73
- if (matches.length >= MAX_MATCHES || Date.now() > deadline)
74
- break;
75
- let content;
76
- try {
77
- content = fs.readFileSync(file.absolutePath, 'utf-8');
78
- }
79
- catch {
80
- continue;
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;
86
- // Fresh regex per file so lastIndex state never leaks across files.
87
- const re = new RegExp(pattern, 'g');
88
- let m;
89
- while ((m = re.exec(content)) !== null) {
90
- const startLine = lineAt(content, m.index);
91
- const matched = m[0];
92
- const newlines = (matched.match(/\n/g) ?? []).length;
93
- const endLine = startLine + newlines;
94
- const snippet = matched.split('\n')[0].trim();
95
- matches.push({
96
- file: file.relativePath,
97
- span: [startLine, endLine],
98
- snippet,
99
- });
100
- if (matches.length >= MAX_MATCHES || Date.now() > deadline)
101
- break;
102
- // Guard against zero-width matches looping forever.
103
- if (m.index === re.lastIndex)
104
- re.lastIndex++;
105
- }
106
- }
107
- const payload = { matches };
108
- return {
109
- content: [{ type: 'text', text: JSON.stringify(payload) }],
110
- structuredContent: payload,
111
- };
112
- });
113
- }
114
- //# sourceMappingURL=find-pattern.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-pattern.js","sourceRoot":"","sources":["../../src/tools/find-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,2DAA2D;AAC3D,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB;;;;;;;;GAQG;AACH,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;IAC5F,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CAClE,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC,CACH;CACF,CAAC;AAQF,wDAAwD;AACxD,SAAS,MAAM,CAAC,IAAY,EAAE,GAAW;IACvC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,mEAAmE;YACnE,wEAAwE;YACxE,kEAAkE;QACpE,WAAW;QACX,YAAY;KACb,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE;QAC/B,qEAAqE;QACrE,qEAAqE;QACrE,4DAA4D;QAC5D,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,+BAAgC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;QAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;gBAAE,MAAM;YAElE,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,qEAAqE;YACrE,oDAAoD;YACpD,IAAI,WAAW,CAAC,OAAO,CAAC;gBAAE,SAAS;YAEnC,oEAAoE;YACpE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAEpC,IAAI,CAAyB,CAAC;YAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrB,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrD,MAAM,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;gBACrC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;gBAE/C,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,IAAI,CAAC,YAAY;oBACvB,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;oBAC1B,OAAO;iBACR,CAAC,CAAC;gBAEH,IAAI,OAAO,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;oBAAE,MAAM;gBAClE,oDAAoD;gBACpD,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,SAAS;oBAAE,EAAE,CAAC,SAAS,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1D,iBAAiB,EAAE,OAA6C;SACjE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,10 +0,0 @@
1
- /**
2
- * `find_spec_drift` MCP tool.
3
- *
4
- * Reports drift between code and spec: code paths with no matching
5
- * requirement (code_without_spec) and requirements with no matching code
6
- * (spec_without_code), each with a suggested remediation.
7
- */
8
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
- export declare function registerFindSpecDrift(server: McpServer): void;
10
- //# sourceMappingURL=find-spec-drift.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-spec-drift.d.ts","sourceRoot":"","sources":["../../src/tools/find-spec-drift.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoBzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB7D"}
@@ -1,41 +0,0 @@
1
- /**
2
- * `find_spec_drift` MCP tool.
3
- *
4
- * Reports drift between code and spec: code paths with no matching
5
- * requirement (code_without_spec) and requirements with no matching code
6
- * (spec_without_code), each with a suggested remediation.
7
- */
8
- import { z } from 'zod';
9
- import { analyzeSpecGap } from 'circle-ir-ai';
10
- import { loadCircleIR } from '../analysis.js';
11
- import { toSpecDrift } from '../mappers.js';
12
- const inputSchema = {
13
- spec_dir: z.string().describe('Path to the .specifica/ directory containing spec.md'),
14
- code_root: z.string().describe('Path to the code root to analyze'),
15
- };
16
- const outputSchema = {
17
- drifts: z.array(z.object({
18
- kind: z.enum(['code_without_spec', 'spec_without_code']),
19
- location: z.string(),
20
- suggested_action: z.string(),
21
- })),
22
- };
23
- export function registerFindSpecDrift(server) {
24
- server.registerTool('find_spec_drift', {
25
- title: 'Find Spec Drift',
26
- description: 'Find drift between code and spec: undocumented behaviors ' +
27
- '(code_without_spec) and unimplemented requirements ' +
28
- '(spec_without_code), each with a suggested action.',
29
- inputSchema,
30
- outputSchema,
31
- }, async ({ spec_dir, code_root }) => {
32
- const { codePath, results } = await loadCircleIR(code_root);
33
- const specGap = await analyzeSpecGap(codePath, results, { specDir: spec_dir });
34
- const payload = toSpecDrift(specGap);
35
- return {
36
- content: [{ type: 'text', text: JSON.stringify(payload) }],
37
- structuredContent: payload,
38
- };
39
- });
40
- }
41
- //# sourceMappingURL=find-spec-drift.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-spec-drift.js","sourceRoot":"","sources":["../../src/tools/find-spec-drift.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,GAAG;IAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IACrF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CACnE,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;QACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;KAC7B,CAAC,CACH;CACF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,2DAA2D;YAC3D,qDAAqD;YACrD,oDAAoD;QACtD,WAAW;QACX,YAAY;KACb,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QAChC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/E,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1D,iBAAiB,EAAE,OAA6C;SACjE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,14 +0,0 @@
1
- /**
2
- * find_stale_dependencies MCP tool (Pillar I, Batch 2).
3
- *
4
- * Checks npm dependencies for:
5
- * 1. Staleness: last publish date via npm registry
6
- * 2. Known vulnerabilities: via OSV (Open Source Vulnerabilities) API
7
- *
8
- * npm package.json only (pypi/cargo/go deferred).
9
- *
10
- * @see https://github.com/cogniumhq/cognium-ai/issues/80
11
- */
12
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
13
- export declare function registerFindStaleDependencies(server: McpServer): void;
14
- //# sourceMappingURL=find-stale-dependencies.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-stale-dependencies.d.ts","sourceRoot":"","sources":["../../src/tools/find-stale-dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAoJzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+DrE"}