@cybedefend/vibedefend 1.4.7 → 1.6.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 (246) hide show
  1. package/README.md +77 -2
  2. package/dist/api/gateway-request.js +49 -0
  3. package/dist/api/gateway-request.js.map +1 -0
  4. package/dist/api/projects.js +67 -0
  5. package/dist/api/projects.js.map +1 -1
  6. package/dist/api/repository-link.js +157 -0
  7. package/dist/api/repository-link.js.map +1 -0
  8. package/dist/auth/auth-store.js +107 -25
  9. package/dist/auth/auth-store.js.map +1 -1
  10. package/dist/auth/auth.js +21 -0
  11. package/dist/auth/auth.js.map +1 -1
  12. package/dist/clients/cursor.js +5 -1
  13. package/dist/clients/cursor.js.map +1 -1
  14. package/dist/clients/vscode.js +38 -29
  15. package/dist/clients/vscode.js.map +1 -1
  16. package/dist/commands/mcp/allow.js +219 -0
  17. package/dist/commands/mcp/allow.js.map +1 -0
  18. package/dist/commands/mcp/connect.js +337 -0
  19. package/dist/commands/mcp/connect.js.map +1 -0
  20. package/dist/commands/mcp/index.js +170 -0
  21. package/dist/commands/mcp/index.js.map +1 -0
  22. package/dist/commands/mcp/proxy.js +264 -0
  23. package/dist/commands/mcp/proxy.js.map +1 -0
  24. package/dist/commands/mcp/scan.js +349 -0
  25. package/dist/commands/mcp/scan.js.map +1 -0
  26. package/dist/commands/mcp/sync.js +215 -0
  27. package/dist/commands/mcp/sync.js.map +1 -0
  28. package/dist/config.js +6 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/diagnostics.js +78 -12
  31. package/dist/diagnostics.js.map +1 -1
  32. package/dist/doctor.js +19 -0
  33. package/dist/doctor.js.map +1 -1
  34. package/dist/guards-evaluator/analysis-types.js +27 -0
  35. package/dist/guards-evaluator/analysis-types.js.map +1 -0
  36. package/dist/guards-evaluator/command-analysis.js +572 -0
  37. package/dist/guards-evaluator/command-analysis.js.map +1 -0
  38. package/dist/guards-evaluator/command-view.js +586 -0
  39. package/dist/guards-evaluator/command-view.js.map +1 -0
  40. package/dist/guards-evaluator/env.js +11 -0
  41. package/dist/guards-evaluator/env.js.map +1 -0
  42. package/dist/guards-evaluator/evaluate.js +91 -41
  43. package/dist/guards-evaluator/evaluate.js.map +1 -1
  44. package/dist/guards-evaluator/index.js +2 -1
  45. package/dist/guards-evaluator/index.js.map +1 -1
  46. package/dist/guards-evaluator/inline-code.js +259 -0
  47. package/dist/guards-evaluator/inline-code.js.map +1 -0
  48. package/dist/guards-evaluator/normalize.js +716 -0
  49. package/dist/guards-evaluator/normalize.js.map +1 -0
  50. package/dist/guards-evaluator/preprocess.js +13 -5
  51. package/dist/guards-evaluator/preprocess.js.map +1 -1
  52. package/dist/guards-evaluator/redact.js +19 -0
  53. package/dist/guards-evaluator/redact.js.map +1 -1
  54. package/dist/guards-evaluator/regex.js +25 -3
  55. package/dist/guards-evaluator/regex.js.map +1 -1
  56. package/dist/guards-evaluator/safe-commands.js +155 -0
  57. package/dist/guards-evaluator/safe-commands.js.map +1 -0
  58. package/dist/guards-evaluator/triage.js +315 -0
  59. package/dist/guards-evaluator/triage.js.map +1 -0
  60. package/dist/hook-runner.js +24873 -5068
  61. package/dist/hooks/install.js +38 -0
  62. package/dist/hooks/install.js.map +1 -1
  63. package/dist/hooks/runtime/config.js +38 -0
  64. package/dist/hooks/runtime/config.js.map +1 -1
  65. package/dist/hooks/runtime/emit.js +126 -53
  66. package/dist/hooks/runtime/emit.js.map +1 -1
  67. package/dist/hooks/runtime/fetch-rules.js +27 -7
  68. package/dist/hooks/runtime/fetch-rules.js.map +1 -1
  69. package/dist/hooks/runtime/gateway-http-error.js +34 -0
  70. package/dist/hooks/runtime/gateway-http-error.js.map +1 -0
  71. package/dist/hooks/runtime/guard-rules-cache.js +139 -17
  72. package/dist/hooks/runtime/guard-rules-cache.js.map +1 -1
  73. package/dist/hooks/runtime/guard-violations-buffer.js +321 -48
  74. package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
  75. package/dist/hooks/runtime/judge-cache.js +6 -0
  76. package/dist/hooks/runtime/judge-cache.js.map +1 -1
  77. package/dist/hooks/runtime/judge-triage.js +193 -0
  78. package/dist/hooks/runtime/judge-triage.js.map +1 -0
  79. package/dist/hooks/runtime/judge.js +7 -1
  80. package/dist/hooks/runtime/judge.js.map +1 -1
  81. package/dist/hooks/runtime/pre-compact.js +21 -6
  82. package/dist/hooks/runtime/pre-compact.js.map +1 -1
  83. package/dist/hooks/runtime/resolve.js +108 -17
  84. package/dist/hooks/runtime/resolve.js.map +1 -1
  85. package/dist/hooks/runtime/retry-policy.js +57 -0
  86. package/dist/hooks/runtime/retry-policy.js.map +1 -0
  87. package/dist/hooks/runtime/review-sessions.js +74 -0
  88. package/dist/hooks/runtime/review-sessions.js.map +1 -0
  89. package/dist/hooks/runtime/script-resolve.js +695 -0
  90. package/dist/hooks/runtime/script-resolve.js.map +1 -0
  91. package/dist/hooks/runtime/session-activation.js +226 -0
  92. package/dist/hooks/runtime/session-activation.js.map +1 -0
  93. package/dist/hooks/runtime/session-review.js +174 -46
  94. package/dist/hooks/runtime/session-review.js.map +1 -1
  95. package/dist/hooks/runtime/session-start.js +35 -4
  96. package/dist/hooks/runtime/session-start.js.map +1 -1
  97. package/dist/hooks/runtime/session-writes.js +232 -0
  98. package/dist/hooks/runtime/session-writes.js.map +1 -0
  99. package/dist/hooks/runtime/sniff.js +26 -7
  100. package/dist/hooks/runtime/sniff.js.map +1 -1
  101. package/dist/hooks/runtime/target-resolve.js +336 -0
  102. package/dist/hooks/runtime/target-resolve.js.map +1 -0
  103. package/dist/hooks/runtime/unmapped-tools.js +93 -0
  104. package/dist/hooks/runtime/unmapped-tools.js.map +1 -0
  105. package/dist/hooks/runtime/usage-block.js +4 -0
  106. package/dist/hooks/runtime/usage-block.js.map +1 -1
  107. package/dist/hooks/runtime/user-prompt-submit.js +8 -2
  108. package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
  109. package/dist/hooks/runtime/wire-text.js +41 -0
  110. package/dist/hooks/runtime/wire-text.js.map +1 -0
  111. package/dist/hooks/runtime/work-dir.js +84 -0
  112. package/dist/hooks/runtime/work-dir.js.map +1 -0
  113. package/dist/index.js +45 -12
  114. package/dist/index.js.map +1 -1
  115. package/dist/install.js +174 -11
  116. package/dist/install.js.map +1 -1
  117. package/dist/link.js +74 -48
  118. package/dist/link.js.map +1 -1
  119. package/dist/login.js +99 -14
  120. package/dist/login.js.map +1 -1
  121. package/dist/mcp/auth/agent-sign-ins.js +174 -0
  122. package/dist/mcp/auth/agent-sign-ins.js.map +1 -0
  123. package/dist/mcp/auth/callback.js +200 -0
  124. package/dist/mcp/auth/callback.js.map +1 -0
  125. package/dist/mcp/auth/connect.js +392 -0
  126. package/dist/mcp/auth/connect.js.map +1 -0
  127. package/dist/mcp/auth/discovery.js +399 -0
  128. package/dist/mcp/auth/discovery.js.map +1 -0
  129. package/dist/mcp/auth/oauth.js +326 -0
  130. package/dist/mcp/auth/oauth.js.map +1 -0
  131. package/dist/mcp/auth/probe.js +128 -0
  132. package/dist/mcp/auth/probe.js.map +1 -0
  133. package/dist/mcp/auth/secrets.js +446 -0
  134. package/dist/mcp/auth/secrets.js.map +1 -0
  135. package/dist/mcp/auth/store.js +260 -0
  136. package/dist/mcp/auth/store.js.map +1 -0
  137. package/dist/mcp/auth/tokenSource.js +55 -0
  138. package/dist/mcp/auth/tokenSource.js.map +1 -0
  139. package/dist/mcp/config/atomicWrite.js +98 -0
  140. package/dist/mcp/config/atomicWrite.js.map +1 -0
  141. package/dist/mcp/config/clients.js +171 -0
  142. package/dist/mcp/config/clients.js.map +1 -0
  143. package/dist/mcp/config/cybedefend-servers.js +48 -0
  144. package/dist/mcp/config/cybedefend-servers.js.map +1 -0
  145. package/dist/mcp/config/discover.js +114 -0
  146. package/dist/mcp/config/discover.js.map +1 -0
  147. package/dist/mcp/config/hook.js +123 -0
  148. package/dist/mcp/config/hook.js.map +1 -0
  149. package/dist/mcp/config/index.js +11 -0
  150. package/dist/mcp/config/index.js.map +1 -0
  151. package/dist/mcp/config/install.js +132 -0
  152. package/dist/mcp/config/install.js.map +1 -0
  153. package/dist/mcp/config/installed.js +37 -0
  154. package/dist/mcp/config/installed.js.map +1 -0
  155. package/dist/mcp/config/jsonEdit.js +119 -0
  156. package/dist/mcp/config/jsonEdit.js.map +1 -0
  157. package/dist/mcp/config/lock.js +102 -0
  158. package/dist/mcp/config/lock.js.map +1 -0
  159. package/dist/mcp/config/proxyBinary.js +211 -0
  160. package/dist/mcp/config/proxyBinary.js.map +1 -0
  161. package/dist/mcp/config/rewrite.js +388 -0
  162. package/dist/mcp/config/rewrite.js.map +1 -0
  163. package/dist/mcp/config/types.js +34 -0
  164. package/dist/mcp/config/types.js.map +1 -0
  165. package/dist/mcp/proxy/audit.js +83 -0
  166. package/dist/mcp/proxy/audit.js.map +1 -0
  167. package/dist/mcp/proxy/authInterceptor.js +119 -0
  168. package/dist/mcp/proxy/authInterceptor.js.map +1 -0
  169. package/dist/mcp/proxy/expand.js +93 -0
  170. package/dist/mcp/proxy/expand.js.map +1 -0
  171. package/dist/mcp/proxy/inject.js +397 -0
  172. package/dist/mcp/proxy/inject.js.map +1 -0
  173. package/dist/mcp/proxy/intercept.js +37 -0
  174. package/dist/mcp/proxy/intercept.js.map +1 -0
  175. package/dist/mcp/proxy/jsonrpc.js +153 -0
  176. package/dist/mcp/proxy/jsonrpc.js.map +1 -0
  177. package/dist/mcp/proxy/log.js +109 -0
  178. package/dist/mcp/proxy/log.js.map +1 -0
  179. package/dist/mcp/proxy/paths.js +53 -0
  180. package/dist/mcp/proxy/paths.js.map +1 -0
  181. package/dist/mcp/proxy/proxy.js +510 -0
  182. package/dist/mcp/proxy/proxy.js.map +1 -0
  183. package/dist/mcp/proxy/spec.js +203 -0
  184. package/dist/mcp/proxy/spec.js.map +1 -0
  185. package/dist/mcp/proxy/sse.js +77 -0
  186. package/dist/mcp/proxy/sse.js.map +1 -0
  187. package/dist/mcp/proxy/upstream.js +2 -0
  188. package/dist/mcp/proxy/upstream.js.map +1 -0
  189. package/dist/mcp/proxy/upstreamHttp.js +499 -0
  190. package/dist/mcp/proxy/upstreamHttp.js.map +1 -0
  191. package/dist/mcp/proxy/upstreamStdio.js +188 -0
  192. package/dist/mcp/proxy/upstreamStdio.js.map +1 -0
  193. package/dist/mcp/proxy/upstreams.js +143 -0
  194. package/dist/mcp/proxy/upstreams.js.map +1 -0
  195. package/dist/mcp/proxy/verifyInterceptor.js +559 -0
  196. package/dist/mcp/proxy/verifyInterceptor.js.map +1 -0
  197. package/dist/mcp/proxy/windowsCommand.js +99 -0
  198. package/dist/mcp/proxy/windowsCommand.js.map +1 -0
  199. package/dist/mcp/scan/args.js +228 -0
  200. package/dist/mcp/scan/args.js.map +1 -0
  201. package/dist/mcp/scan/results.js +253 -0
  202. package/dist/mcp/scan/results.js.map +1 -0
  203. package/dist/mcp/scan/types.js +40 -0
  204. package/dist/mcp/scan/types.js.map +1 -0
  205. package/dist/mcp/verify/api.js +475 -0
  206. package/dist/mcp/verify/api.js.map +1 -0
  207. package/dist/mcp/verify/backend.js +143 -0
  208. package/dist/mcp/verify/backend.js.map +1 -0
  209. package/dist/mcp/verify/cache.js +182 -0
  210. package/dist/mcp/verify/cache.js.map +1 -0
  211. package/dist/mcp/verify/contract-errors.js +198 -0
  212. package/dist/mcp/verify/contract-errors.js.map +1 -0
  213. package/dist/mcp/verify/digest.js +91 -0
  214. package/dist/mcp/verify/digest.js.map +1 -0
  215. package/dist/mcp/verify/factory.js +56 -0
  216. package/dist/mcp/verify/factory.js.map +1 -0
  217. package/dist/mcp/verify/identity.js +173 -0
  218. package/dist/mcp/verify/identity.js.map +1 -0
  219. package/dist/mcp/verify/policy-store.js +63 -0
  220. package/dist/mcp/verify/policy-store.js.map +1 -0
  221. package/dist/mcp/verify/policy.js +158 -0
  222. package/dist/mcp/verify/policy.js.map +1 -0
  223. package/dist/mcp/verify/pool.js +27 -0
  224. package/dist/mcp/verify/pool.js.map +1 -0
  225. package/dist/mcp/verify/token-refresh.js +44 -0
  226. package/dist/mcp/verify/token-refresh.js.map +1 -0
  227. package/dist/mcp/verify/token.js +67 -0
  228. package/dist/mcp/verify/token.js.map +1 -0
  229. package/dist/mcp/verify/verifier.js +1009 -0
  230. package/dist/mcp/verify/verifier.js.map +1 -0
  231. package/dist/org-gate.js +1 -1
  232. package/dist/org-gate.js.map +1 -1
  233. package/dist/org.js +146 -0
  234. package/dist/org.js.map +1 -0
  235. package/dist/project-create.js +129 -0
  236. package/dist/project-create.js.map +1 -0
  237. package/dist/prompts.js +21 -0
  238. package/dist/prompts.js.map +1 -1
  239. package/dist/re2.wasm +0 -0
  240. package/dist/status.js +61 -0
  241. package/dist/status.js.map +1 -1
  242. package/dist/uninstall.js +49 -4
  243. package/dist/uninstall.js.map +1 -1
  244. package/dist/utils.js +62 -6
  245. package/dist/utils.js.map +1 -1
  246. package/package.json +10 -3
