@intutic/mcp-governance-proxy 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -18
- package/dist/agentTools.d.ts +68 -0
- package/dist/agentTools.d.ts.map +1 -0
- package/dist/agentTools.js +150 -0
- package/dist/agentTools.js.map +1 -0
- package/dist/anomaly/detectors.js +1 -1
- package/dist/anomaly/detectors.js.map +1 -1
- package/dist/anomaly/index.d.ts +2 -1
- package/dist/anomaly/index.d.ts.map +1 -1
- package/dist/anomaly/index.js.map +1 -1
- package/dist/approvalHold.d.ts +66 -0
- package/dist/approvalHold.d.ts.map +1 -0
- package/dist/approvalHold.js +143 -0
- package/dist/approvalHold.js.map +1 -0
- package/dist/budget.d.ts +133 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +191 -0
- package/dist/budget.js.map +1 -0
- package/dist/config.d.ts +7 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/daemon/healthMonitor.d.ts +2 -0
- package/dist/daemon/healthMonitor.d.ts.map +1 -1
- package/dist/daemon/healthMonitor.js +60 -27
- package/dist/daemon/healthMonitor.js.map +1 -1
- package/dist/daemon/index.d.ts +0 -2
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +0 -2
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/instrumentation.d.ts +2 -2
- package/dist/daemon/instrumentation.js +2 -2
- package/dist/daemon/policyCache.d.ts +38 -3
- package/dist/daemon/policyCache.d.ts.map +1 -1
- package/dist/daemon/policyCache.js +64 -22
- package/dist/daemon/policyCache.js.map +1 -1
- package/dist/daemon/socketServer.d.ts +0 -1
- package/dist/daemon/socketServer.d.ts.map +1 -1
- package/dist/daemon/socketServer.js +0 -1
- package/dist/daemon/socketServer.js.map +1 -1
- package/dist/daemon/statusReporter.d.ts.map +1 -1
- package/dist/daemon/statusReporter.js +0 -1
- package/dist/daemon/statusReporter.js.map +1 -1
- package/dist/daemon/telemetryBatcher.d.ts.map +1 -1
- package/dist/daemon/telemetryBatcher.js +0 -1
- package/dist/daemon/telemetryBatcher.js.map +1 -1
- package/dist/daemonClient.d.ts.map +1 -1
- package/dist/daemonClient.js +0 -1
- package/dist/daemonClient.js.map +1 -1
- package/dist/dlp.d.ts +32 -3
- package/dist/dlp.d.ts.map +1 -1
- package/dist/dlp.js +116 -18
- package/dist/dlp.js.map +1 -1
- package/dist/dlpPii.d.ts +66 -0
- package/dist/dlpPii.d.ts.map +1 -0
- package/dist/dlpPii.js +235 -0
- package/dist/dlpPii.js.map +1 -0
- package/dist/emitter.d.ts +68 -10
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +29 -43
- package/dist/emitter.js.map +1 -1
- package/dist/guardedValkey.d.ts +40 -0
- package/dist/guardedValkey.d.ts.map +1 -0
- package/dist/guardedValkey.js +84 -0
- package/dist/guardedValkey.js.map +1 -0
- package/dist/httpJson.d.ts +19 -0
- package/dist/httpJson.d.ts.map +1 -0
- package/dist/httpJson.js +62 -0
- package/dist/httpJson.js.map +1 -0
- package/dist/identity.d.ts +27 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +36 -0
- package/dist/identity.js.map +1 -0
- package/dist/injection.js +1 -1
- package/dist/interceptor.d.ts +135 -8
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +284 -45
- package/dist/interceptor.js.map +1 -1
- package/dist/policy.d.ts +105 -2
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +188 -40
- package/dist/policy.js.map +1 -1
- package/dist/proxy.d.ts +35 -11
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +183 -66
- package/dist/proxy.js.map +1 -1
- package/dist/refusals.d.ts +26 -0
- package/dist/refusals.d.ts.map +1 -0
- package/dist/refusals.js +43 -0
- package/dist/refusals.js.map +1 -0
- package/dist/registryObserver.d.ts +37 -0
- package/dist/registryObserver.d.ts.map +1 -0
- package/dist/registryObserver.js +70 -0
- package/dist/registryObserver.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/dist/sessionScope.d.ts +1 -1
- package/dist/sessionScope.js +1 -1
- package/dist/sessionStore.d.ts +10 -23
- package/dist/sessionStore.d.ts.map +1 -1
- package/dist/sessionStore.js +17 -76
- package/dist/sessionStore.js.map +1 -1
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/dist/wasm/context.d.ts +10 -0
- package/dist/wasm/context.d.ts.map +1 -1
- package/dist/wasm/context.js +27 -0
- package/dist/wasm/context.js.map +1 -1
- package/dist/wasm/hostImports.d.ts +3 -3
- package/dist/wasm/hostImports.d.ts.map +1 -1
- package/dist/wasm/hostImports.js +8 -7
- package/dist/wasm/hostImports.js.map +1 -1
- package/dist/wasm/loader.d.ts +8 -1
- package/dist/wasm/loader.d.ts.map +1 -1
- package/dist/wasm/loader.js +2 -0
- package/dist/wasm/loader.js.map +1 -1
- package/dist/wasm/referencedFiles.d.ts +29 -4
- package/dist/wasm/referencedFiles.d.ts.map +1 -1
- package/dist/wasm/referencedFiles.js +48 -21
- package/dist/wasm/referencedFiles.js.map +1 -1
- package/dist/wasm/runner.d.ts +106 -22
- package/dist/wasm/runner.d.ts.map +1 -1
- package/dist/wasm/runner.js +194 -74
- package/dist/wasm/runner.js.map +1 -1
- package/dist/wasm/watch.js +1 -1
- package/dist/wasm/worker.d.ts +10 -6
- package/dist/wasm/worker.d.ts.map +1 -1
- package/dist/wasm/worker.js +93 -9
- package/dist/wasm/worker.js.map +1 -1
- package/package.json +5 -4
- package/dist/toolPoison.d.ts +0 -32
- package/dist/toolPoison.d.ts.map +0 -1
- package/dist/toolPoison.js +0 -81
- package/dist/toolPoison.js.map +0 -1
- package/dist/wasm/fuel.d.ts +0 -35
- package/dist/wasm/fuel.d.ts.map +0 -1
- package/dist/wasm/fuel.js +0 -299
- package/dist/wasm/fuel.js.map +0 -1
- package/dist/wasm/memoryCap.d.ts +0 -21
- package/dist/wasm/memoryCap.d.ts.map +0 -1
- package/dist/wasm/memoryCap.js +0 -54
- package/dist/wasm/memoryCap.js.map +0 -1
- package/dist/wasm/wasmBinary.d.ts +0 -25
- package/dist/wasm/wasmBinary.d.ts.map +0 -1
- package/dist/wasm/wasmBinary.js +0 -100
- package/dist/wasm/wasmBinary.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
The MCP Governance Proxy sits between an AI coding agent and its MCP tool servers. It intercepts every `tools/call` JSON-RPC message on stdin/stdout, evaluates the call against workspace governance policies, and either forwards, blocks
|
|
9
|
+
The MCP Governance Proxy sits between an AI coding agent and its MCP tool servers. It intercepts every `tools/call` JSON-RPC message on stdin/stdout, evaluates the call against workspace governance policies, and either forwards it, blocks it, or holds it for a person's approval, and redacts secrets out of results on the way back — all without requiring changes to the agent or the tool server.
|
|
10
10
|
|
|
11
11
|
## Modes
|
|
12
12
|
|
|
@@ -22,12 +22,14 @@ The proxy spawns the real MCP server as a child process and relays JSON-RPC mess
|
|
|
22
22
|
|
|
23
23
|
### Standalone Mode
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
With no server to wrap (no `--` command, no `--remote-url`), `intutic-mcp-proxy` is itself an MCP server named `intutic`, exposing three read-only tools: `intutic_governance_status`, `intutic_list_sops` and `intutic_list_incidents`. The two list tools take a `limit` (1–50, default 10). The control plane lists incidents only for the OWNER, ADMIN or EM role; any other role gets a message saying so instead.
|
|
26
26
|
|
|
27
27
|
```
|
|
28
|
-
Agent ↔ intutic-mcp-
|
|
28
|
+
Agent ↔ intutic-mcp-proxy (MCP server) ↔ Intutic control plane
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
It needs `INTUTIC_API_KEY`, the control plane's address (`INTUTIC_CONTROL_PLANE_URL`, or `INTUTIC_HOST` in `~/.intutic/env/runtime.env`; default `http://localhost:3001`) and a workspace id (`--workspace-id` or `INTUTIC_WORKSPACE_ID`).
|
|
32
|
+
|
|
31
33
|
### Remote Bridge Mode
|
|
32
34
|
|
|
33
35
|
Fronts a remote (HTTP/SSE-transport) MCP server instead of a spawned child process. The harness still spawns this proxy as a normal stdio child — no new listener, no new port — but the proxy's upstream side talks to the remote server over HTTP or Server-Sent Events using the MCP SDK's client transports directly:
|
|
@@ -42,26 +44,28 @@ Every governance check proxy mode applies to a stdio server — allowlists, `too
|
|
|
42
44
|
|
|
43
45
|
### DLP Scanning
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
Built-in patterns, plus any the workspace adds. A match in a call's arguments blocks the call; a credential in a result is redacted before the agent reads it:
|
|
48
|
+
|
|
49
|
+
- 9 secret patterns: OpenAI, Anthropic and Google API keys, GitHub personal access and server tokens, Slack bot and user tokens, AWS access key IDs, and long hex strings that look like secrets
|
|
50
|
+
- 2 private-key patterns: PEM and EC private key headers
|
|
51
|
+
- Destructive commands: `rm -rf /` and 4 SQL statements (`DROP TABLE`, `DROP DATABASE`, `DROP SCHEMA`, `TRUNCATE TABLE`) — arguments only, matched against each decoded argument string; whitespace, a line continuation, comments or an escaped `\n` between the SQL keywords do not hide them, and a quoted mention counts
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
- Secrets and passwords
|
|
49
|
-
- Private keys and certificates
|
|
50
|
-
- SQL injection patterns
|
|
51
|
-
- PII indicators
|
|
53
|
+
**PII detectors**, the same validated detectors the LLM proxy runs: payment card numbers (Luhn check), IBANs (mod 97 check) and US Social Security numbers (checked against issued ranges) are on by default, email addresses and phone numbers off. Arguments are never rewritten, so an enabled detector blocks the call when it finds PII in the arguments; in a result, the PII is redacted. `INTUTIC_MCP_DLP_DETECTORS` sets this machine's actions, as a JSON object of detector id → `off`, `redact` or `block` (such as `{"pii.email":"redact"}`), and a connected workspace's `piiDetectors` setting sets the baseline, which the machine's own setting may only make stricter. See [PII detectors](https://docs.intutic.ai/guide/policies#pii-detectors).
|
|
52
54
|
|
|
53
55
|
### Policy Enforcement
|
|
54
56
|
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
57
|
+
- **MCP server registry**: a server an owner or admin blocked is refused; under the workspace's `deny` default, so is any server not yet approved; a tool switched off within a server is hidden and refused
|
|
58
|
+
- **Allowlists**: `mcpAllowedServers` / `mcpAllowedTools`, empty meaning unrestricted
|
|
59
|
+
- **SSO group policy**: the workspace's `sso_group_policy`, applied to the member the API key belongs to
|
|
60
|
+
- **SOP rules** matched on tool name and arguments: `block`, `warn`, or `require_approval` — a hold recorded in the workspace's review queue; once it is approved, the identical call passes only while the workspace's review-hold bypass is on
|
|
61
|
+
- **Audit events** for every decision, carrying the caller: API key prefix, OS user, harness session and server
|
|
58
62
|
|
|
59
63
|
## Binaries
|
|
60
64
|
|
|
61
65
|
| Binary | Description |
|
|
62
66
|
|--------|-------------|
|
|
63
|
-
| `intutic-mcp-proxy` |
|
|
64
|
-
| `intutic-mcp-daemon` |
|
|
67
|
+
| `intutic-mcp-proxy` | Wraps an MCP server (stdio or remote), or with no server to wrap, runs the standalone `intutic` MCP server |
|
|
68
|
+
| `intutic-mcp-daemon` | Long-lived local daemon on a Unix socket (`~/.intutic/mcp-proxy.sock`, or `MCP_DAEMON_SOCKET`) that caches policy and batches telemetry for proxies running with `INTUTIC_MCP_PROXY_MODE=daemon`. Not an MCP server. |
|
|
65
69
|
|
|
66
70
|
## Installation
|
|
67
71
|
|
|
@@ -78,7 +82,7 @@ npm install @intutic/mcp-governance-proxy
|
|
|
78
82
|
"mcpServers": {
|
|
79
83
|
"filesystem": {
|
|
80
84
|
"command": "intutic-mcp-proxy",
|
|
81
|
-
"args": ["--", "npx", "@modelcontextprotocol/server-filesystem", "/path"]
|
|
85
|
+
"args": ["--server-name", "filesystem", "--", "npx", "@modelcontextprotocol/server-filesystem", "/path"]
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
}
|
|
@@ -86,10 +90,20 @@ npm install @intutic/mcp-governance-proxy
|
|
|
86
90
|
|
|
87
91
|
### Standalone Mode
|
|
88
92
|
|
|
89
|
-
```
|
|
90
|
-
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"mcpServers": {
|
|
96
|
+
"intutic": {
|
|
97
|
+
"command": "npx",
|
|
98
|
+
"args": ["-y", "-p", "@intutic/mcp-governance-proxy", "intutic-mcp-proxy", "--workspace-id", "wk_your_workspace"],
|
|
99
|
+
"env": { "INTUTIC_API_KEY": "<your API key>" }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
91
103
|
```
|
|
92
104
|
|
|
105
|
+
The package has two binaries, so `npx` needs `-p @intutic/mcp-governance-proxy` and the binary name.
|
|
106
|
+
|
|
93
107
|
### Remote Bridge Mode
|
|
94
108
|
|
|
95
109
|
```json
|
|
@@ -97,7 +111,7 @@ intutic-mcp-daemon --port 3100
|
|
|
97
111
|
"mcpServers": {
|
|
98
112
|
"linear": {
|
|
99
113
|
"command": "intutic-mcp-proxy",
|
|
100
|
-
"args": ["--remote-url", "https://mcp.linear.app/sse", "--remote-transport", "sse"],
|
|
114
|
+
"args": ["--server-name", "linear", "--remote-url", "https://mcp.linear.app/sse", "--remote-transport", "sse"],
|
|
101
115
|
"env": { "INTUTIC_REMOTE_HEADERS": "{\"Authorization\":\"Bearer <token>\"}" }
|
|
102
116
|
}
|
|
103
117
|
}
|
|
@@ -106,6 +120,8 @@ intutic-mcp-daemon --port 3100
|
|
|
106
120
|
|
|
107
121
|
`--remote-transport` accepts `sse` or `http` (default `http`, the SDK's current non-deprecated `StreamableHTTPClientTransport`). `--remote-url` and a positional stdio command (`--` followed by a command) are mutually exclusive — pass one or the other. Auth headers ride via the `INTUTIC_REMOTE_HEADERS` environment variable (a JSON object string), never as a CLI argument — argv is visible to any local process via `ps`.
|
|
108
122
|
|
|
123
|
+
`--server-name` is the name the registry, the server allowlist and the TOFU pin file (`~/.intutic/mcp-pins/<workspace>__<server>.json`) know the server by; without it the server is `unknown`. `intutic connect` sets it when it wraps a harness's servers. Every environment variable and flag is listed in the [MCP Server Governance guide](https://docs.intutic.ai/guide/mcp-governance#configuration-reference).
|
|
124
|
+
|
|
109
125
|
## Part of Intutic
|
|
110
126
|
|
|
111
127
|
This package is part of the [Intutic](https://github.com/intutic/intutic) monorepo — an open-core AI governance control plane for developer teams.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentTools.ts — what the `intutic` MCP server's own tools answer.
|
|
3
|
+
*
|
|
4
|
+
* The standalone `intutic` entry (proxy.ts `runStandalone`) gives an agent
|
|
5
|
+
* tools to ask about governance instead of guessing from a refusal message:
|
|
6
|
+
* whether a hold it was given has been decided and whether a retry will
|
|
7
|
+
* pass, what the MCP server registry says about a server, and how much of
|
|
8
|
+
* each MCP call budget is left. The answers are built here, from what the
|
|
9
|
+
* control plane and Valkey return, so they can be tested without a server.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { type McpBudgetPolicy } from '@intutic/shared-types';
|
|
14
|
+
/** One control-plane read, never thrown: a failure degrades a tool's answer, it does not crash the server. */
|
|
15
|
+
export type ControlPlaneResult = {
|
|
16
|
+
ok: true;
|
|
17
|
+
data: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
reason: 'forbidden' | 'not_found' | 'unreachable';
|
|
21
|
+
};
|
|
22
|
+
export declare function readControlPlane(controlPlaneUrl: string, apiKey: string, workspaceId: string, path: string): Promise<ControlPlaneResult>;
|
|
23
|
+
/** Renders a failed read as text for the agent, naming the actual cause. */
|
|
24
|
+
export declare function describeFailure(result: {
|
|
25
|
+
reason: 'forbidden' | 'not_found' | 'unreachable';
|
|
26
|
+
}, what: string): string;
|
|
27
|
+
export interface HoldStatus {
|
|
28
|
+
holdId: string;
|
|
29
|
+
status: 'PENDING_REVIEW' | 'APPROVED' | 'REJECTED' | string;
|
|
30
|
+
/** What the agent should do next. */
|
|
31
|
+
retry: 'wait' | 'passes' | 'held_again' | 'do_not_retry';
|
|
32
|
+
/** Until when a retry passes, when it does. */
|
|
33
|
+
bypassExpiresAt?: string;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Where a hold stands, from its decision row and the workspace's approved
|
|
38
|
+
* bypasses. An approval lets the identical retry through only while a bypass
|
|
39
|
+
* exists for it, which needs the workspace's review-hold bypass setting on.
|
|
40
|
+
*/
|
|
41
|
+
export declare function holdStatus(holdId: string, decision: {
|
|
42
|
+
status?: unknown;
|
|
43
|
+
}, bypasses: unknown): HoldStatus;
|
|
44
|
+
/**
|
|
45
|
+
* What the registry means for calls to each server: whether calls to it run,
|
|
46
|
+
* and which of its tools are switched off. `server` narrows it to one.
|
|
47
|
+
*/
|
|
48
|
+
export declare function registryStatus(data: unknown, server?: string): Record<string, unknown>;
|
|
49
|
+
export interface BudgetRemaining {
|
|
50
|
+
budgetId: string;
|
|
51
|
+
counts: string;
|
|
52
|
+
period: string;
|
|
53
|
+
limit: number;
|
|
54
|
+
/** `null` when the count could not be read. */
|
|
55
|
+
used: number | null;
|
|
56
|
+
remaining: number | null;
|
|
57
|
+
resetAt: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Every MCP call budget that can count this caller's calls, with what is
|
|
61
|
+
* left of it this period. `readUsed` reads the counters the proxies keep
|
|
62
|
+
* (budget.ts), returning `undefined` when it cannot.
|
|
63
|
+
*/
|
|
64
|
+
export declare function budgetRemaining(policy: McpBudgetPolicy, workspaceId: string, caller: {
|
|
65
|
+
memberId: string | null;
|
|
66
|
+
fallback: string;
|
|
67
|
+
}, readUsed: (keys: string[]) => Promise<number[] | undefined>, nowMs?: number): Promise<BudgetRemaining[]>;
|
|
68
|
+
//# sourceMappingURL=agentTools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentTools.d.ts","sourceRoot":"","sources":["../src/agentTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAmC,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAG7F,8GAA8G;AAC9G,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,CAAA;CAAE,CAAA;AAEpE,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,CAAC,CAe7B;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,CAAA;CAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnH;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAA;IAC3D,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAA;IACxD,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,EAAE,OAAO,GAAG,UAAU,CA0CxG;AASD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCtF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,EAC3D,KAAK,GAAE,MAAmB,GACzB,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5B"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentTools.ts — what the `intutic` MCP server's own tools answer.
|
|
3
|
+
*
|
|
4
|
+
* The standalone `intutic` entry (proxy.ts `runStandalone`) gives an agent
|
|
5
|
+
* tools to ask about governance instead of guessing from a refusal message:
|
|
6
|
+
* whether a hold it was given has been decided and whether a retry will
|
|
7
|
+
* pass, what the MCP server registry says about a server, and how much of
|
|
8
|
+
* each MCP call budget is left. The answers are built here, from what the
|
|
9
|
+
* control plane and Valkey return, so they can be tested without a server.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { budgetWindow, describeMcpBudget } from '@intutic/shared-types';
|
|
14
|
+
import { budgetCounterKey } from './budget.js';
|
|
15
|
+
export async function readControlPlane(controlPlaneUrl, apiKey, workspaceId, path) {
|
|
16
|
+
try {
|
|
17
|
+
const res = await fetch(`${controlPlaneUrl}${path}`, {
|
|
18
|
+
headers: { Authorization: `Bearer ${apiKey}`, 'x-workspace-id': workspaceId },
|
|
19
|
+
signal: AbortSignal.timeout(5000),
|
|
20
|
+
});
|
|
21
|
+
// 403 and 404 are answers, not outages. Collapsing them into
|
|
22
|
+
// "unreachable" sends someone debugging their network for an hour.
|
|
23
|
+
if (res.status === 403)
|
|
24
|
+
return { ok: false, reason: 'forbidden' };
|
|
25
|
+
if (res.status === 404)
|
|
26
|
+
return { ok: false, reason: 'not_found' };
|
|
27
|
+
if (!res.ok)
|
|
28
|
+
return { ok: false, reason: 'unreachable' };
|
|
29
|
+
return { ok: true, data: await res.json() };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return { ok: false, reason: 'unreachable' };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Renders a failed read as text for the agent, naming the actual cause. */
|
|
36
|
+
export function describeFailure(result, what) {
|
|
37
|
+
if (result.reason === 'forbidden') {
|
|
38
|
+
return `Your Intutic role is not permitted to ${what}. This needs the OWNER, ADMIN or EM role.`;
|
|
39
|
+
}
|
|
40
|
+
if (result.reason === 'not_found')
|
|
41
|
+
return `The Intutic control plane answered 404 when asked to ${what}.`;
|
|
42
|
+
return `Could not reach control plane to ${what}.`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Where a hold stands, from its decision row and the workspace's approved
|
|
46
|
+
* bypasses. An approval lets the identical retry through only while a bypass
|
|
47
|
+
* exists for it, which needs the workspace's review-hold bypass setting on.
|
|
48
|
+
*/
|
|
49
|
+
export function holdStatus(holdId, decision, bypasses) {
|
|
50
|
+
const status = typeof decision.status === 'string' ? decision.status : 'UNKNOWN';
|
|
51
|
+
if (status === 'PENDING_REVIEW') {
|
|
52
|
+
return {
|
|
53
|
+
holdId,
|
|
54
|
+
status,
|
|
55
|
+
retry: 'wait',
|
|
56
|
+
message: 'Waiting for an owner, admin or engineering manager to approve or reject it ' +
|
|
57
|
+
`(intutic decision approve ${holdId}, or the Slack card). Do not retry yet; tell the user the hold id.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (status === 'REJECTED') {
|
|
61
|
+
return { holdId, status, retry: 'do_not_retry', message: 'Rejected. Do not retry this call; continue without it or ask the user.' };
|
|
62
|
+
}
|
|
63
|
+
if (status === 'APPROVED') {
|
|
64
|
+
const list = bypasses?.bypasses;
|
|
65
|
+
const bypass = Array.isArray(list)
|
|
66
|
+
? list.find((b) => b.holdId === holdId && typeof b.expiresAt === 'string' && Date.parse(b.expiresAt) > Date.now())
|
|
67
|
+
: undefined;
|
|
68
|
+
if (bypass) {
|
|
69
|
+
return {
|
|
70
|
+
holdId,
|
|
71
|
+
status,
|
|
72
|
+
retry: 'passes',
|
|
73
|
+
bypassExpiresAt: bypass.expiresAt,
|
|
74
|
+
message: `Approved. Retry the identical call (same tool, same arguments) before ${String(bypass.expiresAt)}; any other call is not covered.`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
holdId,
|
|
79
|
+
status,
|
|
80
|
+
retry: 'held_again',
|
|
81
|
+
message: "Approved, but a retry will be held again: the workspace's review-hold bypass " +
|
|
82
|
+
'(reviewHoldBypassEnabled) is off, or the approval window has passed. Tell the user the call was approved ' +
|
|
83
|
+
'and needs to be run another way, or ask an admin to turn the bypass on.',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return { holdId, status, retry: 'do_not_retry', message: `The hold is ${status}. Do not retry this call.` };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* What the registry means for calls to each server: whether calls to it run,
|
|
90
|
+
* and which of its tools are switched off. `server` narrows it to one.
|
|
91
|
+
*/
|
|
92
|
+
export function registryStatus(data, server) {
|
|
93
|
+
const body = (data ?? {});
|
|
94
|
+
const defaultPolicy = body.defaultPolicy === 'deny' ? 'deny' : 'allow';
|
|
95
|
+
const servers = (Array.isArray(body.servers) ? body.servers : [])
|
|
96
|
+
.filter((s) => typeof s.serverName === 'string' && (!server || s.serverName === server))
|
|
97
|
+
.map((s) => {
|
|
98
|
+
const status = String(s.status);
|
|
99
|
+
const held = s.heldForReview === true;
|
|
100
|
+
const calls = held
|
|
101
|
+
? 'refused (SERVER_HELD): a high-risk tool change is waiting for an owner or admin'
|
|
102
|
+
: status === 'blocked'
|
|
103
|
+
? 'refused (SERVER_BLOCKED)'
|
|
104
|
+
: status === 'approved' || defaultPolicy === 'allow'
|
|
105
|
+
? 'allowed'
|
|
106
|
+
: 'refused (SERVER_NOT_APPROVED): waiting in the approval queue';
|
|
107
|
+
return {
|
|
108
|
+
server: s.serverName,
|
|
109
|
+
status,
|
|
110
|
+
calls,
|
|
111
|
+
disabledTools: Array.isArray(s.disabledTools) ? s.disabledTools : [],
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
defaultPolicy,
|
|
116
|
+
servers,
|
|
117
|
+
...(server && servers.length === 0
|
|
118
|
+
? {
|
|
119
|
+
note: defaultPolicy === 'deny'
|
|
120
|
+
? `"${server}" is not in the registry; calls to it are refused (SERVER_NOT_APPROVED) until an owner or admin approves it.`
|
|
121
|
+
: `"${server}" is not in the registry yet; calls to it are allowed under the default policy.`,
|
|
122
|
+
}
|
|
123
|
+
: {}),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Every MCP call budget that can count this caller's calls, with what is
|
|
128
|
+
* left of it this period. `readUsed` reads the counters the proxies keep
|
|
129
|
+
* (budget.ts), returning `undefined` when it cannot.
|
|
130
|
+
*/
|
|
131
|
+
export async function budgetRemaining(policy, workspaceId, caller, readUsed, nowMs = Date.now()) {
|
|
132
|
+
const mine = policy.budgets.filter((b) => b.memberId === undefined || b.memberId === caller.memberId);
|
|
133
|
+
const subject = caller.memberId ?? caller.fallback;
|
|
134
|
+
const windows = mine.map((b) => budgetWindow(b.period, nowMs));
|
|
135
|
+
const keys = mine.map((b, i) => budgetCounterKey(workspaceId, b.id, windows[i].startMs, b.scope === 'member' || b.scope === 'member_server' ? subject : ''));
|
|
136
|
+
const used = keys.length > 0 ? await readUsed(keys) : [];
|
|
137
|
+
return mine.map((b, i) => {
|
|
138
|
+
const n = used?.[i];
|
|
139
|
+
return {
|
|
140
|
+
budgetId: b.id,
|
|
141
|
+
counts: describeMcpBudget(b, b.memberId ? 'you' : undefined),
|
|
142
|
+
period: b.period,
|
|
143
|
+
limit: b.limit,
|
|
144
|
+
used: n ?? null,
|
|
145
|
+
remaining: n === undefined ? null : Math.max(0, b.limit - n),
|
|
146
|
+
resetAt: new Date(windows[i].resetAtMs).toISOString(),
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=agentTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentTools.js","sourceRoot":"","sources":["../src/agentTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAwB,MAAM,uBAAuB,CAAA;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAO9C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,eAAuB,EACvB,MAAc,EACd,WAAmB,EACnB,IAAY;IAEZ,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,GAAG,IAAI,EAAE,EAAE;YACnD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,gBAAgB,EAAE,WAAW,EAAE;YAC7E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAA;QACF,6DAA6D;QAC7D,mEAAmE;QACnE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QACjE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QACjE,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;QACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,MAA6D,EAAE,IAAY;IACzG,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,yCAAyC,IAAI,2CAA2C,CAAA;IACjG,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,wDAAwD,IAAI,GAAG,CAAA;IACzG,OAAO,oCAAoC,IAAI,GAAG,CAAA;AACpD,CAAC;AAYD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,QAA8B,EAAE,QAAiB;IAC1F,MAAM,MAAM,GAAG,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IAChF,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChC,OAAO;YACL,MAAM;YACN,MAAM;YACN,KAAK,EAAE,MAAM;YACb,OAAO,EACL,6EAA6E;gBAC7E,6BAA6B,MAAM,oEAAoE;SAC1G,CAAA;IACH,CAAC;IACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,wEAAwE,EAAE,CAAA;IACrI,CAAC;IACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAI,QAA0C,EAAE,QAAQ,CAAA;QAClE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAChC,CAAC,CAAE,IAAuC,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CACtG;YACH,CAAC,CAAC,SAAS,CAAA;QACb,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;gBACL,MAAM;gBACN,MAAM;gBACN,KAAK,EAAE,QAAQ;gBACf,eAAe,EAAE,MAAM,CAAC,SAAmB;gBAC3C,OAAO,EAAE,yEAAyE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,kCAAkC;aAC7I,CAAA;QACH,CAAC;QACD,OAAO;YACL,MAAM;YACN,MAAM;YACN,KAAK,EAAE,YAAY;YACnB,OAAO,EACL,+EAA+E;gBAC/E,2GAA2G;gBAC3G,yEAAyE;SAC5E,CAAA;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,MAAM,2BAA2B,EAAE,CAAA;AAC7G,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,MAAe;IAC3D,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAmD,CAAA;IAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IACtE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,OAA4B,CAAC,CAAC,CAAC,EAAE,CAAC;SACpF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC;SACvF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,aAAa,KAAK,IAAI,CAAA;QACrC,MAAM,KAAK,GAAG,IAAI;YAChB,CAAC,CAAC,iFAAiF;YACnF,CAAC,CAAC,MAAM,KAAK,SAAS;gBACpB,CAAC,CAAC,0BAA0B;gBAC5B,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,aAAa,KAAK,OAAO;oBAClD,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,8DAA8D,CAAA;QACtE,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,UAAU;YACpB,MAAM;YACN,KAAK;YACL,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;SACrE,CAAA;IACH,CAAC,CAAC,CAAA;IACJ,OAAO;QACL,aAAa;QACb,OAAO;QACP,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAChC,CAAC,CAAC;gBACE,IAAI,EACF,aAAa,KAAK,MAAM;oBACtB,CAAC,CAAC,IAAI,MAAM,8GAA8G;oBAC1H,CAAC,CAAC,IAAI,MAAM,iFAAiF;aAClG;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAA;AACH,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAuB,EACvB,WAAmB,EACnB,MAAqD,EACrD,QAA2D,EAC3D,QAAgB,IAAI,CAAC,GAAG,EAAE;IAE1B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAA;IACrG,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAA;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC7B,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAC7H,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACxD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACnB,OAAO;YACL,QAAQ,EAAE,CAAC,CAAC,EAAE;YACd,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5D,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,IAAI,IAAI;YACf,SAAS,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC5D,OAAO,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;SACvD,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @module
|
|
19
19
|
*/
|
|
20
|
-
import { scanToolDescription } from '
|
|
20
|
+
import { scanToolDescription } from '@intutic/shared-types';
|
|
21
21
|
/** Severity order for sorting/clamping — mirrors `Disposition`'s derived
|
|
22
22
|
* `Ord` in mod.rs (`Steer < Reask < Ask < Kill`); this package never uses
|
|
23
23
|
* `Ask`, so the four-way order collapses to three. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detectors.js","sourceRoot":"","sources":["../../src/anomaly/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"detectors.js","sourceRoot":"","sources":["../../src/anomaly/detectors.ts"],"names":[],"mappings":"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"}
|
package/dist/anomaly/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
import type { AnomalyFinding, Disposition } from './detectors.js';
|
|
10
|
+
import type { McpAnomalyDetectorId } from '@intutic/shared-types';
|
|
10
11
|
export * from './detectors.js';
|
|
11
12
|
/**
|
|
12
13
|
* Ported from `packages/proxy/src/plugins/anomaly/mod.rs`'s
|
|
@@ -23,7 +24,7 @@ export declare const REASK_MAX_ATTEMPTS = 3;
|
|
|
23
24
|
* even when no finding fired yet (an `'off'` override skips evaluation
|
|
24
25
|
* entirely — see `resolveEffectiveDisposition`).
|
|
25
26
|
*/
|
|
26
|
-
export declare const DETECTOR_BASE_DISPOSITION: Readonly<Record<
|
|
27
|
+
export declare const DETECTOR_BASE_DISPOSITION: Readonly<Record<McpAnomalyDetectorId, Disposition>>;
|
|
27
28
|
export type AnomalyMode = 'enforce' | 'warn' | 'off';
|
|
28
29
|
/**
|
|
29
30
|
* Resolves the EFFECTIVE disposition for one finding, honoring:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anomaly/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjE,cAAc,gBAAgB,CAAA;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anomaly/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEjE,cAAc,gBAAgB,CAAA;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAQzF,CAAA;AAID,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC,GACvD,WAAW,GAAG,KAAK,CAarB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/anomaly/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/anomaly/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,cAAc,gBAAgB,CAAA;AAE9B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAwD;IAC5F,kBAAkB,EAAE,OAAO;IAC3B,eAAe,EAAE,OAAO;IACxB,cAAc,EAAE,OAAO;IACvB,uBAAuB,EAAE,OAAO;IAChC,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,OAAO;IACvB,cAAc,EAAE,MAAM;CACvB,CAAA;AAED,MAAM,QAAQ,GAAkD,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;AAIvG;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAAuB,EACvB,IAAiB,EACjB,SAAwD;IAExD,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IAEhC,MAAM,WAAW,GAAwB,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;IACxF,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAE9C,MAAM,UAAU,GAA4B,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAC9E,IAAI,QAAQ,KAAK,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAErD,yEAAyE;IACzE,0EAA0E;IAC1E,2DAA2D;IAC3D,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/E,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* approvalHold.ts — `require_approval` rules as real holds, not blocks.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the harness hook gates' hold tier through the same control-plane
|
|
5
|
+
* decisions API:
|
|
6
|
+
*
|
|
7
|
+
* 1. A call that matches a `require_approval` rule is looked up in the
|
|
8
|
+
* workspace's approved bypasses (`GET /api/v1/decisions/approved-bypasses`).
|
|
9
|
+
* An exact, unexpired match — same rule, same server and tool, same
|
|
10
|
+
* arguments — lets the call through.
|
|
11
|
+
* 2. Otherwise the call is refused and a hold is recorded
|
|
12
|
+
* (`POST /api/v1/decisions`), which puts it in the review queue, notifies
|
|
13
|
+
* the workspace (`decision.pending`, Slack included), and gives the agent a
|
|
14
|
+
* hold id to quote.
|
|
15
|
+
* 3. An Owner, Admin or EM approves it (`intutic decision approve <holdId>`, the review
|
|
16
|
+
* API, or the Slack card — all one code path in the control plane). The
|
|
17
|
+
* approval lets the identical retry pass only while the workspace's
|
|
18
|
+
* review-hold bypass (`reviewHoldBypassEnabled`) is on: approving then
|
|
19
|
+
* writes the bypass step 1 finds, valid for `reviewHoldBypassTtlMinutes`.
|
|
20
|
+
* Otherwise the approval records the decision only, exactly as it does for
|
|
21
|
+
* a hook-gate hold.
|
|
22
|
+
*
|
|
23
|
+
* "Identical" is the bypass key: the rule id, `mcp__<server>__<tool>`
|
|
24
|
+
* lower-cased, and a SHA-256 of the arguments serialised with sorted keys, so
|
|
25
|
+
* the same arguments in a different key order still match and any other
|
|
26
|
+
* argument value does not.
|
|
27
|
+
*
|
|
28
|
+
* A hold needs the control plane both ways — to find an approval and to
|
|
29
|
+
* record a request for one — so an unreachable control plane means the call
|
|
30
|
+
* stays held, whatever the fail-open setting: a rule that says a person must
|
|
31
|
+
* approve is not satisfied by nobody being reachable to ask.
|
|
32
|
+
*
|
|
33
|
+
* @module
|
|
34
|
+
*/
|
|
35
|
+
import type { SopRule } from './policy.js';
|
|
36
|
+
import type { CallerIdentity } from './identity.js';
|
|
37
|
+
export type HoldOutcome = {
|
|
38
|
+
kind: 'bypassed';
|
|
39
|
+
holdId: string;
|
|
40
|
+
decidedBy: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'held';
|
|
43
|
+
holdId: string;
|
|
44
|
+
recorded: boolean;
|
|
45
|
+
};
|
|
46
|
+
/** JSON with object keys sorted at every level, so key order never changes a hash. */
|
|
47
|
+
export declare function canonicalJson(value: unknown): string;
|
|
48
|
+
export declare function holdKey(serverName: string, toolName: string, toolInput: unknown): {
|
|
49
|
+
toolNameNormalized: string;
|
|
50
|
+
targetHash: string;
|
|
51
|
+
};
|
|
52
|
+
export declare class ApprovalHolds {
|
|
53
|
+
private readonly controlPlaneUrl;
|
|
54
|
+
private readonly apiKey;
|
|
55
|
+
private readonly workspaceId;
|
|
56
|
+
private readonly serverName;
|
|
57
|
+
/** Rides on the hold record so the reviewer sees who asked (identity.ts). */
|
|
58
|
+
private readonly identity;
|
|
59
|
+
constructor(controlPlaneUrl: string, apiKey: string, workspaceId: string, serverName: string,
|
|
60
|
+
/** Rides on the hold record so the reviewer sees who asked (identity.ts). */
|
|
61
|
+
identity?: CallerIdentity | undefined);
|
|
62
|
+
/** Lets the call through on an approved bypass, or records a hold and returns its id. Never throws. */
|
|
63
|
+
request(rule: Pick<SopRule, 'id' | 'reason'>, toolName: string, toolInput: unknown): Promise<HoldOutcome>;
|
|
64
|
+
private findBypass;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=approvalHold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvalHold.d.ts","sourceRoot":"","sources":["../src/approvalHold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAOnD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAA;AAEvD,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASpD;AAED,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG;IAAE,kBAAkB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAKpI;AAgBD,qBAAa,aAAa;IAEtB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBALR,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM;IACnC,6EAA6E;IAC5D,QAAQ,GAAE,cAAc,GAAG,SAAqB;IAGnE,uGAAuG;IACjG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;YAoCjG,UAAU;CA4BzB"}
|