@cognium-ai/mcp-server 4.16.5 → 4.17.1
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 +1834 -0
- package/README.md +27 -257
- package/dist/deprecation.d.ts +5 -0
- package/dist/deprecation.d.ts.map +1 -0
- package/dist/deprecation.js +7 -0
- package/dist/deprecation.js.map +1 -0
- package/dist/index.d.ts +18 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -19
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +15 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +26 -31
- package/dist/server.js.map +1 -1
- package/package.json +6 -7
- package/dist/analysis.d.ts +0 -25
- package/dist/analysis.d.ts.map +0 -1
- package/dist/analysis.js +0 -45
- package/dist/analysis.js.map +0 -1
- package/dist/mappers.d.ts +0 -41
- package/dist/mappers.d.ts.map +0 -1
- package/dist/mappers.js +0 -69
- package/dist/mappers.js.map +0 -1
- package/dist/tools/check-license-compliance.d.ts +0 -11
- package/dist/tools/check-license-compliance.d.ts.map +0 -1
- package/dist/tools/check-license-compliance.js +0 -125
- package/dist/tools/check-license-compliance.js.map +0 -1
- package/dist/tools/find-credential-exposure.d.ts +0 -17
- package/dist/tools/find-credential-exposure.d.ts.map +0 -1
- package/dist/tools/find-credential-exposure.js +0 -185
- package/dist/tools/find-credential-exposure.js.map +0 -1
- package/dist/tools/find-excessive-permissions.d.ts +0 -16
- package/dist/tools/find-excessive-permissions.d.ts.map +0 -1
- package/dist/tools/find-excessive-permissions.js +0 -144
- package/dist/tools/find-excessive-permissions.js.map +0 -1
- package/dist/tools/find-install-script-risk.d.ts +0 -11
- package/dist/tools/find-install-script-risk.d.ts.map +0 -1
- package/dist/tools/find-install-script-risk.js +0 -115
- package/dist/tools/find-install-script-risk.js.map +0 -1
- package/dist/tools/find-pattern.d.ts +0 -13
- package/dist/tools/find-pattern.d.ts.map +0 -1
- package/dist/tools/find-pattern.js +0 -114
- package/dist/tools/find-pattern.js.map +0 -1
- package/dist/tools/find-spec-drift.d.ts +0 -10
- package/dist/tools/find-spec-drift.d.ts.map +0 -1
- package/dist/tools/find-spec-drift.js +0 -41
- package/dist/tools/find-spec-drift.js.map +0 -1
- package/dist/tools/find-stale-dependencies.d.ts +0 -14
- package/dist/tools/find-stale-dependencies.d.ts.map +0 -1
- package/dist/tools/find-stale-dependencies.js +0 -177
- package/dist/tools/find-stale-dependencies.js.map +0 -1
- package/dist/tools/find-typosquats.d.ts +0 -11
- package/dist/tools/find-typosquats.d.ts.map +0 -1
- package/dist/tools/find-typosquats.js +0 -141
- package/dist/tools/find-typosquats.js.map +0 -1
- package/dist/tools/layer-bom.d.ts +0 -15
- package/dist/tools/layer-bom.d.ts.map +0 -1
- package/dist/tools/layer-bom.js +0 -98
- package/dist/tools/layer-bom.js.map +0 -1
- package/dist/tools/verify-spec-conformance.d.ts +0 -9
- package/dist/tools/verify-spec-conformance.d.ts.map +0 -1
- package/dist/tools/verify-spec-conformance.js +0 -49
- package/dist/tools/verify-spec-conformance.js.map +0 -1
- package/dist/walk.d.ts +0 -33
- package/dist/walk.d.ts.map +0 -1
- package/dist/walk.js +0 -83
- package/dist/walk.js.map +0 -1
package/dist/analysis.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Circle-IR loading for the MCP server.
|
|
3
|
-
*
|
|
4
|
-
* Wraps circle-ir-ai's analyzer lifecycle: initialize the WASM-backed
|
|
5
|
-
* analyzer once, walk the code root for supported source files, and run
|
|
6
|
-
* circle-ir's `analyze` per file. The resulting `CircleIR[]` is the input to
|
|
7
|
-
* `analyzeSpecGap` (used by the verify/drift tools).
|
|
8
|
-
*
|
|
9
|
-
* Mirrors the wiring recipe in cognium-ai's `spec-diff` command, but depends
|
|
10
|
-
* only on `circle-ir` + `circle-ir-ai` (not the cognium-ai CLI).
|
|
11
|
-
*/
|
|
12
|
-
import * as fs from 'fs';
|
|
13
|
-
import * as path from 'path';
|
|
14
|
-
import { analyze } from 'circle-ir';
|
|
15
|
-
import { ensureAnalyzerInitialized } from 'circle-ir-ai';
|
|
16
|
-
import { collectSourceFiles } from './walk.js';
|
|
17
|
-
/**
|
|
18
|
-
* Walk `codeRoot`, analyze each supported source file, and return the
|
|
19
|
-
* collected `CircleIR[]` alongside the resolved code path.
|
|
20
|
-
*/
|
|
21
|
-
export async function loadCircleIR(codeRoot, options = {}) {
|
|
22
|
-
await ensureAnalyzerInitialized();
|
|
23
|
-
const codePath = path.resolve(codeRoot);
|
|
24
|
-
const files = collectSourceFiles(codePath, options);
|
|
25
|
-
const results = [];
|
|
26
|
-
for (const file of files) {
|
|
27
|
-
let content;
|
|
28
|
-
try {
|
|
29
|
-
content = fs.readFileSync(file.absolutePath, 'utf-8');
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
try {
|
|
35
|
-
const ir = await analyze(content, path.basename(file.absolutePath), file.language);
|
|
36
|
-
results.push(ir);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// Skip files circle-ir can't parse; spec-gap tolerates a partial corpus.
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return { codePath, results };
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=analysis.js.map
|
package/dist/analysis.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAiB,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAoB,MAAM,WAAW,CAAC;AASjE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,UAAuB,EAAE;IAEzB,MAAM,yBAAyB,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAe,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnF,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC"}
|
package/dist/mappers.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure mappers from the engine's `SpecGapResult` (camelCase) to the MCP
|
|
3
|
-
* boundary shapes (snake_case). Kept side-effect-free so they can be unit
|
|
4
|
-
* tested without spinning up the analyzer.
|
|
5
|
-
*
|
|
6
|
-
* Schema stability: field names here are draft-stable through 2026-08-31.
|
|
7
|
-
* Additive changes are safe; renames/removals are breaking (bump major).
|
|
8
|
-
*/
|
|
9
|
-
import type { SpecGapResult } from 'circle-ir-ai';
|
|
10
|
-
/** Confidence at/above which a covered match is "covered" vs "partial". */
|
|
11
|
-
export declare const PARTIAL_CONFIDENCE_THRESHOLD = 0.7;
|
|
12
|
-
export type RequirementStatus = 'covered' | 'partial' | 'uncovered';
|
|
13
|
-
export interface RequirementEvidence {
|
|
14
|
-
function?: string;
|
|
15
|
-
file?: string;
|
|
16
|
-
span?: [number, number];
|
|
17
|
-
}
|
|
18
|
-
export interface VerifyRequirement {
|
|
19
|
-
id: string;
|
|
20
|
-
status: RequirementStatus;
|
|
21
|
-
evidence: RequirementEvidence;
|
|
22
|
-
}
|
|
23
|
-
export interface VerifyConformanceResult {
|
|
24
|
-
alignment_score: number;
|
|
25
|
-
requirements: VerifyRequirement[];
|
|
26
|
-
summary: string;
|
|
27
|
-
}
|
|
28
|
-
export type DriftKind = 'code_without_spec' | 'spec_without_code';
|
|
29
|
-
export interface Drift {
|
|
30
|
-
kind: DriftKind;
|
|
31
|
-
location: string;
|
|
32
|
-
suggested_action: string;
|
|
33
|
-
}
|
|
34
|
-
export interface FindSpecDriftResult {
|
|
35
|
-
drifts: Drift[];
|
|
36
|
-
}
|
|
37
|
-
/** Map a `SpecGapResult` to the `verify_spec_conformance` output shape. */
|
|
38
|
-
export declare function toVerifyConformance(result: SpecGapResult): VerifyConformanceResult;
|
|
39
|
-
/** Map a `SpecGapResult` to the `find_spec_drift` output shape. */
|
|
40
|
-
export declare function toSpecDrift(result: SpecGapResult): FindSpecDriftResult;
|
|
41
|
-
//# sourceMappingURL=mappers.d.ts.map
|
package/dist/mappers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure mappers from the engine's `SpecGapResult` (camelCase) to the MCP
|
|
3
|
-
* boundary shapes (snake_case). Kept side-effect-free so they can be unit
|
|
4
|
-
* tested without spinning up the analyzer.
|
|
5
|
-
*
|
|
6
|
-
* Schema stability: field names here are draft-stable through 2026-08-31.
|
|
7
|
-
* Additive changes are safe; renames/removals are breaking (bump major).
|
|
8
|
-
*/
|
|
9
|
-
/** Confidence at/above which a covered match is "covered" vs "partial". */
|
|
10
|
-
export const PARTIAL_CONFIDENCE_THRESHOLD = 0.7;
|
|
11
|
-
/** Map a `SpecGapResult` to the `verify_spec_conformance` output shape. */
|
|
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
|
-
}
|
|
25
|
-
const requirements = [];
|
|
26
|
-
for (const match of result.coveredRequirements) {
|
|
27
|
-
requirements.push({
|
|
28
|
-
id: match.requirement.id,
|
|
29
|
-
status: match.confidence >= PARTIAL_CONFIDENCE_THRESHOLD ? 'covered' : 'partial',
|
|
30
|
-
evidence: { function: match.matchedFunction },
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
for (const uncovered of result.uncoveredRequirements) {
|
|
34
|
-
requirements.push({
|
|
35
|
-
id: uncovered.requirement.id,
|
|
36
|
-
status: 'uncovered',
|
|
37
|
-
evidence: {},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
const { covered, totalRequirements, coveragePercent, undocumented } = result.summary;
|
|
41
|
-
const summary = `${covered}/${totalRequirements} requirements covered (${coveragePercent}%); ` +
|
|
42
|
-
`${undocumented} undocumented behaviors`;
|
|
43
|
-
return {
|
|
44
|
-
alignment_score: result.specAlignmentScore,
|
|
45
|
-
requirements,
|
|
46
|
-
summary,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/** Map a `SpecGapResult` to the `find_spec_drift` output shape. */
|
|
50
|
-
export function toSpecDrift(result) {
|
|
51
|
-
const drifts = [];
|
|
52
|
-
for (const behavior of result.undocumentedBehaviors) {
|
|
53
|
-
drifts.push({
|
|
54
|
-
kind: 'code_without_spec',
|
|
55
|
-
location: behavior.functionName,
|
|
56
|
-
suggested_action: behavior.suggestion,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
for (const uncovered of result.uncoveredRequirements) {
|
|
60
|
-
const { id, description } = uncovered.requirement;
|
|
61
|
-
drifts.push({
|
|
62
|
-
kind: 'spec_without_code',
|
|
63
|
-
location: id,
|
|
64
|
-
suggested_action: uncovered.reason || `Implement ${id}: ${description}`,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return { drifts };
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=mappers.js.map
|
package/dist/mappers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* check_license_compliance MCP tool (Pillar I, Workflow #2).
|
|
3
|
-
*
|
|
4
|
-
* Scans a code root for copyleft/restrictive license issues in dependencies.
|
|
5
|
-
* Supports Node.js (package.json) and Rust (Cargo.toml) ecosystems.
|
|
6
|
-
*
|
|
7
|
-
* @see https://github.com/cogniumhq/cognium-ai/issues/79
|
|
8
|
-
*/
|
|
9
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
|
-
export declare function registerCheckLicenseCompliance(server: McpServer): void;
|
|
11
|
-
//# sourceMappingURL=check-license-compliance.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check-license-compliance.d.ts","sourceRoot":"","sources":["../../src/tools/check-license-compliance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0HzE,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsDtE"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* check_license_compliance MCP tool (Pillar I, Workflow #2).
|
|
3
|
-
*
|
|
4
|
-
* Scans a code root for copyleft/restrictive license issues in dependencies.
|
|
5
|
-
* Supports Node.js (package.json) and Rust (Cargo.toml) ecosystems.
|
|
6
|
-
*
|
|
7
|
-
* @see https://github.com/cogniumhq/cognium-ai/issues/79
|
|
8
|
-
*/
|
|
9
|
-
import { z } from 'zod';
|
|
10
|
-
import { scanLicenseCompliance, COPYLEFT_SEVERITY, } from 'circle-ir-ai';
|
|
11
|
-
const MAX_FINDINGS = 500;
|
|
12
|
-
const inputSchema = {
|
|
13
|
-
code_root: z.string().describe('Absolute path to the code root to scan'),
|
|
14
|
-
include_dev_deps: z.boolean().optional().default(false).describe('Include devDependencies (default: false)'),
|
|
15
|
-
severity_floor: z.enum(['info', 'low', 'medium', 'high', 'critical']).optional().default('low').describe('Minimum severity to report (default: low)'),
|
|
16
|
-
};
|
|
17
|
-
const findingSchema = z.object({
|
|
18
|
-
kind: z.literal('LICENSE_VIOLATION'),
|
|
19
|
-
severity: z.enum(['low', 'medium', 'high', 'critical']),
|
|
20
|
-
location: z.object({
|
|
21
|
-
file: z.string(),
|
|
22
|
-
span: z.tuple([z.number(), z.number()]),
|
|
23
|
-
}),
|
|
24
|
-
evidence: z.object({
|
|
25
|
-
rule_id: z.string(),
|
|
26
|
-
dependency: z.string(),
|
|
27
|
-
license: z.string(),
|
|
28
|
-
confidence: z.number(),
|
|
29
|
-
}),
|
|
30
|
-
suggested_action: z.string(),
|
|
31
|
-
});
|
|
32
|
-
const outputSchema = {
|
|
33
|
-
findings: z.array(findingSchema),
|
|
34
|
-
summary: z.object({
|
|
35
|
-
total: z.number(),
|
|
36
|
-
by_severity: z.object({
|
|
37
|
-
critical: z.number(),
|
|
38
|
-
high: z.number(),
|
|
39
|
-
medium: z.number(),
|
|
40
|
-
low: z.number(),
|
|
41
|
-
}),
|
|
42
|
-
by_ecosystem: z.object({
|
|
43
|
-
nodejs: z.number(),
|
|
44
|
-
rust: z.number(),
|
|
45
|
-
}),
|
|
46
|
-
truncated: z.boolean(),
|
|
47
|
-
}),
|
|
48
|
-
copyleft_reference: z.record(z.string(), z.string()).describe('Reference table: license to severity'),
|
|
49
|
-
};
|
|
50
|
-
const SEVERITY_ORDER = {
|
|
51
|
-
info: 0,
|
|
52
|
-
low: 1,
|
|
53
|
-
medium: 2,
|
|
54
|
-
high: 3,
|
|
55
|
-
critical: 4,
|
|
56
|
-
};
|
|
57
|
-
function licenseToFinding(finding) {
|
|
58
|
-
return {
|
|
59
|
-
kind: 'LICENSE_VIOLATION',
|
|
60
|
-
severity: finding.severity === 'info' ? 'low' : finding.severity,
|
|
61
|
-
location: {
|
|
62
|
-
file: finding.file,
|
|
63
|
-
span: [finding.line ?? 1, finding.line ?? 1],
|
|
64
|
-
},
|
|
65
|
-
evidence: {
|
|
66
|
-
rule_id: finding.ruleId,
|
|
67
|
-
dependency: finding.dependency,
|
|
68
|
-
license: finding.license,
|
|
69
|
-
confidence: finding.confidence,
|
|
70
|
-
},
|
|
71
|
-
suggested_action: finding.suggestedAction,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function buildCopyleftReference() {
|
|
75
|
-
const ref = {};
|
|
76
|
-
for (const [license, severity] of Object.entries(COPYLEFT_SEVERITY)) {
|
|
77
|
-
ref[license] = severity;
|
|
78
|
-
}
|
|
79
|
-
return ref;
|
|
80
|
-
}
|
|
81
|
-
export function registerCheckLicenseCompliance(server) {
|
|
82
|
-
server.registerTool('check_license_compliance', {
|
|
83
|
-
title: 'Check License Compliance',
|
|
84
|
-
description: 'Scan a code root for copyleft/restrictive license issues in dependencies. ' +
|
|
85
|
-
'Supports Node.js (package.json) and Rust (Cargo.toml). ' +
|
|
86
|
-
'Flags AGPL, GPL, LGPL, MPL, and other copyleft licenses with severity classification. ' +
|
|
87
|
-
'Returns findings with dependency info, license SPDX, and remediation guidance.',
|
|
88
|
-
inputSchema,
|
|
89
|
-
outputSchema,
|
|
90
|
-
}, async ({ code_root, include_dev_deps, severity_floor }) => {
|
|
91
|
-
const scanResult = await scanLicenseCompliance(code_root, {
|
|
92
|
-
includeDevDeps: include_dev_deps,
|
|
93
|
-
minSeverity: severity_floor,
|
|
94
|
-
});
|
|
95
|
-
const floorValue = SEVERITY_ORDER[severity_floor ?? 'low'];
|
|
96
|
-
const filteredFindings = scanResult.findings.filter((f) => SEVERITY_ORDER[f.severity] >= floorValue);
|
|
97
|
-
const truncated = filteredFindings.length > MAX_FINDINGS;
|
|
98
|
-
const findings = filteredFindings
|
|
99
|
-
.slice(0, MAX_FINDINGS)
|
|
100
|
-
.map(licenseToFinding);
|
|
101
|
-
const result = {
|
|
102
|
-
findings,
|
|
103
|
-
summary: {
|
|
104
|
-
total: filteredFindings.length,
|
|
105
|
-
by_severity: {
|
|
106
|
-
critical: filteredFindings.filter((f) => f.severity === 'critical').length,
|
|
107
|
-
high: filteredFindings.filter((f) => f.severity === 'high').length,
|
|
108
|
-
medium: filteredFindings.filter((f) => f.severity === 'medium').length,
|
|
109
|
-
low: filteredFindings.filter((f) => f.severity === 'low').length,
|
|
110
|
-
},
|
|
111
|
-
by_ecosystem: {
|
|
112
|
-
nodejs: filteredFindings.filter((f) => f.ecosystem === 'nodejs').length,
|
|
113
|
-
rust: filteredFindings.filter((f) => f.ecosystem === 'rust').length,
|
|
114
|
-
},
|
|
115
|
-
truncated,
|
|
116
|
-
},
|
|
117
|
-
copyleft_reference: buildCopyleftReference(),
|
|
118
|
-
};
|
|
119
|
-
return {
|
|
120
|
-
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
121
|
-
structuredContent: result,
|
|
122
|
-
};
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
//# sourceMappingURL=check-license-compliance.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check-license-compliance.js","sourceRoot":"","sources":["../../src/tools/check-license-compliance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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;AA8JzE,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkEtE"}
|
|
@@ -1,185 +0,0 @@
|
|
|
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
|
-
// REFACTOR-019 (since 0.4.18): expose LLM verify controls. Default
|
|
24
|
-
// OFF for the MCP surface — clients invoking via MCP may not have
|
|
25
|
-
// LLM_API_KEY available, and an opt-in surface is friendlier than
|
|
26
|
-
// a silent ON. cognium-ai 2.14.x defaults the CLI to ON because
|
|
27
|
-
// users opt into the CLI; MCP clients haven't.
|
|
28
|
-
llm_verify: z.boolean().optional().default(false).describe('Enable LLM verification to reduce false positives (default: false; requires LLM_API_KEY on auth-required endpoints)'),
|
|
29
|
-
verify_budget: z.number().int().min(0).optional().default(100).describe('Cap on LLM verifier calls per scan (default: 100; 0 disables LLM verify entirely)'),
|
|
30
|
-
};
|
|
31
|
-
const findingSchema = z.object({
|
|
32
|
-
kind: z.literal('CREDENTIAL_EXPOSURE'),
|
|
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
|
-
match_snippet: z.string(),
|
|
41
|
-
confidence: z.number(),
|
|
42
|
-
}),
|
|
43
|
-
suggested_action: z.string(),
|
|
44
|
-
});
|
|
45
|
-
const outputSchema = {
|
|
46
|
-
findings: z.array(findingSchema),
|
|
47
|
-
summary: z.object({
|
|
48
|
-
total: z.number(),
|
|
49
|
-
by_severity: z.object({
|
|
50
|
-
critical: z.number(),
|
|
51
|
-
high: z.number(),
|
|
52
|
-
medium: z.number(),
|
|
53
|
-
low: z.number(),
|
|
54
|
-
}),
|
|
55
|
-
truncated: z.boolean(),
|
|
56
|
-
}),
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Map severity to suggested action
|
|
60
|
-
*/
|
|
61
|
-
function getSuggestedAction(secret) {
|
|
62
|
-
const category = secret.category.toLowerCase();
|
|
63
|
-
const isActive = secret.presentInHead;
|
|
64
|
-
if (!isActive) {
|
|
65
|
-
return 'Secret found in git history only. Consider rotating and cleaning history with git-filter-repo or BFG.';
|
|
66
|
-
}
|
|
67
|
-
switch (category) {
|
|
68
|
-
case 'aws':
|
|
69
|
-
return 'Rotate the AWS access key immediately via IAM console and move to AWS Secrets Manager or environment variables.';
|
|
70
|
-
case 'github':
|
|
71
|
-
return 'Revoke the token at https://github.com/settings/tokens and use GITHUB_TOKEN or repository secrets instead.';
|
|
72
|
-
case 'openai':
|
|
73
|
-
return 'Revoke the key at https://platform.openai.com/api-keys and load from environment variables.';
|
|
74
|
-
case 'anthropic':
|
|
75
|
-
return 'Revoke the key in the Anthropic Console and load from environment variables.';
|
|
76
|
-
case 'stripe':
|
|
77
|
-
return 'Rotate in the Stripe Dashboard and use environment variables or a secrets manager.';
|
|
78
|
-
case 'slack':
|
|
79
|
-
return 'Revoke the token in Slack workspace settings and use environment variables.';
|
|
80
|
-
case 'gcp':
|
|
81
|
-
return 'Restrict or revoke in Google Cloud Console and use service account keys or Workload Identity.';
|
|
82
|
-
case 'private-key':
|
|
83
|
-
return 'Remove immediately, rotate the keypair, and never commit private keys to source control.';
|
|
84
|
-
case 'jwt':
|
|
85
|
-
return 'JWTs carry whatever scope they were minted with. Rotate signing keys and remove the token.';
|
|
86
|
-
case 'npm':
|
|
87
|
-
return 'Revoke at https://www.npmjs.com/settings/<user>/tokens and use NPM_TOKEN environment variable.';
|
|
88
|
-
case 'high-entropy':
|
|
89
|
-
return 'If this is a credential, move to environment variables or a secrets manager. If sample data, add to .gitignore.';
|
|
90
|
-
default:
|
|
91
|
-
return 'Rotate this credential immediately and move to environment variables or a secrets manager.';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Map severity order for filtering
|
|
96
|
-
*/
|
|
97
|
-
const SEVERITY_ORDER = {
|
|
98
|
-
info: 0,
|
|
99
|
-
low: 1,
|
|
100
|
-
medium: 2,
|
|
101
|
-
high: 3,
|
|
102
|
-
critical: 4,
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Convert DetectedSecret to CredentialFinding
|
|
106
|
-
*/
|
|
107
|
-
function secretToFinding(secret, codeRoot) {
|
|
108
|
-
// Make file path relative to code_root
|
|
109
|
-
let relativePath = secret.file;
|
|
110
|
-
if (relativePath.startsWith(codeRoot)) {
|
|
111
|
-
relativePath = relativePath.slice(codeRoot.length);
|
|
112
|
-
if (relativePath.startsWith('/')) {
|
|
113
|
-
relativePath = relativePath.slice(1);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
kind: 'CREDENTIAL_EXPOSURE',
|
|
118
|
-
severity: secret.severity === 'low' ? 'low' : secret.severity,
|
|
119
|
-
location: {
|
|
120
|
-
file: relativePath,
|
|
121
|
-
span: [secret.line, secret.line], // Single line span
|
|
122
|
-
},
|
|
123
|
-
evidence: {
|
|
124
|
-
rule_id: secret.patternId,
|
|
125
|
-
match_snippet: secret.match, // Already redacted by scanner
|
|
126
|
-
confidence: secret.llmConfidence ?? (secret.category === 'high-entropy' ? 0.7 : 0.95),
|
|
127
|
-
},
|
|
128
|
-
suggested_action: getSuggestedAction(secret),
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
export function registerFindCredentialExposure(server) {
|
|
132
|
-
server.registerTool('find_credential_exposure', {
|
|
133
|
-
title: 'Find Credential Exposure',
|
|
134
|
-
description: 'Scan a code root for hardcoded credentials (API keys, tokens, passwords, ' +
|
|
135
|
-
'private keys). Uses SAST pattern matching and optional git history scanning. ' +
|
|
136
|
-
'Returns findings with severity, location, and remediation guidance.',
|
|
137
|
-
inputSchema,
|
|
138
|
-
outputSchema,
|
|
139
|
-
}, async ({ code_root, include_git_history, severity_floor, llm_verify, verify_budget }) => {
|
|
140
|
-
// Map severity_floor to scanner's minSeverity
|
|
141
|
-
const minSeverity = severity_floor === 'info' ? undefined :
|
|
142
|
-
severity_floor === 'low' ? 'low' :
|
|
143
|
-
severity_floor === 'medium' ? 'medium' :
|
|
144
|
-
severity_floor === 'high' ? 'high' :
|
|
145
|
-
severity_floor === 'critical' ? 'critical' :
|
|
146
|
-
'low';
|
|
147
|
-
const scanResult = await scanForSecrets(code_root, {
|
|
148
|
-
scanHistory: include_git_history,
|
|
149
|
-
minSeverity,
|
|
150
|
-
maxCommits: 100, // Reasonable limit for git history
|
|
151
|
-
// REFACTOR-019: forward LLM verify controls. Engine handles the
|
|
152
|
-
// `llmVerify && verifyBudget > 0` precedence + the silent no-op
|
|
153
|
-
// on missing LLM config (scanner.ts:568-575). MCP layer does
|
|
154
|
-
// not duplicate that logic.
|
|
155
|
-
llmVerify: llm_verify,
|
|
156
|
-
verifyBudget: verify_budget,
|
|
157
|
-
});
|
|
158
|
-
// Filter by severity floor and convert to findings
|
|
159
|
-
const floorValue = SEVERITY_ORDER[severity_floor ?? 'low'];
|
|
160
|
-
const filteredSecrets = scanResult.secrets.filter((s) => SEVERITY_ORDER[s.severity] >= floorValue);
|
|
161
|
-
// Convert to findings format, respecting MAX_FINDINGS
|
|
162
|
-
const truncated = filteredSecrets.length > MAX_FINDINGS;
|
|
163
|
-
const findings = filteredSecrets
|
|
164
|
-
.slice(0, MAX_FINDINGS)
|
|
165
|
-
.map((s) => secretToFinding(s, code_root));
|
|
166
|
-
const result = {
|
|
167
|
-
findings,
|
|
168
|
-
summary: {
|
|
169
|
-
total: filteredSecrets.length,
|
|
170
|
-
by_severity: {
|
|
171
|
-
critical: filteredSecrets.filter((s) => s.severity === 'critical').length,
|
|
172
|
-
high: filteredSecrets.filter((s) => s.severity === 'high').length,
|
|
173
|
-
medium: filteredSecrets.filter((s) => s.severity === 'medium').length,
|
|
174
|
-
low: filteredSecrets.filter((s) => s.severity === 'low').length,
|
|
175
|
-
},
|
|
176
|
-
truncated,
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
return {
|
|
180
|
-
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
181
|
-
structuredContent: result,
|
|
182
|
-
};
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
//# sourceMappingURL=find-credential-exposure.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-credential-exposure.js","sourceRoot":"","sources":["../../src/tools/find-credential-exposure.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +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 type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
15
|
-
export declare function registerFindExcessivePermissions(server: McpServer): void;
|
|
16
|
-
//# sourceMappingURL=find-excessive-permissions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-excessive-permissions.d.ts","sourceRoot":"","sources":["../../src/tools/find-excessive-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiGzE,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmExE"}
|