@@ -0,0 +1,559 @@
1
+ /**
2
+ * Where verification meets the forwarding loop.
3
+ *
4
+ * The loop's job is to move messages; deciding what a tool list means is this
5
+ * file's. It plugs into the `Interceptor` seam Phase 1 left, and touches
6
+ * exactly three things:
7
+ *
8
+ * - a `tools/list` RESPONSE, which it may replace;
9
+ * - a `tools/call` REQUEST for one of the proxy's own tools, which it
10
+ * answers itself and never forwards — the upstream has never heard of
11
+ * `vibedefend_alert` and would return an error the agent would relay as
12
+ * a bug of ours;
13
+ * - a `tools/call` REQUEST, which is where the judgement is BOUGHT — for
14
+ * the called tool only (`verifyOne`) — and where the SERVER'S ACTION is
15
+ * executed: on a BLOCKED server it is refused outright (hiding the list
16
+ * is not locking the door — an agent that remembers a tool name can
17
+ * still call it); a tool the server blocks is refused the same way; a
18
+ * tool the server says to ASK about has the user asked, through MCP
19
+ * elicitation, whether to send the call anyway — once per server and
20
+ * session on a yes, every time on a no; a tool the server only WARNS
21
+ * about goes through, its result framed. A client that cannot be asked
22
+ * (no `elicitation` capability) gets the previous behaviour: the call
23
+ * goes through, `vibedefend_alert` was in the list. Never fail-open on a
24
+ * question that WAS asked and got no answer;
25
+ * - `notifications/tools/list_changed`, which it notes and lets through so
26
+ * the client asks again;
27
+ * - `notifications/cancelled` from the agent, for a call still waiting on
28
+ * the user: the call is dropped, unanswered, and the notification is not
29
+ * forwarded — the upstream never saw the call. Any other cancellation
30
+ * passes through.
31
+ *
32
+ * Everything else passes untouched, which is the whole point of the seam.
33
+ */
34
+ import { applyToToolsList, CONFIRMATION_SCHEMA, confirmationPrompt, isSyntheticTool, prefixResult, refusedCallResponse, replaceResult, syntheticCallResponse, } from './inject.js';
35
+ import { scanArguments } from '../scan/args.js';
36
+ import { scanResult } from '../scan/results.js';
37
+ import { toolDigest } from '../verify/digest.js';
38
+ import { idKey, isRequest, isResponse, methodOf } from './jsonrpc.js';
39
+ /**
40
+ * How long a question may stay on screen. A user who is away is not a user
41
+ * who said yes: past this, the call is refused and the agent is told why.
42
+ */
43
+ export const CONFIRMATION_TIMEOUT_MS = 5 * 60 * 1000;
44
+ /**
45
+ * A call's seat in the queue for the user, and the way to pull it out.
46
+ *
47
+ * `race` settles with the user's answer or, if the agent sends
48
+ * `notifications/cancelled` for the call first, with a no — the call is
49
+ * dropped either way, but the caller can tell which, and only the former is
50
+ * answered.
51
+ */
52
+ class Cancellation {
53
+ tool;
54
+ cancelled = false;
55
+ signal;
56
+ settle = () => undefined;
57
+ constructor(tool) {
58
+ this.tool = tool;
59
+ this.signal = new Promise((resolve) => {
60
+ this.settle = resolve;
61
+ });
62
+ }
63
+ cancel() {
64
+ this.cancelled = true;
65
+ this.settle({ proceed: false, remember: false });
66
+ }
67
+ race(answer) {
68
+ return Promise.race([answer, this.signal]);
69
+ }
70
+ }
71
+ /**
72
+ * The last finding, so a call to a synthetic tool can answer with the detail
73
+ * that produced it rather than re-running a verification.
74
+ */
75
+ const NO_FINDING = {
76
+ serverName: 'this server',
77
+ kind: 'no finding is on record',
78
+ tools: [],
79
+ };
80
+ export function createVerifyInterceptor(options) {
81
+ const { verifier, logger } = options;
82
+ /** Ids of the `tools/list` requests in flight, so the answers can be matched. */
83
+ const pendingLists = new Set();
84
+ /** Calls in flight, so a result can be scanned knowing which tool it is from. */
85
+ const pendingCalls = new Map();
86
+ /** The last list, for the schema a call's arguments are judged against. */
87
+ let knownTools = new Map();
88
+ let lastFinding = NO_FINDING;
89
+ /** The last verification, for the gate a `tools/call` goes through. */
90
+ let lastOutcome;
91
+ /** The user said yes for this server, for the rest of the session. */
92
+ let confirmed = false;
93
+ /** A question already on screen: calls that arrive meanwhile wait for its answer. */
94
+ let openQuestion;
95
+ /**
96
+ * Calls waiting on the user, by request id, so a `notifications/cancelled`
97
+ * from the agent can settle the one it names. A client that gave up on the
98
+ * call has told its model the call failed; a yes that arrives afterwards
99
+ * must not send it anyway.
100
+ */
101
+ const pendingConfirmations = new Map();
102
+ let warnedCannotAsk = false;
103
+ return {
104
+ name: 'verify',
105
+ async fromAgent(message, context) {
106
+ const method = methodOf(message);
107
+ if (method === 'notifications/cancelled') {
108
+ const requestId = typeof message.params === 'object' && message.params !== null
109
+ ? message.params.requestId
110
+ : undefined;
111
+ const key = idKey(requestId);
112
+ const waiting = key ? pendingConfirmations.get(key) : undefined;
113
+ if (waiting) {
114
+ // The call is still here, waiting on the user: it never reached
115
+ // the upstream, so the upstream has nothing to cancel and must not
116
+ // hear of an id it never saw. Settle the call as declined instead.
117
+ logger.info('verify: the agent cancelled a tools/call while the user was being asked', {
118
+ tool: waiting.tool,
119
+ });
120
+ waiting.cancel();
121
+ return { action: 'drop', reason: 'the cancelled call was never forwarded' };
122
+ }
123
+ return { action: 'forward' };
124
+ }
125
+ if (isRequest(message) && method === 'tools/list') {
126
+ const key = idKey(message.id);
127
+ if (key)
128
+ pendingLists.add(key);
129
+ return { action: 'forward' };
130
+ }
131
+ if (isRequest(message) && method === 'tools/call') {
132
+ const params = typeof message.params === 'object' && message.params !== null
133
+ ? message.params
134
+ : {};
135
+ const name = params.name;
136
+ if (isSyntheticTool(name)) {
137
+ // Answered here, never forwarded: it is our tool, not theirs.
138
+ return {
139
+ action: 'respond',
140
+ message: syntheticCallResponse(message.id, String(name), lastFinding),
141
+ reason: 'a VibeDefend tool is answered by VibeDefend',
142
+ };
143
+ }
144
+ const toolName = typeof name === 'string' ? name : '(unnamed)';
145
+ // The SERVER-level gate, from the last list: a blocked server takes
146
+ // every call with it, whatever the individual tool's record says.
147
+ if (lastOutcome?.decision.action === 'block') {
148
+ logger.info('verify: refused a tools/call to a blocked server', { tool: toolName });
149
+ return {
150
+ action: 'respond',
151
+ message: refusedCallResponse(message.id, options.serverName, toolName, lastFinding, 'blocked'),
152
+ reason: 'the server is blocked',
153
+ };
154
+ }
155
+ const definition = knownTools.get(toolName);
156
+ const findings = scanArguments(params.arguments, {
157
+ spec: options.spec,
158
+ inputSchema: definition?.inputSchema,
159
+ description: definition?.description,
160
+ });
161
+ if (findings.length > 0) {
162
+ // Reported, never blocked: the plan's default here is `warn`, and a
163
+ // proxy that refused a call because a value looked like a token
164
+ // would break the tools people use to manage tokens.
165
+ logger.warn('scan: something in the arguments of a tools/call', {
166
+ tool: toolName,
167
+ findings: findings.map((finding) => finding.rule),
168
+ });
169
+ }
170
+ // The judgement, bought here and for this tool only.
171
+ let verdictFinding;
172
+ let policy = verifier.policy();
173
+ if (definition) {
174
+ const outcome = await verifier.verifyOne(definition);
175
+ policy = outcome.policy;
176
+ options.onOutcome?.({
177
+ action: outcome.decision.action,
178
+ verdict: outcome.verdict,
179
+ fromCache: outcome.fromCache,
180
+ tool: toolName,
181
+ });
182
+ if (outcome.decision.action !== 'pass') {
183
+ lastFinding = outcome.finding;
184
+ logger.info('verify: decided for a call', {
185
+ tool: toolName,
186
+ action: outcome.decision.action,
187
+ rationale: outcome.decision.rationale,
188
+ verdict: outcome.verdict,
189
+ fromCache: outcome.fromCache,
190
+ });
191
+ if (outcome.decision.action === 'block') {
192
+ // Answered here, never forwarded: the call would have reached
193
+ // a tool the verdict says must not run.
194
+ return {
195
+ action: 'respond',
196
+ message: refusedCallResponse(message.id, options.serverName, toolName, outcome.finding, 'blocked'),
197
+ reason: 'the called tool is refused by its verdict',
198
+ };
199
+ }
200
+ // The TOOL-level gate: this tool's own verdict, bought just now or
201
+ // served from the dictionary. The user decides, once per server
202
+ // and session on a yes.
203
+ if (needsConfirmation(outcome)) {
204
+ const refused = await confirmOrRefuse(message, toolName, outcome.finding, context.agent);
205
+ if (refused)
206
+ return refused;
207
+ }
208
+ verdictFinding = verdictFindingOf(outcome);
209
+ }
210
+ }
211
+ else if (!lastOutcome) {
212
+ // No list yet this session: nothing has been verified, so there is
213
+ // no server verdict to gate on and no definition to judge. The call
214
+ // goes through like everything else this seam does not understand,
215
+ // and the first `tools/list` sets the gate for the ones after it.
216
+ logger.info('verify: a tools/call before any tools/list, forwarding without a verdict', {
217
+ tool: toolName,
218
+ });
219
+ }
220
+ else if (needsConfirmation(lastOutcome)) {
221
+ // A name the last list did not carry — added after a
222
+ // `list_changed` the client did not follow up on, or one the agent
223
+ // remembered. There is no definition to judge, but the SERVER's
224
+ // verdict still stands, and a suspicious server is not vouched for
225
+ // by the tool being new. The user decides, as for a listed tool.
226
+ const refused = await confirmOrRefuse(message, toolName, lastFinding, context.agent);
227
+ if (refused)
228
+ return refused;
229
+ }
230
+ const key = idKey(message.id);
231
+ if (key) {
232
+ pendingCalls.set(key, {
233
+ tool: toolName,
234
+ digest: definition ? safeDigest(definition) : undefined,
235
+ argumentBytes: byteLength(params.arguments),
236
+ findings,
237
+ verdictFinding,
238
+ withholdOnFinding: policy.mode === 'block',
239
+ startedAt: Date.now(),
240
+ });
241
+ }
242
+ }
243
+ return { action: 'forward' };
244
+ },
245
+ async fromUpstream(message, context) {
246
+ if (methodOf(message) === 'notifications/tools/list_changed') {
247
+ // Noted, and forwarded: the client is the one that decides to ask
248
+ // again, and swallowing this would leave it with a stale list.
249
+ verifier.noteListChanged();
250
+ logger.info('verify: the upstream announced its tool list changed');
251
+ return { action: 'forward' };
252
+ }
253
+ if (!isResponse(message))
254
+ return { action: 'forward' };
255
+ const key = idKey(message.id);
256
+ if (!key)
257
+ return { action: 'forward' };
258
+ const call = pendingCalls.get(key);
259
+ if (call) {
260
+ pendingCalls.delete(key);
261
+ return finishCall(call, message);
262
+ }
263
+ if (!pendingLists.has(key))
264
+ return { action: 'forward' };
265
+ pendingLists.delete(key);
266
+ const result = message.result;
267
+ if (typeof result !== 'object' || result === null)
268
+ return { action: 'forward' };
269
+ const tools = result.tools;
270
+ if (!Array.isArray(tools))
271
+ return { action: 'forward' };
272
+ knownTools = new Map(tools
273
+ .filter((tool) => typeof tool?.name === 'string')
274
+ .map((tool) => [tool.name, tool]));
275
+ const outcome = await verifier.verify(tools);
276
+ options.onOutcome?.({
277
+ action: outcome.decision.action,
278
+ verdict: outcome.verdict,
279
+ fromCache: outcome.fromCache,
280
+ });
281
+ lastFinding = outcome.finding;
282
+ lastOutcome = outcome;
283
+ logger.info('verify: decided', {
284
+ action: outcome.decision.action,
285
+ rationale: outcome.decision.rationale,
286
+ verdict: outcome.verdict,
287
+ fromCache: outcome.fromCache,
288
+ tools: tools.length,
289
+ });
290
+ if (outcome.decision.action === 'pass')
291
+ return { action: 'forward' };
292
+ // The alert must not promise a prompt that will not come: none comes
293
+ // for an agent that cannot be asked, nor for a finding nobody is asked
294
+ // about (a contract error).
295
+ const canAsk = Boolean(context.agent?.supports('elicitation'));
296
+ const willAsk = needsConfirmation(outcome) && canAsk;
297
+ // Each flagged tool's own verdict, so the notice that replaces its
298
+ // description names ITS finding — see `withheldTool`.
299
+ const flagged = (outcome.tools ?? [])
300
+ .filter((tool) => tool.verdict === 'malicious' || tool.verdict === 'suspicious')
301
+ .map((tool) => ({ name: tool.name, verdict: tool.verdict, reason: tool.reason }));
302
+ // A server nobody is asked about (malicious, under `warn`) can still
303
+ // carry a suspicious tool — and a call to THAT one is put to the user.
304
+ const willAskForSuspicious = !willAsk && canAsk && flagged.some((tool) => tool.verdict === 'suspicious');
305
+ return {
306
+ action: 'replace',
307
+ message: {
308
+ ...message,
309
+ result: applyToToolsList(result, outcome.decision.action, outcome.finding, {
310
+ willAsk,
311
+ willAskForSuspicious,
312
+ flagged,
313
+ }),
314
+ },
315
+ };
316
+ },
317
+ };
318
+ /**
319
+ * The confirmation step of a `tools/call`: the decision that ends the call
320
+ * (refused, or dropped after a cancellation), or nothing when it may go on.
321
+ */
322
+ async function confirmOrRefuse(message, toolName, finding, agent) {
323
+ if (confirmed)
324
+ return undefined;
325
+ const { answer, cancelled } = await askAbout(message.id, toolName, finding, agent);
326
+ if (cancelled) {
327
+ // No response, on purpose: the spec has the receiver of a cancellation
328
+ // "not send a response for the cancelled request", and the sender
329
+ // ignore one that arrives anyway. A late refusal text would land in
330
+ // the agent's context as a fresh tool error for a call it already
331
+ // wrote off.
332
+ return { action: 'drop', reason: 'the agent cancelled the call before the user answered' };
333
+ }
334
+ if (answer.proceed)
335
+ return undefined;
336
+ if (answer.answered === false) {
337
+ logger.info('verify: no answer to the confirmation, the tools/call is not sent', { tool: toolName });
338
+ return {
339
+ action: 'respond',
340
+ message: refusedCallResponse(message.id, options.serverName, toolName, finding, 'unanswered'),
341
+ reason: 'the confirmation got no answer',
342
+ };
343
+ }
344
+ logger.info('verify: the user declined a tools/call to a suspicious tool', { tool: toolName });
345
+ return {
346
+ action: 'respond',
347
+ message: refusedCallResponse(message.id, options.serverName, toolName, finding, 'declined'),
348
+ reason: 'the user declined to send the call',
349
+ };
350
+ }
351
+ async function askAbout(requestId, toolName, finding, agent) {
352
+ const cancellation = new Cancellation(toolName);
353
+ const key = idKey(requestId);
354
+ if (key)
355
+ pendingConfirmations.set(key, cancellation);
356
+ try {
357
+ const answer = await confirmWithUser(toolName, finding, agent, cancellation);
358
+ return { answer, cancelled: cancellation.cancelled };
359
+ }
360
+ finally {
361
+ if (key)
362
+ pendingConfirmations.delete(key);
363
+ }
364
+ }
365
+ /**
366
+ * Puts the question to the user, once at a time.
367
+ *
368
+ * Two calls arriving while the prompt is up must not produce two prompts —
369
+ * the second would be answered by reflex — so the second WAITS on the open
370
+ * one. What the answer then covers depends on what the user said:
371
+ *
372
+ * - a yes with `remember` covers the session, so every waiter goes through;
373
+ * - a yes WITHOUT `remember` covers only the call the prompt named. The
374
+ * user vouched for `read_file`, not for the `exfiltrate_env` that queued
375
+ * behind it. A waiter re-asks, in turn, once the prompt closes — one
376
+ * open question at a time, each naming its own tool;
377
+ * - a no covers every call that waited on it. "Not this one" said while
378
+ * N calls were queued is N refusals, not one refusal and N-1 nudges, and
379
+ * the next call after the prompt closes asks again — a no is never
380
+ * remembered.
381
+ */
382
+ async function confirmWithUser(toolName, finding, agent, cancellation) {
383
+ if (!agent || !agent.supports('elicitation')) {
384
+ if (!warnedCannotAsk) {
385
+ warnedCannotAsk = true;
386
+ logger.warn('verify: the agent cannot be asked (no elicitation capability), forwarding calls to a suspicious server');
387
+ }
388
+ return { proceed: true, remember: false };
389
+ }
390
+ for (;;) {
391
+ if (confirmed)
392
+ return { proceed: true, remember: true };
393
+ if (openQuestion) {
394
+ // Somebody else's prompt. Its answer is ours only if it was a no, or
395
+ // a yes for the whole session.
396
+ const shared = await cancellation.race(openQuestion);
397
+ if (!shared.proceed || shared.remember)
398
+ return shared;
399
+ continue;
400
+ }
401
+ openQuestion = ask(agent, toolName, finding)
402
+ .then((answer) => {
403
+ if (answer.proceed && answer.remember)
404
+ confirmed = true;
405
+ return answer;
406
+ })
407
+ .finally(() => {
408
+ openQuestion = undefined;
409
+ });
410
+ const answer = await cancellation.race(openQuestion);
411
+ if (cancellation.cancelled)
412
+ return answer;
413
+ logger.info('verify: the user answered the confirmation', {
414
+ tool: toolName,
415
+ proceed: answer.proceed,
416
+ remember: answer.remember,
417
+ });
418
+ return answer;
419
+ }
420
+ }
421
+ async function ask(agent, toolName, finding) {
422
+ let response;
423
+ try {
424
+ response = await agent.request('elicitation/create', {
425
+ message: confirmationPrompt(options.serverName, toolName, finding),
426
+ requestedSchema: CONFIRMATION_SCHEMA,
427
+ }, CONFIRMATION_TIMEOUT_MS);
428
+ }
429
+ catch (error) {
430
+ // A question that got no answer is a no. The alternative — forwarding
431
+ // because the prompt broke — would make a crashed dialog the way past
432
+ // the gate.
433
+ logger.warn('verify: the confirmation prompt failed, refusing the call', {
434
+ error: error instanceof Error ? error.message : String(error),
435
+ });
436
+ return { proceed: false, remember: false, answered: false };
437
+ }
438
+ const result = typeof response.result === 'object' && response.result !== null
439
+ ? response.result
440
+ : undefined;
441
+ if (!result || result.action !== 'accept')
442
+ return { proceed: false, remember: false };
443
+ const content = typeof result.content === 'object' && result.content !== null
444
+ ? result.content
445
+ : {};
446
+ return { proceed: true, remember: content.remember !== false };
447
+ }
448
+ /**
449
+ * Scans a result, frames it if there is something to say, and writes the
450
+ * audit line either way.
451
+ */
452
+ function finishCall(call, message) {
453
+ const resultFindings = message.result === undefined ? [] : scanResult(message.result);
454
+ const findings = [...call.findings, ...resultFindings];
455
+ const resultBytes = byteLength(message.result);
456
+ options.audit?.record({
457
+ serverId: options.serverId,
458
+ serverName: options.serverName,
459
+ tool: call.tool,
460
+ digest: call.digest,
461
+ // Rules only. The arguments and the result are never written down: a
462
+ // file that quoted them would be a second copy of everything the user
463
+ // has done, sitting in their home directory.
464
+ findings: findings.length > 0 ? findings.map((finding) => finding.rule) : undefined,
465
+ argumentBytes: call.argumentBytes,
466
+ resultBytes,
467
+ isError: Boolean(message.result?.isError),
468
+ durationMs: Date.now() - call.startedAt,
469
+ });
470
+ if (resultFindings.length === 0 && !call.verdictFinding)
471
+ return { action: 'forward' };
472
+ if (resultFindings.length > 0) {
473
+ logger.warn('scan: something in the result of a tools/call', {
474
+ tool: call.tool,
475
+ findings: resultFindings.map((finding) => finding.rule),
476
+ });
477
+ lastFinding = {
478
+ serverName: options.serverName,
479
+ kind: 'a tool result tried to give you instructions',
480
+ tools: [call.tool],
481
+ reason: resultFindings[0]?.detail,
482
+ };
483
+ }
484
+ // The verdict frames, it never withholds: a call the server blocks was
485
+ // answered before it left, so a verdict here is one the server let
486
+ // through. Only a RESULT finding — an injection in the text — is
487
+ // withheld, and only under the organization's `block` policy.
488
+ const framed = [...(call.verdictFinding ? [call.verdictFinding] : []), ...resultFindings];
489
+ return {
490
+ action: 'replace',
491
+ message: {
492
+ ...message,
493
+ result: call.withholdOnFinding && resultFindings.length > 0
494
+ ? replaceResult(options.serverName, call.tool, resultFindings)
495
+ : prefixResult(message.result, options.serverName, call.tool, framed),
496
+ },
497
+ };
498
+ }
499
+ }
500
+ /**
501
+ * Whether a verification is one the user must be asked about.
502
+ *
503
+ * A block is enforced without a question. `alert` is the path for a
504
+ * SUSPICIOUS verdict or a list that changed mid-session — the two findings
505
+ * where the user's judgement is the missing piece. A contract error alerts
506
+ * too, but it is about OUR machinery, and asking the user to vouch for a
507
+ * server because our backend disagrees with our client would be asking the
508
+ * wrong person the wrong question.
509
+ */
510
+ function needsConfirmation(outcome) {
511
+ return (outcome.decision.action === 'alert' &&
512
+ (outcome.verdict === 'suspicious' || outcome.decision.rationale === 'changed-mid-session'));
513
+ }
514
+ /**
515
+ * The word put on a result, when the tool's own verdict deserves one.
516
+ *
517
+ * Only a verdict ABOUT THE TOOL — suspicious, malicious, refused by the user,
518
+ * a list that changed under the session — earns the frame. A contract error
519
+ * is about our backend and our client disagreeing: the list-level alert
520
+ * already says so, and a "- ok (tool-verdict)" banner on every result of a
521
+ * clean tool would say nothing at all.
522
+ */
523
+ function verdictFindingOf(outcome) {
524
+ const { verdict, decision, finding } = outcome;
525
+ const aboutTheTool = verdict === 'suspicious' ||
526
+ verdict === 'malicious' ||
527
+ decision.rationale === 'denied-by-user' ||
528
+ decision.rationale === 'changed-mid-session';
529
+ if (!aboutTheTool)
530
+ return undefined;
531
+ return {
532
+ kind: 'tool-verdict',
533
+ rule: 'tool-verdict',
534
+ where: 'tool',
535
+ detail: finding.reason ? `${finding.kind}: ${finding.reason}` : finding.kind,
536
+ severity: 'high',
537
+ };
538
+ }
539
+ /** A digest, or nothing: an un-hashable schema is not a reason to fail a call. */
540
+ function safeDigest(tool) {
541
+ try {
542
+ return toolDigest(tool);
543
+ }
544
+ catch {
545
+ return undefined;
546
+ }
547
+ }
548
+ /** How big a value is on the wire. Sizes are audited; contents never are. */
549
+ function byteLength(value) {
550
+ if (value === undefined)
551
+ return 0;
552
+ try {
553
+ return Buffer.byteLength(JSON.stringify(value) ?? '', 'utf8');
554
+ }
555
+ catch {
556
+ return 0;
557
+ }
558
+ }
559
+ //# sourceMappingURL=verifyInterceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyInterceptor.js","sourceRoot":"","sources":["../../../src/mcp/proxy/verifyInterceptor.ts"],"names":[],"mappings":"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"}