@aimarket/warden 0.3.0 → 0.5.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/CHANGELOG.md +155 -3
- package/README-es.md +82 -11
- package/README-fr.md +82 -11
- package/README-ru.md +82 -11
- package/README-zh.md +79 -10
- package/README.md +91 -14
- package/dist/glob.d.ts +81 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +180 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +42 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -29
- package/dist/index.js.map +1 -1
- package/dist/mcp-rpc.d.ts +40 -0
- package/dist/mcp-rpc.d.ts.map +1 -0
- package/dist/mcp-rpc.js +117 -0
- package/dist/mcp-rpc.js.map +1 -0
- package/dist/mcp-server.d.ts +10 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +89 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-tools.d.ts +42 -0
- package/dist/mcp-tools.d.ts.map +1 -0
- package/dist/mcp-tools.js +652 -0
- package/dist/mcp-tools.js.map +1 -0
- package/dist/origin.d.ts.map +1 -1
- package/dist/origin.js +7 -2
- package/dist/origin.js.map +1 -1
- package/dist/pinning.d.ts +18 -0
- package/dist/pinning.d.ts.map +1 -1
- package/dist/pinning.js +59 -11
- package/dist/pinning.js.map +1 -1
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +10 -7
- package/dist/sandbox.js.map +1 -1
- package/dist/sanitize.d.ts +38 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +53 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/static-scan.d.ts +46 -2
- package/dist/static-scan.d.ts.map +1 -1
- package/dist/static-scan.js +358 -34
- package/dist/static-scan.js.map +1 -1
- package/dist/threat-feed.d.ts +3 -0
- package/dist/threat-feed.d.ts.map +1 -1
- package/dist/threat-feed.js +118 -29
- package/dist/threat-feed.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServerRef, PinStore, ToolDef, WardenGate, WardenLogger, WardenPolicy, WardenVerdict } from "./types.js";
|
|
2
2
|
import { ThreatFeed } from "./threat-feed.js";
|
|
3
3
|
export { StaticScanGate, staticScanRuleset, staticScanRulesetRef, STATIC_SCAN_RULESET_VERSION, } from "./static-scan.js";
|
|
4
|
-
export { PinningGate, canonicalToolsHash, tryCanonicalToolsHash, UNCANONICAL_TOOLS_HASH } from "./pinning.js";
|
|
4
|
+
export { PinningGate, canonicalToolsHash, tryCanonicalToolsHash, serverIdentityHash, UNCANONICAL_TOOLS_HASH } from "./pinning.js";
|
|
5
5
|
export { OriginGate } from "./origin.js";
|
|
6
6
|
export { ThreatFeed, ThreatGate, DEFAULT_FEED_MAX_AGE_MS, FEED_CLOCK_SKEW_MS } from "./threat-feed.js";
|
|
7
7
|
export { EgressGuard, isSensitiveTool, classifyTools } from "./sandbox.js";
|
|
@@ -10,6 +10,8 @@ export type { CanonicalizationCode } from "./jcs.js";
|
|
|
10
10
|
export type { StaticScanRule, StaticScanRuleset } from "./static-scan.js";
|
|
11
11
|
export type { ThreatFeedOptions } from "./threat-feed.js";
|
|
12
12
|
export { silentLogger } from "./logger.js";
|
|
13
|
+
export { displaySafe, DEFAULT_DISPLAY_MAX } from "./sanitize.js";
|
|
14
|
+
export { wildcardMatch } from "./glob.js";
|
|
13
15
|
export * from "./types.js";
|
|
14
16
|
export interface WardenInit {
|
|
15
17
|
gates: WardenGate[];
|
|
@@ -33,10 +35,17 @@ export interface WardenCreateDeps {
|
|
|
33
35
|
*
|
|
34
36
|
* Every MCP server is vetted through an ordered gate chain before its tools are
|
|
35
37
|
* exposed to the agent: cheap static scanning first, then the known-bad threat
|
|
36
|
-
* feed, then
|
|
37
|
-
* gates; the verdict is allow/block
|
|
38
|
-
* per-tool partition so a mostly-trusted
|
|
39
|
-
* quarantined without severing the whole
|
|
38
|
+
* feed, then origin (declared by the operator, or offered by a remote catalog),
|
|
39
|
+
* then drift/pinning. Findings accumulate across gates; the verdict is allow/block
|
|
40
|
+
* plus a composite 0..1 safety score and a per-tool partition so a mostly-trusted
|
|
41
|
+
* server can have one poisoned tool quarantined without severing the whole
|
|
42
|
+
* connection.
|
|
43
|
+
*
|
|
44
|
+
* The score is WARDEN's OWN — the product of what each gate contributed, computed
|
|
45
|
+
* from local facts. No reputation oracle is consulted and no socket is opened while
|
|
46
|
+
* vetting. Slot three used to be a reputation gate that asked an oracle for a score
|
|
47
|
+
* it had no data to compute; it is gone, and test/no-phantom-gate.test.ts fails if
|
|
48
|
+
* anything like it comes back.
|
|
40
49
|
*/
|
|
41
50
|
export declare class Warden {
|
|
42
51
|
private readonly gates;
|
|
@@ -44,11 +53,19 @@ export declare class Warden {
|
|
|
44
53
|
private readonly log;
|
|
45
54
|
constructor(init: WardenInit);
|
|
46
55
|
/**
|
|
47
|
-
* Guard against config typos that silently disable blocking
|
|
48
|
-
*
|
|
49
|
-
*
|
|
56
|
+
* Guard against config typos that silently disable blocking, on a COPY.
|
|
57
|
+
*
|
|
58
|
+
* If `blockAtSeverity` isn't a valid Severity key, `SEVERITY_RANK[bad]` is
|
|
59
|
+
* undefined and every comparison `number >= undefined` is false — zero blocks,
|
|
60
|
+
* zero warnings — so the value is repaired. Repairing it in place used to write
|
|
61
|
+
* into the host's own policy object, which is both a surprise (their config
|
|
62
|
+
* silently changes under them, and any other Warden sharing the object sees it)
|
|
63
|
+
* and a crash: `Object.freeze(policy)` is a reasonable thing for a host to do,
|
|
64
|
+
* and assigning to a frozen property throws a TypeError out of the constructor
|
|
65
|
+
* under ESM strict mode. A firewall that refuses to be constructed because the
|
|
66
|
+
* config was immutable is not a firewall.
|
|
50
67
|
*/
|
|
51
|
-
private
|
|
68
|
+
private normalizePolicy;
|
|
52
69
|
/** Build the standard gate chain: static → threat → origin → pinning. */
|
|
53
70
|
static create(deps: WardenCreateDeps): Warden;
|
|
54
71
|
/**
|
|
@@ -57,6 +74,22 @@ export declare class Warden {
|
|
|
57
74
|
* is fatal or any finding reaches policy.blockAtSeverity.
|
|
58
75
|
*/
|
|
59
76
|
vet(server: McpServerRef, tools: ToolDef[]): Promise<WardenVerdict>;
|
|
77
|
+
/**
|
|
78
|
+
* Run one gate, converting a thrown error into a blocking finding.
|
|
79
|
+
*
|
|
80
|
+
* A gate that crashed did not clear the server, so the honest result is a
|
|
81
|
+
* finding at `high` with a zero score — which blocks at the default threshold
|
|
82
|
+
* and, under a report-only policy (`blockAtSeverity: "critical"`), is reported
|
|
83
|
+
* without blocking, exactly like every other high-severity finding.
|
|
84
|
+
*
|
|
85
|
+
* Letting the exception escape instead was worse than it looks: `vet()`
|
|
86
|
+
* rejected, so the host got no verdict at all — not the findings the earlier
|
|
87
|
+
* gates had already produced, not the per-tool partition — and whether that
|
|
88
|
+
* ended in a blocked connection or an unhandled rejection was up to the host.
|
|
89
|
+
* A store with a full disk or a custom gate with a bug should not be able to
|
|
90
|
+
* decide that.
|
|
91
|
+
*/
|
|
92
|
+
private runGate;
|
|
60
93
|
/**
|
|
61
94
|
* Record the user's approval: pin the current tool defs so future drift is
|
|
62
95
|
* detected. Idempotent — re-approving just refreshes the snapshot.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EAER,OAAO,EAEP,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EAER,OAAO,EAEP,UAAU,EAEV,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,UAAU,EAAc,MAAM,kBAAkB,CAAC;AAK1D,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAClI,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACvG,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,cAAc,YAAY,CAAC;AAU3B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,kEAAkE;IAClE,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,EAAE,UAAU;IAM5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IAWvB,yEAAyE;IACzE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM;IAU7C;;;;OAIG;IACG,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAqDzE;;;;;;;;;;;;;;OAcG;YACW,OAAO;IAiCrB;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,cAAc;CAGvB"}
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,16 @@ import { OriginGate } from "./origin.js";
|
|
|
4
4
|
import { ThreatGate } from "./threat-feed.js";
|
|
5
5
|
import { classifyTools } from "./sandbox.js";
|
|
6
6
|
import { silentLogger } from "./logger.js";
|
|
7
|
+
import { displaySafe } from "./sanitize.js";
|
|
7
8
|
export { StaticScanGate, staticScanRuleset, staticScanRulesetRef, STATIC_SCAN_RULESET_VERSION, } from "./static-scan.js";
|
|
8
|
-
export { PinningGate, canonicalToolsHash, tryCanonicalToolsHash, UNCANONICAL_TOOLS_HASH } from "./pinning.js";
|
|
9
|
+
export { PinningGate, canonicalToolsHash, tryCanonicalToolsHash, serverIdentityHash, UNCANONICAL_TOOLS_HASH } from "./pinning.js";
|
|
9
10
|
export { OriginGate } from "./origin.js";
|
|
10
11
|
export { ThreatFeed, ThreatGate, DEFAULT_FEED_MAX_AGE_MS, FEED_CLOCK_SKEW_MS } from "./threat-feed.js";
|
|
11
12
|
export { EgressGuard, isSensitiveTool, classifyTools } from "./sandbox.js";
|
|
12
13
|
export { canonicalize, parseJsonStrict, CanonicalizationError, MAX_SAFE_JSON_INTEGER } from "./jcs.js";
|
|
13
14
|
export { silentLogger } from "./logger.js";
|
|
15
|
+
export { displaySafe, DEFAULT_DISPLAY_MAX } from "./sanitize.js";
|
|
16
|
+
export { wildcardMatch } from "./glob.js";
|
|
14
17
|
export * from "./types.js";
|
|
15
18
|
const SEVERITY_RANK = {
|
|
16
19
|
info: 0,
|
|
@@ -24,39 +27,53 @@ const SEVERITY_RANK = {
|
|
|
24
27
|
*
|
|
25
28
|
* Every MCP server is vetted through an ordered gate chain before its tools are
|
|
26
29
|
* exposed to the agent: cheap static scanning first, then the known-bad threat
|
|
27
|
-
* feed, then
|
|
28
|
-
* gates; the verdict is allow/block
|
|
29
|
-
* per-tool partition so a mostly-trusted
|
|
30
|
-
* quarantined without severing the whole
|
|
30
|
+
* feed, then origin (declared by the operator, or offered by a remote catalog),
|
|
31
|
+
* then drift/pinning. Findings accumulate across gates; the verdict is allow/block
|
|
32
|
+
* plus a composite 0..1 safety score and a per-tool partition so a mostly-trusted
|
|
33
|
+
* server can have one poisoned tool quarantined without severing the whole
|
|
34
|
+
* connection.
|
|
35
|
+
*
|
|
36
|
+
* The score is WARDEN's OWN — the product of what each gate contributed, computed
|
|
37
|
+
* from local facts. No reputation oracle is consulted and no socket is opened while
|
|
38
|
+
* vetting. Slot three used to be a reputation gate that asked an oracle for a score
|
|
39
|
+
* it had no data to compute; it is gone, and test/no-phantom-gate.test.ts fails if
|
|
40
|
+
* anything like it comes back.
|
|
31
41
|
*/
|
|
32
42
|
export class Warden {
|
|
33
43
|
gates;
|
|
34
44
|
policy;
|
|
35
45
|
log;
|
|
36
46
|
constructor(init) {
|
|
37
|
-
this.gates = init.gates;
|
|
38
|
-
this.policy = init.policy;
|
|
47
|
+
this.gates = [...init.gates];
|
|
39
48
|
this.log = (init.log ?? silentLogger()).child("warden");
|
|
40
|
-
this.
|
|
49
|
+
this.policy = this.normalizePolicy(init.policy);
|
|
41
50
|
}
|
|
42
51
|
/**
|
|
43
|
-
* Guard against config typos that silently disable blocking
|
|
44
|
-
*
|
|
45
|
-
*
|
|
52
|
+
* Guard against config typos that silently disable blocking, on a COPY.
|
|
53
|
+
*
|
|
54
|
+
* If `blockAtSeverity` isn't a valid Severity key, `SEVERITY_RANK[bad]` is
|
|
55
|
+
* undefined and every comparison `number >= undefined` is false — zero blocks,
|
|
56
|
+
* zero warnings — so the value is repaired. Repairing it in place used to write
|
|
57
|
+
* into the host's own policy object, which is both a surprise (their config
|
|
58
|
+
* silently changes under them, and any other Warden sharing the object sees it)
|
|
59
|
+
* and a crash: `Object.freeze(policy)` is a reasonable thing for a host to do,
|
|
60
|
+
* and assigning to a frozen property throws a TypeError out of the constructor
|
|
61
|
+
* under ESM strict mode. A firewall that refuses to be constructed because the
|
|
62
|
+
* config was immutable is not a firewall.
|
|
46
63
|
*/
|
|
47
|
-
|
|
64
|
+
normalizePolicy(policy) {
|
|
48
65
|
const valid = ["info", "low", "medium", "high", "critical"];
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
66
|
+
if (valid.includes(policy.blockAtSeverity))
|
|
67
|
+
return { ...policy };
|
|
68
|
+
const fallback = "high";
|
|
69
|
+
this.log.warn(`WARDEN: invalid blockAtSeverity "${displaySafe(policy.blockAtSeverity, 40)}" ` +
|
|
70
|
+
`(expected one of ${valid.join(", ")}) — falling back to "${fallback}" to keep blocking enabled`);
|
|
71
|
+
return { ...policy, blockAtSeverity: fallback };
|
|
55
72
|
}
|
|
56
73
|
/** Build the standard gate chain: static → threat → origin → pinning. */
|
|
57
74
|
static create(deps) {
|
|
58
75
|
const gates = [
|
|
59
|
-
new StaticScanGate(),
|
|
76
|
+
new StaticScanGate(deps.log),
|
|
60
77
|
new ThreatGate(deps.threatFeed),
|
|
61
78
|
new OriginGate(),
|
|
62
79
|
new PinningGate(deps.store),
|
|
@@ -75,12 +92,7 @@ export class Warden {
|
|
|
75
92
|
let decidedBy;
|
|
76
93
|
const blockThreshold = SEVERITY_RANK[this.policy.blockAtSeverity];
|
|
77
94
|
for (const gate of this.gates) {
|
|
78
|
-
const result = await
|
|
79
|
-
server,
|
|
80
|
-
tools,
|
|
81
|
-
prior: [...findings],
|
|
82
|
-
policy: this.policy,
|
|
83
|
-
});
|
|
95
|
+
const result = await this.runGate(gate, server, tools, findings);
|
|
84
96
|
findings.push(...result.findings);
|
|
85
97
|
scores.push(clamp01(result.score));
|
|
86
98
|
// Advisory findings never block, at any threshold — see WardenFinding.advisory.
|
|
@@ -91,7 +103,7 @@ export class Warden {
|
|
|
91
103
|
decidedBy = gate.name;
|
|
92
104
|
}
|
|
93
105
|
if (result.fatal) {
|
|
94
|
-
this.log.warn(`gate "${gate.name}" returned fatal for server ${server.id}`);
|
|
106
|
+
this.log.warn(`gate "${displaySafe(gate.name, 60)}" returned fatal for server ${displaySafe(server.id)}`);
|
|
95
107
|
break; // short-circuit only on an explicit fatal
|
|
96
108
|
}
|
|
97
109
|
}
|
|
@@ -100,10 +112,11 @@ export class Warden {
|
|
|
100
112
|
const score = scores.reduce((acc, s) => acc * s, 1);
|
|
101
113
|
const { allowedTools, blockedTools } = this.partitionTools(tools, findings, blockThreshold);
|
|
102
114
|
if (!allow) {
|
|
103
|
-
this.log.warn(`BLOCK ${server.id} (decidedBy=${decidedBy
|
|
115
|
+
this.log.warn(`BLOCK ${displaySafe(server.id)} (decidedBy=${displaySafe(decidedBy ?? "-", 60)}, ` +
|
|
116
|
+
`score=${score.toFixed(3)}, findings=${findings.length})`);
|
|
104
117
|
}
|
|
105
118
|
else {
|
|
106
|
-
this.log.info(`ALLOW ${server.id} (score=${score.toFixed(3)}, sensitive=${blockedTools.length === 0 ? this.sensitiveCount(tools) : "?"})`);
|
|
119
|
+
this.log.info(`ALLOW ${displaySafe(server.id)} (score=${score.toFixed(3)}, sensitive=${blockedTools.length === 0 ? this.sensitiveCount(tools) : "?"})`);
|
|
107
120
|
}
|
|
108
121
|
return {
|
|
109
122
|
allow,
|
|
@@ -115,6 +128,48 @@ export class Warden {
|
|
|
115
128
|
rulesets: { staticScan: staticScanRulesetRef() },
|
|
116
129
|
};
|
|
117
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Run one gate, converting a thrown error into a blocking finding.
|
|
133
|
+
*
|
|
134
|
+
* A gate that crashed did not clear the server, so the honest result is a
|
|
135
|
+
* finding at `high` with a zero score — which blocks at the default threshold
|
|
136
|
+
* and, under a report-only policy (`blockAtSeverity: "critical"`), is reported
|
|
137
|
+
* without blocking, exactly like every other high-severity finding.
|
|
138
|
+
*
|
|
139
|
+
* Letting the exception escape instead was worse than it looks: `vet()`
|
|
140
|
+
* rejected, so the host got no verdict at all — not the findings the earlier
|
|
141
|
+
* gates had already produced, not the per-tool partition — and whether that
|
|
142
|
+
* ended in a blocked connection or an unhandled rejection was up to the host.
|
|
143
|
+
* A store with a full disk or a custom gate with a bug should not be able to
|
|
144
|
+
* decide that.
|
|
145
|
+
*/
|
|
146
|
+
async runGate(gate, server, tools, prior) {
|
|
147
|
+
try {
|
|
148
|
+
const result = await gate.evaluate({ server, tools, prior: [...prior], policy: this.policy });
|
|
149
|
+
// A third-party gate is not obliged to be well-behaved either.
|
|
150
|
+
return {
|
|
151
|
+
findings: Array.isArray(result?.findings) ? result.findings : [],
|
|
152
|
+
score: typeof result?.score === "number" ? result.score : 0,
|
|
153
|
+
...(result?.fatal ? { fatal: true } : {}),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
158
|
+
this.log.error(`gate "${displaySafe(gate.name, 60)}" threw: ${displaySafe(detail, 300)}`);
|
|
159
|
+
return {
|
|
160
|
+
findings: [
|
|
161
|
+
{
|
|
162
|
+
gate: gate.name,
|
|
163
|
+
severity: "high",
|
|
164
|
+
code: "GATE_ERROR",
|
|
165
|
+
message: `Gate "${displaySafe(gate.name, 60)}" failed to complete (${displaySafe(detail, 300)}), so this ` +
|
|
166
|
+
`server was not checked by it.`,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
score: 0,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
118
173
|
/**
|
|
119
174
|
* Record the user's approval: pin the current tool defs so future drift is
|
|
120
175
|
* detected. Idempotent — re-approving just refreshes the snapshot.
|
|
@@ -126,7 +181,7 @@ export class Warden {
|
|
|
126
181
|
return;
|
|
127
182
|
}
|
|
128
183
|
await pinning.pin(server, tools);
|
|
129
|
-
this.log.info(`pinned tool defs for ${server.id} (${tools.length} tools)`);
|
|
184
|
+
this.log.info(`pinned tool defs for ${displaySafe(server.id)} (${tools.length} tools)`);
|
|
130
185
|
}
|
|
131
186
|
/**
|
|
132
187
|
* A tool is blocked if a finding naming it reaches the block threshold.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC MCP methods for the stdio server (no transport).
|
|
3
|
+
*/
|
|
4
|
+
export declare const PROTOCOL = "2025-03-26";
|
|
5
|
+
export declare function packageVersion(): string;
|
|
6
|
+
export interface JsonRpcReq {
|
|
7
|
+
jsonrpc?: string;
|
|
8
|
+
id?: string | number | null;
|
|
9
|
+
method?: string;
|
|
10
|
+
params?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface JsonRpcRes {
|
|
13
|
+
jsonrpc: "2.0";
|
|
14
|
+
id: string | number | null;
|
|
15
|
+
result?: unknown;
|
|
16
|
+
error?: {
|
|
17
|
+
code: number;
|
|
18
|
+
message: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function listedTools(): {
|
|
22
|
+
name: string;
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
inputSchema: Record<string, unknown>;
|
|
26
|
+
outputSchema: Record<string, unknown>;
|
|
27
|
+
annotations: {
|
|
28
|
+
title: string;
|
|
29
|
+
readOnlyHint: boolean;
|
|
30
|
+
destructiveHint: boolean;
|
|
31
|
+
idempotentHint: boolean;
|
|
32
|
+
openWorldHint: boolean;
|
|
33
|
+
};
|
|
34
|
+
}[];
|
|
35
|
+
export declare function consumeLsp(buf: Buffer): {
|
|
36
|
+
rest: Buffer;
|
|
37
|
+
bodies: string[];
|
|
38
|
+
};
|
|
39
|
+
export declare function handleRpc(msg: JsonRpcReq): Promise<JsonRpcRes | null>;
|
|
40
|
+
//# sourceMappingURL=mcp-rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-rpc.d.ts","sourceRoot":"","sources":["../src/mcp-rpc.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAO,MAAM,QAAQ,eAAe,CAAC;AAGrC,wBAAgB,cAAc,IAAI,MAAM,CAQvC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C;AAED,wBAAgB,WAAW;;;;;;;;;;;;;IAS1B;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAiB1E;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgE3E"}
|
package/dist/mcp-rpc.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC MCP methods for the stdio server (no transport).
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { callMcpTool, MCP_INSTRUCTIONS, MCP_TOOLS, McpToolError, payloadTooLarge } from "./mcp-tools.js";
|
|
8
|
+
export const PROTOCOL = "2025-03-26";
|
|
9
|
+
const FALLBACK_VERSION = "0.5.0";
|
|
10
|
+
export function packageVersion() {
|
|
11
|
+
try {
|
|
12
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
13
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
14
|
+
return typeof pkg.version === "string" ? pkg.version : FALLBACK_VERSION;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return FALLBACK_VERSION;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function listedTools() {
|
|
21
|
+
return MCP_TOOLS.map((t) => ({
|
|
22
|
+
name: t.name,
|
|
23
|
+
title: t.title,
|
|
24
|
+
description: t.description,
|
|
25
|
+
inputSchema: t.inputSchema,
|
|
26
|
+
outputSchema: t.outputSchema,
|
|
27
|
+
annotations: t.annotations,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
export function consumeLsp(buf) {
|
|
31
|
+
const bodies = [];
|
|
32
|
+
while (true) {
|
|
33
|
+
const headerEnd = buf.indexOf("\r\n\r\n");
|
|
34
|
+
if (headerEnd < 0)
|
|
35
|
+
return { rest: buf, bodies };
|
|
36
|
+
const header = buf.subarray(0, headerEnd).toString("ascii");
|
|
37
|
+
const match = /Content-Length:\s*(\d+)/i.exec(header);
|
|
38
|
+
if (!match) {
|
|
39
|
+
buf = buf.subarray(headerEnd + 4);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const len = Number(match[1]);
|
|
43
|
+
const start = headerEnd + 4;
|
|
44
|
+
if (buf.length < start + len)
|
|
45
|
+
return { rest: buf, bodies };
|
|
46
|
+
bodies.push(buf.subarray(start, start + len).toString("utf8"));
|
|
47
|
+
buf = buf.subarray(start + len);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function handleRpc(msg) {
|
|
51
|
+
const method = msg.method ?? "";
|
|
52
|
+
const id = msg.id;
|
|
53
|
+
if (method.startsWith("notifications/"))
|
|
54
|
+
return null;
|
|
55
|
+
const ok = (result) => ({ jsonrpc: "2.0", id: id ?? null, result });
|
|
56
|
+
const fail = (code, message) => ({
|
|
57
|
+
jsonrpc: "2.0",
|
|
58
|
+
id: id ?? null,
|
|
59
|
+
error: { code, message },
|
|
60
|
+
});
|
|
61
|
+
switch (method) {
|
|
62
|
+
case "initialize":
|
|
63
|
+
return ok({
|
|
64
|
+
protocolVersion: PROTOCOL,
|
|
65
|
+
capabilities: { tools: { listChanged: false } },
|
|
66
|
+
serverInfo: {
|
|
67
|
+
name: "warden",
|
|
68
|
+
title: "WARDEN MCP security firewall",
|
|
69
|
+
version: packageVersion(),
|
|
70
|
+
},
|
|
71
|
+
instructions: MCP_INSTRUCTIONS,
|
|
72
|
+
});
|
|
73
|
+
case "ping":
|
|
74
|
+
return ok({});
|
|
75
|
+
case "tools/list":
|
|
76
|
+
return ok({ tools: listedTools() });
|
|
77
|
+
case "tools/call": {
|
|
78
|
+
if (id === undefined)
|
|
79
|
+
return null;
|
|
80
|
+
const params = (msg.params ?? {});
|
|
81
|
+
const name = typeof params.name === "string" ? params.name : "";
|
|
82
|
+
if (!name)
|
|
83
|
+
return fail(-32602, "tools/call requires params.name");
|
|
84
|
+
const args = params.arguments && typeof params.arguments === "object" && !Array.isArray(params.arguments)
|
|
85
|
+
? params.arguments
|
|
86
|
+
: {};
|
|
87
|
+
if (payloadTooLarge(args)) {
|
|
88
|
+
return ok({ content: [{ type: "text", text: "payload exceeds 256 KiB" }], isError: true });
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const { structured } = await callMcpTool(name, args);
|
|
92
|
+
return ok({
|
|
93
|
+
content: [{ type: "text", text: JSON.stringify(structured, null, 2) }],
|
|
94
|
+
structuredContent: structured,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
99
|
+
if (!(err instanceof McpToolError) && !(err instanceof Error)) {
|
|
100
|
+
return ok({ content: [{ type: "text", text: String(err) }], isError: true });
|
|
101
|
+
}
|
|
102
|
+
return ok({ content: [{ type: "text", text: message }], isError: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
case "resources/list":
|
|
106
|
+
return ok({ resources: [] });
|
|
107
|
+
case "resources/templates/list":
|
|
108
|
+
return ok({ resourceTemplates: [] });
|
|
109
|
+
case "prompts/list":
|
|
110
|
+
return ok({ prompts: [] });
|
|
111
|
+
default:
|
|
112
|
+
if (id === undefined)
|
|
113
|
+
return null;
|
|
114
|
+
return fail(-32601, `method not found: ${method}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=mcp-rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-rpc.js","sourceRoot":"","sources":["../src/mcp-rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WARDEN stdio MCP server — Glama / Claude Desktop / Cursor.
|
|
4
|
+
*
|
|
5
|
+
* stdout is the MCP wire. Logs go to stderr. No environment variables required.
|
|
6
|
+
* Speaks LSP-style Content-Length framing (official SDK / mcp-proxy) and
|
|
7
|
+
* newline-delimited JSON as a fallback for simple probes.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WARDEN stdio MCP server — Glama / Claude Desktop / Cursor.
|
|
4
|
+
*
|
|
5
|
+
* stdout is the MCP wire. Logs go to stderr. No environment variables required.
|
|
6
|
+
* Speaks LSP-style Content-Length framing (official SDK / mcp-proxy) and
|
|
7
|
+
* newline-delimited JSON as a fallback for simple probes.
|
|
8
|
+
*/
|
|
9
|
+
import { stderr, stdin, stdout } from "node:process";
|
|
10
|
+
import { consumeLsp, handleRpc } from "./mcp-rpc.js";
|
|
11
|
+
function writeMessage(msg) {
|
|
12
|
+
const body = Buffer.from(JSON.stringify(msg), "utf8");
|
|
13
|
+
stdout.write(`Content-Length: ${body.length}\r\n\r\n`);
|
|
14
|
+
stdout.write(body);
|
|
15
|
+
}
|
|
16
|
+
async function dispatchBody(body) {
|
|
17
|
+
let parsed;
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse(body);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
writeMessage({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "parse error" } });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const res = await handleRpc(parsed);
|
|
26
|
+
if (res)
|
|
27
|
+
writeMessage(res);
|
|
28
|
+
}
|
|
29
|
+
function skipWs(buf) {
|
|
30
|
+
let i = 0;
|
|
31
|
+
while (i < buf.length) {
|
|
32
|
+
const b = buf[i];
|
|
33
|
+
if (b !== 0x20 && b !== 0x09 && b !== 0x0a && b !== 0x0d)
|
|
34
|
+
break;
|
|
35
|
+
i++;
|
|
36
|
+
}
|
|
37
|
+
return buf.subarray(i);
|
|
38
|
+
}
|
|
39
|
+
async function main() {
|
|
40
|
+
let buf = Buffer.from([]);
|
|
41
|
+
let mode = "unknown";
|
|
42
|
+
let ndjson = "";
|
|
43
|
+
for await (const chunk of stdin) {
|
|
44
|
+
const piece = Buffer.from(chunk);
|
|
45
|
+
if (mode === "unknown") {
|
|
46
|
+
buf = Buffer.concat([buf, piece]);
|
|
47
|
+
const trimmed = skipWs(buf);
|
|
48
|
+
if (trimmed.length === 0)
|
|
49
|
+
continue;
|
|
50
|
+
if (trimmed[0] === 0x7b) {
|
|
51
|
+
mode = "ndjson";
|
|
52
|
+
ndjson = buf.toString("utf8");
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
mode = "lsp";
|
|
56
|
+
const { rest, bodies } = consumeLsp(buf);
|
|
57
|
+
buf = Buffer.from(rest);
|
|
58
|
+
for (const body of bodies)
|
|
59
|
+
await dispatchBody(body);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (mode === "lsp") {
|
|
63
|
+
buf = Buffer.concat([buf, piece]);
|
|
64
|
+
const { rest, bodies } = consumeLsp(buf);
|
|
65
|
+
buf = Buffer.from(rest);
|
|
66
|
+
for (const body of bodies)
|
|
67
|
+
await dispatchBody(body);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
ndjson += piece.toString("utf8");
|
|
71
|
+
}
|
|
72
|
+
if (mode === "ndjson") {
|
|
73
|
+
const lines = ndjson.split("\n");
|
|
74
|
+
ndjson = lines.pop() ?? "";
|
|
75
|
+
for (const line of lines) {
|
|
76
|
+
const trimmed = line.trim();
|
|
77
|
+
if (trimmed)
|
|
78
|
+
await dispatchBody(trimmed);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (mode === "ndjson" && ndjson.trim())
|
|
83
|
+
await dispatchBody(ndjson.trim());
|
|
84
|
+
}
|
|
85
|
+
main().catch((err) => {
|
|
86
|
+
stderr.write(`warden-mcp: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool surface for the WARDEN stdio server.
|
|
3
|
+
*
|
|
4
|
+
* These definitions are scored by Glama TDQS. Each tool: a title longer than
|
|
5
|
+
* the name, when-to-use / when-not naming a sibling, MCP annotations that match
|
|
6
|
+
* behaviour, every input property described, and an output schema so the
|
|
7
|
+
* description does not have to narrate the return shape.
|
|
8
|
+
*
|
|
9
|
+
* All six tools are local, deterministic, and perform no network I/O. The
|
|
10
|
+
* stdio process uses the built-in threat-feed floor and an empty pin store —
|
|
11
|
+
* it is a scanner, not a long-lived host.
|
|
12
|
+
*/
|
|
13
|
+
import type { WardenPolicy } from "./types.js";
|
|
14
|
+
export declare const MAX_TOOLS = 256;
|
|
15
|
+
export declare const MAX_STRING = 16384;
|
|
16
|
+
export declare const MAX_PAYLOAD_CHARS = 256000;
|
|
17
|
+
export declare const DEFAULT_MCP_POLICY: WardenPolicy;
|
|
18
|
+
export interface McpToolDef {
|
|
19
|
+
name: string;
|
|
20
|
+
title: string;
|
|
21
|
+
description: string;
|
|
22
|
+
annotations: {
|
|
23
|
+
title: string;
|
|
24
|
+
readOnlyHint: boolean;
|
|
25
|
+
destructiveHint: boolean;
|
|
26
|
+
idempotentHint: boolean;
|
|
27
|
+
openWorldHint: boolean;
|
|
28
|
+
};
|
|
29
|
+
inputSchema: Record<string, unknown>;
|
|
30
|
+
outputSchema: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
export declare const MCP_TOOLS: McpToolDef[];
|
|
33
|
+
export declare const MCP_INSTRUCTIONS: string;
|
|
34
|
+
export declare class McpToolError extends Error {
|
|
35
|
+
constructor(message: string);
|
|
36
|
+
}
|
|
37
|
+
export interface ToolCallResult {
|
|
38
|
+
structured: object;
|
|
39
|
+
}
|
|
40
|
+
export declare function callMcpTool(name: string, args: Record<string, unknown>): Promise<ToolCallResult>;
|
|
41
|
+
export declare function payloadTooLarge(args: unknown): boolean;
|
|
42
|
+
//# sourceMappingURL=mcp-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,OAAO,KAAK,EAKV,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,UAAU,QAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAIzC,eAAO,MAAM,kBAAkB,EAAE,YAKhC,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,OAAO,CAAC;QACxB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AA0DD,eAAO,MAAM,SAAS,EAAE,UAAU,EAwXjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,QASgK,CAAC;AAkF9L,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBtG;AA+FD,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAMtD"}
|