wicked-crew 0.7.40 → 0.7.45
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/dist/api/audit.d.ts +3 -0
- package/dist/api/audit.d.ts.map +1 -1
- package/dist/api/audit.js +2 -0
- package/dist/api/audit.js.map +1 -1
- package/dist/api/capture.d.ts +149 -0
- package/dist/api/capture.d.ts.map +1 -0
- package/dist/api/capture.js +330 -0
- package/dist/api/capture.js.map +1 -0
- package/dist/api/chat-citations.d.ts +174 -0
- package/dist/api/chat-citations.d.ts.map +1 -0
- package/dist/api/chat-citations.js +528 -0
- package/dist/api/chat-citations.js.map +1 -0
- package/dist/api/chat-transcripts.d.ts +20 -1
- package/dist/api/chat-transcripts.d.ts.map +1 -1
- package/dist/api/chat-transcripts.js +29 -0
- package/dist/api/chat-transcripts.js.map +1 -1
- package/dist/api/delivery-cache.d.ts +2 -2
- package/dist/api/delivery-freeze.d.ts +66 -0
- package/dist/api/delivery-freeze.d.ts.map +1 -0
- package/dist/api/delivery-freeze.js +104 -0
- package/dist/api/delivery-freeze.js.map +1 -0
- package/dist/api/delivery-index.d.ts +53 -9
- package/dist/api/delivery-index.d.ts.map +1 -1
- package/dist/api/delivery-index.js +115 -22
- package/dist/api/delivery-index.js.map +1 -1
- package/dist/api/demo.d.ts +90 -0
- package/dist/api/demo.d.ts.map +1 -0
- package/dist/api/demo.js +492 -0
- package/dist/api/demo.js.map +1 -0
- package/dist/api/diagnostics.d.ts +64 -1
- package/dist/api/diagnostics.d.ts.map +1 -1
- package/dist/api/diagnostics.js +129 -1
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/eval-sample.d.ts +6 -6
- package/dist/api/governance-steering.d.ts +2 -2
- package/dist/api/mcp.d.ts +282 -0
- package/dist/api/mcp.d.ts.map +1 -0
- package/dist/api/mcp.js +521 -0
- package/dist/api/mcp.js.map +1 -0
- package/dist/api/plan-schema.d.ts +56 -0
- package/dist/api/plan-schema.d.ts.map +1 -0
- package/dist/api/plan-schema.js +26 -0
- package/dist/api/plan-schema.js.map +1 -0
- package/dist/api/roster-standing.d.ts +15 -2
- package/dist/api/roster-standing.d.ts.map +1 -1
- package/dist/api/roster-standing.js +55 -3
- package/dist/api/roster-standing.js.map +1 -1
- package/dist/api/routes.d.ts +630 -51
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +738 -127
- package/dist/api/routes.js.map +1 -1
- package/dist/api/run-files.d.ts.map +1 -1
- package/dist/api/run-files.js +31 -2
- package/dist/api/run-files.js.map +1 -1
- package/dist/api/run-liveness.d.ts +41 -0
- package/dist/api/run-liveness.d.ts.map +1 -0
- package/dist/api/run-liveness.js +166 -0
- package/dist/api/run-liveness.js.map +1 -0
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +20 -4
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-probe.d.ts +141 -0
- package/dist/api/seat-probe.d.ts.map +1 -0
- package/dist/api/seat-probe.js +257 -0
- package/dist/api/seat-probe.js.map +1 -0
- package/dist/api/seat-record.d.ts +40 -0
- package/dist/api/seat-record.d.ts.map +1 -0
- package/dist/api/seat-record.js +218 -0
- package/dist/api/seat-record.js.map +1 -0
- package/dist/api/seat-signin.d.ts.map +1 -1
- package/dist/api/seat-signin.js +3 -1
- package/dist/api/seat-signin.js.map +1 -1
- package/dist/api/seat-standing.d.ts +24 -4
- package/dist/api/seat-standing.d.ts.map +1 -1
- package/dist/api/seat-standing.js +50 -3
- package/dist/api/seat-standing.js.map +1 -1
- package/dist/api/server.d.ts +34 -48
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +283 -107
- package/dist/api/server.js.map +1 -1
- package/dist/api/skills.d.ts +3 -1
- package/dist/api/skills.d.ts.map +1 -1
- package/dist/api/skills.js +7 -2
- package/dist/api/skills.js.map +1 -1
- package/dist/api/stall-watchdog.d.ts +34 -3
- package/dist/api/stall-watchdog.d.ts.map +1 -1
- package/dist/api/stall-watchdog.js +107 -8
- package/dist/api/stall-watchdog.js.map +1 -1
- package/dist/api/steering-landing.d.ts +6 -6
- package/dist/api/steering-landing.d.ts.map +1 -1
- package/dist/api/steering-landing.js +7 -9
- package/dist/api/steering-landing.js.map +1 -1
- package/dist/api/testing.d.ts +6 -4
- package/dist/api/testing.d.ts.map +1 -1
- package/dist/api/testing.js +82 -47
- package/dist/api/testing.js.map +1 -1
- package/dist/campaign/boot-resume.d.ts +34 -0
- package/dist/campaign/boot-resume.d.ts.map +1 -0
- package/dist/campaign/boot-resume.js +45 -0
- package/dist/campaign/boot-resume.js.map +1 -0
- package/dist/campaigns/rollup.d.ts +4 -1
- package/dist/campaigns/rollup.d.ts.map +1 -1
- package/dist/campaigns/rollup.js +6 -1
- package/dist/campaigns/rollup.js.map +1 -1
- package/dist/campaigns/routes.d.ts +2 -2
- package/dist/cli/bearer.d.ts +27 -1
- package/dist/cli/bearer.d.ts.map +1 -1
- package/dist/cli/bearer.js +62 -2
- package/dist/cli/bearer.js.map +1 -1
- package/dist/cli/governance.d.ts +11 -0
- package/dist/cli/governance.d.ts.map +1 -1
- package/dist/cli/governance.js +8 -2
- package/dist/cli/governance.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +140 -75
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.d.ts +11 -0
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +40 -9
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/service.d.ts +78 -0
- package/dist/cli/service.d.ts.map +1 -0
- package/dist/cli/service.js +334 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/core/adapter.d.ts +238 -12
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +619 -157
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/bridge-reaper.d.ts +4 -1
- package/dist/core/bridge-reaper.d.ts.map +1 -1
- package/dist/core/bridge-reaper.js +15 -1
- package/dist/core/bridge-reaper.js.map +1 -1
- package/dist/core/bus-notice.d.ts +27 -0
- package/dist/core/bus-notice.d.ts.map +1 -0
- package/dist/core/bus-notice.js +24 -0
- package/dist/core/bus-notice.js.map +1 -0
- package/dist/core/bus.d.ts +99 -0
- package/dist/core/bus.d.ts.map +1 -0
- package/dist/core/bus.js +176 -0
- package/dist/core/bus.js.map +1 -0
- package/dist/core/deliver-exclusions.d.ts +71 -0
- package/dist/core/deliver-exclusions.d.ts.map +1 -0
- package/dist/core/deliver-exclusions.js +110 -0
- package/dist/core/deliver-exclusions.js.map +1 -0
- package/dist/core/deliver-text.d.ts +61 -14
- package/dist/core/deliver-text.d.ts.map +1 -1
- package/dist/core/deliver-text.js +178 -30
- package/dist/core/deliver-text.js.map +1 -1
- package/dist/core/deliver-triage.d.ts +11 -2
- package/dist/core/deliver-triage.d.ts.map +1 -1
- package/dist/core/deliver-triage.js +19 -1
- package/dist/core/deliver-triage.js.map +1 -1
- package/dist/core/deliver.d.ts +161 -3
- package/dist/core/deliver.d.ts.map +1 -1
- package/dist/core/deliver.js +463 -25
- package/dist/core/deliver.js.map +1 -1
- package/dist/core/deliverable-floor.d.ts.map +1 -1
- package/dist/core/deliverable-floor.js +5 -7
- package/dist/core/deliverable-floor.js.map +1 -1
- package/dist/core/engine-bus.d.ts +40 -0
- package/dist/core/engine-bus.d.ts.map +1 -0
- package/dist/core/engine-bus.js +27 -0
- package/dist/core/engine-bus.js.map +1 -0
- package/dist/core/estate-mcp-client.d.ts +87 -5
- package/dist/core/estate-mcp-client.d.ts.map +1 -1
- package/dist/core/estate-mcp-client.js +90 -11
- package/dist/core/estate-mcp-client.js.map +1 -1
- package/dist/core/linked-issues.d.ts +46 -0
- package/dist/core/linked-issues.d.ts.map +1 -0
- package/dist/core/linked-issues.js +123 -0
- package/dist/core/linked-issues.js.map +1 -0
- package/dist/core/run-identity.d.ts +100 -0
- package/dist/core/run-identity.d.ts.map +1 -0
- package/dist/core/run-identity.js +178 -0
- package/dist/core/run-identity.js.map +1 -0
- package/dist/core/shutdown.d.ts +16 -0
- package/dist/core/shutdown.d.ts.map +1 -0
- package/dist/core/shutdown.js +39 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/types.d.ts +15 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +67 -3
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +129 -13
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/bridge-root.d.ts +9 -0
- package/dist/interactive/bridge-root.d.ts.map +1 -1
- package/dist/interactive/bridge-root.js +11 -4
- package/dist/interactive/bridge-root.js.map +1 -1
- package/dist/interactive/chat-events.d.ts +14 -9
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +55 -57
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/council-outcome.d.ts +1 -0
- package/dist/interactive/council-outcome.d.ts.map +1 -1
- package/dist/interactive/council-outcome.js +33 -0
- package/dist/interactive/council-outcome.js.map +1 -1
- package/dist/interactive/draft-events.d.ts +36 -17
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +121 -92
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/draft-skill.d.ts +59 -0
- package/dist/interactive/draft-skill.d.ts.map +1 -1
- package/dist/interactive/draft-skill.js +233 -0
- package/dist/interactive/draft-skill.js.map +1 -1
- package/dist/interactive/edit-events.d.ts +1 -14
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +37 -70
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/proxy-routes.d.ts +2 -2
- package/dist/interactive/proxy-routes.d.ts.map +1 -1
- package/dist/interactive/proxy-routes.js +4 -13
- package/dist/interactive/proxy-routes.js.map +1 -1
- package/dist/interactive/ws-relay.d.ts +9 -10
- package/dist/interactive/ws-relay.d.ts.map +1 -1
- package/dist/interactive/ws-relay.js +23 -50
- package/dist/interactive/ws-relay.js.map +1 -1
- package/dist/mcp/broker.d.ts +88 -0
- package/dist/mcp/broker.d.ts.map +1 -0
- package/dist/mcp/broker.js +307 -0
- package/dist/mcp/broker.js.map +1 -0
- package/dist/mcp/call-records.d.ts +61 -0
- package/dist/mcp/call-records.d.ts.map +1 -0
- package/dist/mcp/call-records.js +135 -0
- package/dist/mcp/call-records.js.map +1 -0
- package/dist/mcp/classify.d.ts +45 -0
- package/dist/mcp/classify.d.ts.map +1 -0
- package/dist/mcp/classify.js +83 -0
- package/dist/mcp/classify.js.map +1 -0
- package/dist/mcp/discovery.d.ts +24 -0
- package/dist/mcp/discovery.d.ts.map +1 -0
- package/dist/mcp/discovery.js +78 -0
- package/dist/mcp/discovery.js.map +1 -0
- package/dist/mcp/invoke.d.ts +36 -0
- package/dist/mcp/invoke.d.ts.map +1 -0
- package/dist/mcp/invoke.js +80 -0
- package/dist/mcp/invoke.js.map +1 -0
- package/dist/mcp/policies.d.ts +110 -0
- package/dist/mcp/policies.d.ts.map +1 -0
- package/dist/mcp/policies.js +400 -0
- package/dist/mcp/policies.js.map +1 -0
- package/dist/mcp/probe.d.ts +66 -0
- package/dist/mcp/probe.d.ts.map +1 -0
- package/dist/mcp/probe.js +116 -0
- package/dist/mcp/probe.js.map +1 -0
- package/dist/mcp/redact.d.ts +34 -0
- package/dist/mcp/redact.d.ts.map +1 -0
- package/dist/mcp/redact.js +84 -0
- package/dist/mcp/redact.js.map +1 -0
- package/dist/mcp/registry-store.d.ts +69 -0
- package/dist/mcp/registry-store.d.ts.map +1 -0
- package/dist/mcp/registry-store.js +82 -0
- package/dist/mcp/registry-store.js.map +1 -0
- package/dist/mcp/registry.d.ts +147 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +509 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/rest.d.ts +111 -0
- package/dist/mcp/rest.d.ts.map +1 -0
- package/dist/mcp/rest.js +606 -0
- package/dist/mcp/rest.js.map +1 -0
- package/dist/mcp/secrets.d.ts +66 -0
- package/dist/mcp/secrets.d.ts.map +1 -0
- package/dist/mcp/secrets.js +180 -0
- package/dist/mcp/secrets.js.map +1 -0
- package/dist/mcp/tool-list.d.ts +25 -0
- package/dist/mcp/tool-list.d.ts.map +1 -0
- package/dist/mcp/tool-list.js +62 -0
- package/dist/mcp/tool-list.js.map +1 -0
- package/dist/mcp/upstream-error.d.ts +12 -0
- package/dist/mcp/upstream-error.d.ts.map +1 -0
- package/dist/mcp/upstream-error.js +14 -0
- package/dist/mcp/upstream-error.js.map +1 -0
- package/dist/mcp/usage.d.ts +31 -0
- package/dist/mcp/usage.d.ts.map +1 -0
- package/dist/mcp/usage.js +159 -0
- package/dist/mcp/usage.js.map +1 -0
- package/dist/presets/routes.d.ts +53 -0
- package/dist/presets/routes.d.ts.map +1 -0
- package/dist/presets/routes.js +115 -0
- package/dist/presets/routes.js.map +1 -0
- package/dist/projects/activity.d.ts +6 -18
- package/dist/projects/activity.d.ts.map +1 -1
- package/dist/projects/activity.js +17 -60
- package/dist/projects/activity.js.map +1 -1
- package/dist/projects/events.d.ts +6 -5
- package/dist/projects/events.d.ts.map +1 -1
- package/dist/projects/events.js +33 -58
- package/dist/projects/events.js.map +1 -1
- package/dist/projects/routes.d.ts.map +1 -1
- package/dist/projects/routes.js +19 -0
- package/dist/projects/routes.js.map +1 -1
- package/dist/projects/state-home-preflight.d.ts.map +1 -1
- package/dist/projects/state-home-preflight.js +7 -0
- package/dist/projects/state-home-preflight.js.map +1 -1
- package/dist/projects/state-home-registry.d.ts.map +1 -1
- package/dist/projects/state-home-registry.js +9 -1
- package/dist/projects/state-home-registry.js.map +1 -1
- package/dist/qe/acceptance.d.ts +28 -28
- package/dist/qe/acceptance.d.ts.map +1 -1
- package/dist/qe/acceptance.js +60 -61
- package/dist/qe/acceptance.js.map +1 -1
- package/dist/qe/test-sets.d.ts +3 -5
- package/dist/qe/test-sets.d.ts.map +1 -1
- package/dist/qe/test-sets.js +5 -7
- package/dist/qe/test-sets.js.map +1 -1
- package/dist/skills/installed.d.ts +51 -0
- package/dist/skills/installed.d.ts.map +1 -0
- package/dist/skills/installed.js +46 -0
- package/dist/skills/installed.js.map +1 -0
- package/dist/standing-orders/evaluator.d.ts +113 -0
- package/dist/standing-orders/evaluator.d.ts.map +1 -0
- package/dist/standing-orders/evaluator.js +225 -0
- package/dist/standing-orders/evaluator.js.map +1 -0
- package/dist/standing-orders/history.d.ts +58 -0
- package/dist/standing-orders/history.d.ts.map +1 -0
- package/dist/standing-orders/history.js +117 -0
- package/dist/standing-orders/history.js.map +1 -0
- package/dist/standing-orders/parse.d.ts +19 -0
- package/dist/standing-orders/parse.d.ts.map +1 -0
- package/dist/standing-orders/parse.js +75 -0
- package/dist/standing-orders/parse.js.map +1 -0
- package/dist/standing-orders/routes.d.ts +180 -0
- package/dist/standing-orders/routes.d.ts.map +1 -0
- package/dist/standing-orders/routes.js +95 -0
- package/dist/standing-orders/routes.js.map +1 -0
- package/dist/standing-orders/store.d.ts +154 -0
- package/dist/standing-orders/store.d.ts.map +1 -0
- package/dist/standing-orders/store.js +189 -0
- package/dist/standing-orders/store.js.map +1 -0
- package/dist/studio/assets/index-CvV5qITf.css +32 -0
- package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
- package/dist/studio/index.html +3 -3
- package/dist/studio/testid-inventory.json +3274 -894
- package/dist/team/key.d.ts +5 -0
- package/dist/team/key.d.ts.map +1 -0
- package/dist/team/key.js +21 -0
- package/dist/team/key.js.map +1 -0
- package/dist/team/routes.d.ts +196 -0
- package/dist/team/routes.d.ts.map +1 -0
- package/dist/team/routes.js +274 -0
- package/dist/team/routes.js.map +1 -0
- package/dist/team/ws-relay.d.ts +39 -0
- package/dist/team/ws-relay.d.ts.map +1 -0
- package/dist/team/ws-relay.js +63 -0
- package/dist/team/ws-relay.js.map +1 -0
- package/endpoint-manifest.json +502 -6
- package/package.json +6 -6
- package/dist/interactive/demo-events.d.ts +0 -367
- package/dist/interactive/demo-events.d.ts.map +0 -1
- package/dist/interactive/demo-events.js +0 -1293
- package/dist/interactive/demo-events.js.map +0 -1
- package/dist/qe/gate-events.d.ts +0 -113
- package/dist/qe/gate-events.d.ts.map +0 -1
- package/dist/qe/gate-events.js +0 -172
- package/dist/qe/gate-events.js.map +0 -1
- package/dist/studio/assets/index-Bg7Z3BR-.css +0 -32
- package/dist/studio/assets/index-BvOFMjf9.js +0 -554
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool identity and class (DES-MCP-TOOLS-001 §4.2, §5).
|
|
3
|
+
*
|
|
4
|
+
* - The SUBJECT is the policy token a tool is judged by: `mcp:<server>/<tool>`. A server name
|
|
5
|
+
* never contains `/`, so the first `/` after `mcp:` always splits it.
|
|
6
|
+
* - The CLASS comes from the tool's own `tools/list` annotations, never from a carrier (F-2):
|
|
7
|
+
* an operator override wins; else `read` when `readOnlyHint === true`; else `destructive` when
|
|
8
|
+
* `destructiveHint !== false` (the MCP spec default); else `write`. A tool with NO annotations
|
|
9
|
+
* is `write` (D-4).
|
|
10
|
+
* - The SCHEMA HASH covers everything a policy or an operator approved: description, input and
|
|
11
|
+
* output schema, annotations, and a `rest` tool's request mapping. Any change sends the tool back to unregistered (D-5) until it
|
|
12
|
+
* is previewed and saved again.
|
|
13
|
+
*/
|
|
14
|
+
import type { McpRestMapping, McpToolAnnotations, McpToolClass } from '../core/types.js';
|
|
15
|
+
/** A server name: a lowercase token that is safe inside `mcp:<server>/<tool>` and a keychain account. */
|
|
16
|
+
export declare const MCP_SERVER_NAME_RE: RegExp;
|
|
17
|
+
export declare function mcpSubject(server: string, tool: string): string;
|
|
18
|
+
/** `mcp:<server>/<tool>` → its parts, or `null` for anything else. */
|
|
19
|
+
export declare function parseMcpSubject(subject: string): {
|
|
20
|
+
server: string;
|
|
21
|
+
tool: string;
|
|
22
|
+
} | null;
|
|
23
|
+
/**
|
|
24
|
+
* The class `tools/list` annotations imply (§4.2), exactly as the engine's `mcp_gate::classify`
|
|
25
|
+
* derives it (`tests/mcp-policies.test.ts` pins the two against each other): `null` annotations, or
|
|
26
|
+
* annotations carrying neither `readOnlyHint` nor `destructiveHint`, = none declared = `write` (D-4).
|
|
27
|
+
*/
|
|
28
|
+
export declare function deriveToolClass(annotations: McpToolAnnotations | null): McpToolClass;
|
|
29
|
+
/** The class a policy sees: the operator's override when set, else the derived one. */
|
|
30
|
+
export declare function effectiveToolClass(derived: McpToolClass, override: McpToolClass | null): McpToolClass;
|
|
31
|
+
/** JSON with object keys sorted at every depth, so a hash never depends on key order. */
|
|
32
|
+
export declare function canonicalJson(value: unknown): string;
|
|
33
|
+
export declare function sha256Hex(text: string): string;
|
|
34
|
+
/** The fields of a listed tool the schema hash covers. */
|
|
35
|
+
export interface HashedToolShape {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string | null;
|
|
38
|
+
inputSchema: Record<string, unknown> | null;
|
|
39
|
+
outputSchema: Record<string, unknown> | null;
|
|
40
|
+
annotations: McpToolAnnotations | null;
|
|
41
|
+
/** A `rest` tool's request mapping: part of what was approved, so a changed mapping re-registers. */
|
|
42
|
+
rest?: McpRestMapping | null;
|
|
43
|
+
}
|
|
44
|
+
export declare function toolSchemaHash(tool: HashedToolShape): string;
|
|
45
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/mcp/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEzF,yGAAyG;AACzG,eAAO,MAAM,kBAAkB,QAA+B,CAAC;AAE/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQxF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI,GAAG,YAAY,CAMpF;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,GAAG,YAAY,CAErG;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAcD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACvC,qGAAqG;IACrG,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAY5D"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool identity and class (DES-MCP-TOOLS-001 §4.2, §5).
|
|
3
|
+
*
|
|
4
|
+
* - The SUBJECT is the policy token a tool is judged by: `mcp:<server>/<tool>`. A server name
|
|
5
|
+
* never contains `/`, so the first `/` after `mcp:` always splits it.
|
|
6
|
+
* - The CLASS comes from the tool's own `tools/list` annotations, never from a carrier (F-2):
|
|
7
|
+
* an operator override wins; else `read` when `readOnlyHint === true`; else `destructive` when
|
|
8
|
+
* `destructiveHint !== false` (the MCP spec default); else `write`. A tool with NO annotations
|
|
9
|
+
* is `write` (D-4).
|
|
10
|
+
* - The SCHEMA HASH covers everything a policy or an operator approved: description, input and
|
|
11
|
+
* output schema, annotations, and a `rest` tool's request mapping. Any change sends the tool back to unregistered (D-5) until it
|
|
12
|
+
* is previewed and saved again.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
/** A server name: a lowercase token that is safe inside `mcp:<server>/<tool>` and a keychain account. */
|
|
16
|
+
export const MCP_SERVER_NAME_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;
|
|
17
|
+
export function mcpSubject(server, tool) {
|
|
18
|
+
return `mcp:${server}/${tool}`;
|
|
19
|
+
}
|
|
20
|
+
/** `mcp:<server>/<tool>` → its parts, or `null` for anything else. */
|
|
21
|
+
export function parseMcpSubject(subject) {
|
|
22
|
+
if (!subject.startsWith('mcp:'))
|
|
23
|
+
return null;
|
|
24
|
+
const rest = subject.slice(4);
|
|
25
|
+
const slash = rest.indexOf('/');
|
|
26
|
+
if (slash <= 0 || slash === rest.length - 1)
|
|
27
|
+
return null;
|
|
28
|
+
const server = rest.slice(0, slash);
|
|
29
|
+
if (!MCP_SERVER_NAME_RE.test(server))
|
|
30
|
+
return null;
|
|
31
|
+
return { server, tool: rest.slice(slash + 1) };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The class `tools/list` annotations imply (§4.2), exactly as the engine's `mcp_gate::classify`
|
|
35
|
+
* derives it (`tests/mcp-policies.test.ts` pins the two against each other): `null` annotations, or
|
|
36
|
+
* annotations carrying neither `readOnlyHint` nor `destructiveHint`, = none declared = `write` (D-4).
|
|
37
|
+
*/
|
|
38
|
+
export function deriveToolClass(annotations) {
|
|
39
|
+
if (annotations === null)
|
|
40
|
+
return 'write';
|
|
41
|
+
if (annotations.readOnlyHint === true)
|
|
42
|
+
return 'read';
|
|
43
|
+
if (annotations.readOnlyHint === undefined && annotations.destructiveHint === undefined)
|
|
44
|
+
return 'write';
|
|
45
|
+
if (annotations.destructiveHint !== false)
|
|
46
|
+
return 'destructive';
|
|
47
|
+
return 'write';
|
|
48
|
+
}
|
|
49
|
+
/** The class a policy sees: the operator's override when set, else the derived one. */
|
|
50
|
+
export function effectiveToolClass(derived, override) {
|
|
51
|
+
return override ?? derived;
|
|
52
|
+
}
|
|
53
|
+
/** JSON with object keys sorted at every depth, so a hash never depends on key order. */
|
|
54
|
+
export function canonicalJson(value) {
|
|
55
|
+
return JSON.stringify(sortKeys(value));
|
|
56
|
+
}
|
|
57
|
+
function sortKeys(value) {
|
|
58
|
+
if (Array.isArray(value))
|
|
59
|
+
return value.map(sortKeys);
|
|
60
|
+
if (value !== null && typeof value === 'object') {
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const key of Object.keys(value).sort()) {
|
|
63
|
+
out[key] = sortKeys(value[key]);
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
export function sha256Hex(text) {
|
|
70
|
+
return createHash('sha256').update(text, 'utf8').digest('hex');
|
|
71
|
+
}
|
|
72
|
+
export function toolSchemaHash(tool) {
|
|
73
|
+
return sha256Hex(canonicalJson({
|
|
74
|
+
name: tool.name,
|
|
75
|
+
description: tool.description,
|
|
76
|
+
inputSchema: tool.inputSchema,
|
|
77
|
+
outputSchema: tool.outputSchema,
|
|
78
|
+
annotations: tool.annotations,
|
|
79
|
+
// Only when present, so an MCP tool's hash is what it was before REST upstreams existed.
|
|
80
|
+
...(tool.rest != null ? { rest: tool.rest } : {}),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/mcp/classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Discovered, not managed" (DES-MCP-TOOLS-001 §7, §8 `GET /mcp/servers`): the MCP servers the
|
|
3
|
+
* CLIs on this machine are configured with, by NAME only.
|
|
4
|
+
*
|
|
5
|
+
* - Read-only. Each CLI's own config file is parsed and only the server names leave this module:
|
|
6
|
+
* never a command, URL, header or env value, because those are where a pasted token lives.
|
|
7
|
+
* - Two origins. `operator`: the CLI's default home under the operator's home dir. `worker`: each
|
|
8
|
+
* seat's own root under the worker home, `<worker home>/<cli>` and every instance root
|
|
9
|
+
* `<worker home>/<cli>-<n>` (the layout of wicked-apps-core `seat_config_for_seat`, core#591). A worker-home server is invariant I1's finding: no wicked-handed native MCP
|
|
10
|
+
* server may sit in a worker home, so studio lists these in red.
|
|
11
|
+
* - A file that is absent or does not parse contributes nothing; discovery never fails a request.
|
|
12
|
+
*/
|
|
13
|
+
import type { McpDiscoveredServer } from '../core/types.js';
|
|
14
|
+
/** `[mcp_servers.<id>]` table headers in a codex `config.toml` (bare or quoted ids; sub-tables folded). */
|
|
15
|
+
export declare function codexServerNames(text: string): string[];
|
|
16
|
+
export interface DiscoveryRoots {
|
|
17
|
+
/** The operator's home dir. */
|
|
18
|
+
home: string;
|
|
19
|
+
/** The worker home (`WICKED_WORKER_HOME`); `null` = none configured. */
|
|
20
|
+
workerHome: string | null;
|
|
21
|
+
}
|
|
22
|
+
/** Every server name configured in a CLI home; `managed` is set by the caller against the registry. */
|
|
23
|
+
export declare function discoverMcpServers(roots: DiscoveryRoots, managed: ReadonlySet<string>): McpDiscoveredServer[];
|
|
24
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/mcp/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAgB5D,2GAA2G;AAC3G,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAOvD;AA8BD,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAUD,uGAAuG;AACvG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,mBAAmB,EAAE,CAa7G"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Discovered, not managed" (DES-MCP-TOOLS-001 §7, §8 `GET /mcp/servers`): the MCP servers the
|
|
3
|
+
* CLIs on this machine are configured with, by NAME only.
|
|
4
|
+
*
|
|
5
|
+
* - Read-only. Each CLI's own config file is parsed and only the server names leave this module:
|
|
6
|
+
* never a command, URL, header or env value, because those are where a pasted token lives.
|
|
7
|
+
* - Two origins. `operator`: the CLI's default home under the operator's home dir. `worker`: each
|
|
8
|
+
* seat's own root under the worker home, `<worker home>/<cli>` and every instance root
|
|
9
|
+
* `<worker home>/<cli>-<n>` (the layout of wicked-apps-core `seat_config_for_seat`, core#591). A worker-home server is invariant I1's finding: no wicked-handed native MCP
|
|
10
|
+
* server may sit in a worker home, so studio lists these in red.
|
|
11
|
+
* - A file that is absent or does not parse contributes nothing; discovery never fails a request.
|
|
12
|
+
*/
|
|
13
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
/** Keys of a JSON object at `path`, or `[]`. */
|
|
16
|
+
function jsonKeys(...path) {
|
|
17
|
+
return (text) => {
|
|
18
|
+
let node = JSON.parse(text);
|
|
19
|
+
for (const key of path) {
|
|
20
|
+
if (node === null || typeof node !== 'object' || Array.isArray(node))
|
|
21
|
+
return [];
|
|
22
|
+
node = node[key];
|
|
23
|
+
}
|
|
24
|
+
return node !== null && typeof node === 'object' && !Array.isArray(node) ? Object.keys(node) : [];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** `[mcp_servers.<id>]` table headers in a codex `config.toml` (bare or quoted ids; sub-tables folded). */
|
|
28
|
+
export function codexServerNames(text) {
|
|
29
|
+
const names = new Set();
|
|
30
|
+
// The id must be followed by the table's end or a sub-table dot: a torn header names nothing.
|
|
31
|
+
const re = /^\s*\[\s*mcp_servers\.(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9_-]+))\s*[.\]]/gm;
|
|
32
|
+
for (let m = re.exec(text); m !== null; m = re.exec(text))
|
|
33
|
+
names.add(m[1] ?? m[2] ?? m[3] ?? '');
|
|
34
|
+
names.delete('');
|
|
35
|
+
return [...names];
|
|
36
|
+
}
|
|
37
|
+
const SOURCES = [
|
|
38
|
+
{ cli: 'claude', operator: '.claude.json', worker: '.claude.json', parse: jsonKeys('mcpServers') },
|
|
39
|
+
{ cli: 'codex', operator: '.codex/config.toml', worker: 'config.toml', parse: codexServerNames },
|
|
40
|
+
{ cli: 'copilot', operator: '.copilot/mcp-config.json', worker: 'mcp-config.json', parse: jsonKeys('mcpServers') },
|
|
41
|
+
{ cli: 'opencode', operator: '.config/opencode/opencode.json', worker: 'config/opencode/opencode.json', parse: jsonKeys('mcp') },
|
|
42
|
+
{ cli: 'agy', operator: '.gemini/config/mcp_config.json', worker: '.gemini/config/mcp_config.json', parse: jsonKeys('mcpServers') },
|
|
43
|
+
];
|
|
44
|
+
/** A seat's root dirs in the worker home: `<cli>`, and each instance root `<cli>-<n>` (core#591). */
|
|
45
|
+
function seatRoots(workerHome, cli) {
|
|
46
|
+
let entries;
|
|
47
|
+
try {
|
|
48
|
+
entries = readdirSync(workerHome);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
return entries.filter((e) => e === cli || (e.startsWith(`${cli}-`) && /^[A-Za-z0-9_]+$/.test(e.slice(cli.length + 1)))).sort();
|
|
54
|
+
}
|
|
55
|
+
function namesIn(file, parse) {
|
|
56
|
+
try {
|
|
57
|
+
return parse(readFileSync(file, 'utf8'));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Every server name configured in a CLI home; `managed` is set by the caller against the registry. */
|
|
64
|
+
export function discoverMcpServers(roots, managed) {
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const src of SOURCES) {
|
|
67
|
+
for (const name of namesIn(join(roots.home, src.operator), src.parse)) {
|
|
68
|
+
out.push({ name, cli: src.cli, origin: 'operator', source: `~/${src.operator}`, managed: managed.has(name) });
|
|
69
|
+
}
|
|
70
|
+
for (const seat of roots.workerHome === null ? [] : seatRoots(roots.workerHome, src.cli)) {
|
|
71
|
+
for (const name of namesIn(join(roots.workerHome, seat, src.worker), src.parse)) {
|
|
72
|
+
out.push({ name, cli: src.cli, origin: 'worker', source: `<worker home>/${seat}/${src.worker}`, managed: managed.has(name) });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/mcp/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoke one tool on one upstream MCP server (DES-MCP-TOOLS-001 §6 step 6).
|
|
3
|
+
*
|
|
4
|
+
* - One connection per call: connect, `tools/call`, close. The upstream is reached exactly as the
|
|
5
|
+
* registry's probe reaches it (`transportFor`: the SDK's safe env for stdio plus the ONE variable
|
|
6
|
+
* the secret is injected into, or the one auth header for http), so the secret is resolved and
|
|
7
|
+
* injected here and nowhere else.
|
|
8
|
+
* - Bounded: connect and call share one deadline; a hung upstream is closed and the call fails
|
|
9
|
+
* with the error class `timeout`.
|
|
10
|
+
* - Every failure is classified ({@link classifyUpstreamError}) so the broker can decide whether a
|
|
11
|
+
* retry is allowed (step 7: transport errors, 429 and 5xx only) and what the call record says.
|
|
12
|
+
*
|
|
13
|
+
* A `rest` upstream is not an MCP server: its tools are single HTTP requests (`rest.ts`).
|
|
14
|
+
*
|
|
15
|
+
* The result is returned RAW: the broker scrubs it (D-2) before anything else sees it.
|
|
16
|
+
*/
|
|
17
|
+
import type { McpRestMapping } from '../core/types.js';
|
|
18
|
+
import { type McpUpstreamConfig } from './probe.js';
|
|
19
|
+
import { UpstreamCallError } from './upstream-error.js';
|
|
20
|
+
/** The default per-call deadline (connect + call). */
|
|
21
|
+
export declare const MCP_CALL_TIMEOUT_MS = 30000;
|
|
22
|
+
export { UpstreamCallError, type UpstreamErrorClass } from './upstream-error.js';
|
|
23
|
+
/** A `tools/call` result as the upstream sent it (`content`, `structuredContent?`, `isError?`, ...). */
|
|
24
|
+
export type UpstreamToolResult = Record<string, unknown>;
|
|
25
|
+
export type Invoker = (config: McpUpstreamConfig, secret: string | null, tool: string, args: Record<string, unknown>, timeoutMs: number,
|
|
26
|
+
/** A `rest` tool's request mapping (slice S5a); `null` for an MCP server's tool. */
|
|
27
|
+
rest?: McpRestMapping | null) => Promise<UpstreamToolResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Classify a failure: transport errors (the connection could not be made or closed under the
|
|
30
|
+
* call), HTTP 429 and 5xx are retryable; a timeout, any other HTTP status and a JSON-RPC error the
|
|
31
|
+
* server answered are not.
|
|
32
|
+
*/
|
|
33
|
+
export declare function classifyUpstreamError(err: unknown): UpstreamCallError;
|
|
34
|
+
/** The real invoker. */
|
|
35
|
+
export declare const invokeMcpTool: Invoker;
|
|
36
|
+
//# sourceMappingURL=invoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/mcp/invoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,wGAAwG;AACxG,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,MAAM,OAAO,GAAG,CACpB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,MAAM;AACjB,oFAAoF;AACpF,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,KACzB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAarE;AAED,wBAAwB;AACxB,eAAO,MAAM,aAAa,EAAE,OA8B3B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoke one tool on one upstream MCP server (DES-MCP-TOOLS-001 §6 step 6).
|
|
3
|
+
*
|
|
4
|
+
* - One connection per call: connect, `tools/call`, close. The upstream is reached exactly as the
|
|
5
|
+
* registry's probe reaches it (`transportFor`: the SDK's safe env for stdio plus the ONE variable
|
|
6
|
+
* the secret is injected into, or the one auth header for http), so the secret is resolved and
|
|
7
|
+
* injected here and nowhere else.
|
|
8
|
+
* - Bounded: connect and call share one deadline; a hung upstream is closed and the call fails
|
|
9
|
+
* with the error class `timeout`.
|
|
10
|
+
* - Every failure is classified ({@link classifyUpstreamError}) so the broker can decide whether a
|
|
11
|
+
* retry is allowed (step 7: transport errors, 429 and 5xx only) and what the call record says.
|
|
12
|
+
*
|
|
13
|
+
* A `rest` upstream is not an MCP server: its tools are single HTTP requests (`rest.ts`).
|
|
14
|
+
*
|
|
15
|
+
* The result is returned RAW: the broker scrubs it (D-2) before anything else sees it.
|
|
16
|
+
*/
|
|
17
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
18
|
+
import { StreamableHTTPError } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
19
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
20
|
+
import { transportFor } from './probe.js';
|
|
21
|
+
import { invokeRestTool } from './rest.js';
|
|
22
|
+
import { UpstreamCallError } from './upstream-error.js';
|
|
23
|
+
/** The default per-call deadline (connect + call). */
|
|
24
|
+
export const MCP_CALL_TIMEOUT_MS = 30_000;
|
|
25
|
+
export { UpstreamCallError } from './upstream-error.js';
|
|
26
|
+
/**
|
|
27
|
+
* Classify a failure: transport errors (the connection could not be made or closed under the
|
|
28
|
+
* call), HTTP 429 and 5xx are retryable; a timeout, any other HTTP status and a JSON-RPC error the
|
|
29
|
+
* server answered are not.
|
|
30
|
+
*/
|
|
31
|
+
export function classifyUpstreamError(err) {
|
|
32
|
+
if (err instanceof UpstreamCallError)
|
|
33
|
+
return err;
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
if (err instanceof StreamableHTTPError) {
|
|
36
|
+
const status = typeof err.code === 'number' ? err.code : 0;
|
|
37
|
+
return new UpstreamCallError('http', status === 429 || status >= 500, message);
|
|
38
|
+
}
|
|
39
|
+
if (err instanceof McpError) {
|
|
40
|
+
if (err.code === ErrorCode.ConnectionClosed)
|
|
41
|
+
return new UpstreamCallError('transport', true, message);
|
|
42
|
+
if (err.code === ErrorCode.RequestTimeout)
|
|
43
|
+
return new UpstreamCallError('timeout', false, message);
|
|
44
|
+
return new UpstreamCallError('protocol', false, message);
|
|
45
|
+
}
|
|
46
|
+
return new UpstreamCallError('transport', true, message);
|
|
47
|
+
}
|
|
48
|
+
/** The real invoker. */
|
|
49
|
+
export const invokeMcpTool = async (config, secret, tool, args, timeoutMs, rest = null) => {
|
|
50
|
+
if (config.kind === 'rest') {
|
|
51
|
+
// A REST tool is one pinned HTTP request, built from its allowlisted arguments (I6).
|
|
52
|
+
if (rest === null)
|
|
53
|
+
throw new UpstreamCallError('protocol', false, `${tool} has no REST mapping; test and save the server again`);
|
|
54
|
+
return invokeRestTool(config, secret, rest, args, timeoutMs);
|
|
55
|
+
}
|
|
56
|
+
const { transport, stderrTail } = transportFor(config, secret);
|
|
57
|
+
const client = new Client({ name: 'wicked-crew-mcp-broker', version: '1' }, { capabilities: {} });
|
|
58
|
+
let timer;
|
|
59
|
+
const deadline = new Promise((_, reject) => {
|
|
60
|
+
timer = setTimeout(() => reject(new UpstreamCallError('timeout', false, `timed out after ${Math.round(timeoutMs / 1000)} s`)), timeoutMs);
|
|
61
|
+
});
|
|
62
|
+
const work = (async () => {
|
|
63
|
+
await client.connect(transport);
|
|
64
|
+
return (await client.callTool({ name: tool, arguments: args }, undefined, { timeout: timeoutMs }));
|
|
65
|
+
})();
|
|
66
|
+
try {
|
|
67
|
+
return await Promise.race([work, deadline]);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
work.catch(() => undefined);
|
|
71
|
+
const classified = classifyUpstreamError(err);
|
|
72
|
+
const tail = stderrTail().trim();
|
|
73
|
+
throw tail === '' ? classified : new UpstreamCallError(classified.errorClass, classified.retryable, `${classified.message}; stderr: ${tail}`);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
await client.close().catch(() => undefined);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=invoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/mcp/invoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EAAE,YAAY,EAA0B,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,sDAAsD;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AAejF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAChD,IAAI,GAAG,YAAY,iBAAiB;QAAE,OAAO,GAAG,CAAC;IACjD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,MAAM,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,IAAI,KAAM,SAAS,CAAC,gBAA2B;YAAE,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAClH,IAAI,GAAG,CAAC,IAAI,KAAM,SAAS,CAAC,cAAyB;YAAE,OAAO,IAAI,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/G,OAAO,IAAI,iBAAiB,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,wBAAwB;AACxB,MAAM,CAAC,MAAM,aAAa,GAAY,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE;IACjG,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,qFAAqF;QACrF,IAAI,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,sDAAsD,CAAC,CAAC;QACjI,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;IAClG,IAAI,KAAiC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAChD,KAAK,GAAG,UAAU,CAChB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,mBAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAC1G,SAAS,CACV,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,KAAK,IAAiC,EAAE;QACpD,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAuB,CAAC;IAC3H,CAAC,CAAC,EAAE,CAAC;IACL,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC,OAAO,aAAa,IAAI,EAAE,CAAC,CAAC;IAChJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP policies: the preview matrix and the approvals (DES-MCP-TOOLS-001 §4.5, §4.7, §8; slice S6).
|
|
3
|
+
*
|
|
4
|
+
* - **Preview.** `preview` answers what a call to each tool WOULD get, per phase role × seat × run
|
|
5
|
+
* mode, under the policies in the store right now. It is the engine's own evaluation
|
|
6
|
+
* (`Core.previewMcpCalls`, the same `evaluate` the broker's `evaluateMcpCall` runs) over
|
|
7
|
+
* synthetic unit cells, and nothing is recorded. `previewUnsaved` does the same for a server
|
|
8
|
+
* that is being added, judged as if it were saved now.
|
|
9
|
+
* - **Approvals.** An approval is an audited policy edit, never a grant. It adds a token to the
|
|
10
|
+
* `excludes` of the ledger rules the `mcp-defaults` pack ships: `MCP-FIRST-USE` (the first use
|
|
11
|
+
* of a server asks in every mode) and `MCP-POSTURE-WRITE` (balanced mode asks for a write until
|
|
12
|
+
* the tool is approved). Approving a SERVER (`mcp:<server>`) approves its first use only, so its
|
|
13
|
+
* write tools still ask in balanced mode, one by one (§4.5: a server-level grant would hide the
|
|
14
|
+
* destructive tools behind the one read the operator tried). Approving a TOOL
|
|
15
|
+
* (`mcp:<server>/<tool>`) approves that tool's first use and its writes. Revoking removes the
|
|
16
|
+
* token from both. An approval never lifts an engine gate (D-1, D-5) or an explicit deny:
|
|
17
|
+
* deny dominates in the engine.
|
|
18
|
+
* - **Withdrawal.** A saved tool whose schema changed, and a removed server, lose their approvals,
|
|
19
|
+
* so the next call asks again (operator decision 1: first use asks, "and again when a tool's
|
|
20
|
+
* schema changes"). A server-wide approval cannot exclude one tool, so a changed tool withdraws
|
|
21
|
+
* the server's approval too: the server asks again on its next first use.
|
|
22
|
+
*
|
|
23
|
+
* Ledger edits are read-modify-write of one rule, so they are serialized here.
|
|
24
|
+
*/
|
|
25
|
+
import type { ConformanceRule, McpApprovalsResponse, McpPhaseRole, McpPolicyPreviewResponse, McpPreviewTool, McpRunMode, McpUpstreamKind } from '../core/types.js';
|
|
26
|
+
import { McpRegistryError, type McpRegistry } from './registry.js';
|
|
27
|
+
/**
|
|
28
|
+
* A ledger edit that failed part-way. `changed` names the rules still changed after the rollback
|
|
29
|
+
* (empty when the rollback restored them all); the route audits those before answering 502.
|
|
30
|
+
*/
|
|
31
|
+
export declare class McpLedgerEditError extends McpRegistryError {
|
|
32
|
+
readonly changed: string[];
|
|
33
|
+
constructor(changed: string[], message: string);
|
|
34
|
+
}
|
|
35
|
+
/** The first-use approvals ledger (the engine reads its `excludes`, active or retired). */
|
|
36
|
+
export declare const FIRST_USE_LEDGER = "MCP-FIRST-USE";
|
|
37
|
+
/** The balanced-mode write approvals ledger. */
|
|
38
|
+
export declare const WRITE_LEDGER = "MCP-POSTURE-WRITE";
|
|
39
|
+
/** The six seats a governed unit can run on; the matrix has one column per seat. */
|
|
40
|
+
export declare const MCP_PREVIEW_SEATS: readonly ["claude", "codex", "opencode", "copilot", "pi", "agy"];
|
|
41
|
+
export declare const MCP_PREVIEW_ROLES: readonly McpPhaseRole[];
|
|
42
|
+
export declare const MCP_RUN_MODES: readonly McpRunMode[];
|
|
43
|
+
/** The engine seam this module needs: the rule store and the preview binding. */
|
|
44
|
+
export interface McpPolicyEngine {
|
|
45
|
+
listRules(): Promise<ConformanceRule[]>;
|
|
46
|
+
upsertRule(rule: ConformanceRule): Promise<void>;
|
|
47
|
+
/** `Core.previewMcpCalls`: `{calls, cells}` → `[{subject, cells}]` as JSON. */
|
|
48
|
+
previewCalls(requestJson: string): Promise<string>;
|
|
49
|
+
}
|
|
50
|
+
export interface McpPolicyQuery {
|
|
51
|
+
subject?: string | undefined;
|
|
52
|
+
server?: string | undefined;
|
|
53
|
+
phaseRole?: McpPhaseRole | undefined;
|
|
54
|
+
seat?: string | undefined;
|
|
55
|
+
mode?: McpRunMode | undefined;
|
|
56
|
+
phaseId?: string | undefined;
|
|
57
|
+
}
|
|
58
|
+
/** `mcp:<server>` or `mcp:<server>/<tool>` → its parts, or `null`. */
|
|
59
|
+
export declare function parseApprovalSubject(subject: string): {
|
|
60
|
+
server: string;
|
|
61
|
+
tool: string | null;
|
|
62
|
+
} | null;
|
|
63
|
+
export declare class McpPolicies {
|
|
64
|
+
private readonly registry;
|
|
65
|
+
private readonly engine;
|
|
66
|
+
private chain;
|
|
67
|
+
constructor(registry: McpRegistry, engine: McpPolicyEngine);
|
|
68
|
+
preview(query: McpPolicyQuery): Promise<McpPolicyPreviewResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* The matrix for a server that is being added (`POST /mcp/servers/preview`): every tool judged
|
|
71
|
+
* as if the preview were saved now, so the operator sees what would run, ask or be denied.
|
|
72
|
+
*/
|
|
73
|
+
previewUnsaved(server: {
|
|
74
|
+
name: string;
|
|
75
|
+
kind: McpUpstreamKind;
|
|
76
|
+
}, tools: McpPreviewTool[]): Promise<McpPolicyPreviewResponse>;
|
|
77
|
+
approvals(): Promise<McpApprovalsResponse>;
|
|
78
|
+
/** Approve a subject (a server: first use; a tool: first use and writes). Answers the rule ids that changed. */
|
|
79
|
+
approve(subject: string): Promise<string[]>;
|
|
80
|
+
/** Revoke a subject's approval from both ledgers. 404 when neither holds it. */
|
|
81
|
+
revoke(subject: string): Promise<string[]>;
|
|
82
|
+
/** Remove every listed token from both ledgers (revoke, a changed schema, a removed server). */
|
|
83
|
+
withdraw(tokens: readonly string[]): Promise<string[]>;
|
|
84
|
+
/**
|
|
85
|
+
* The approval tokens saving `next` over the registered server of the same name withdraws: each
|
|
86
|
+
* tool whose saved schema changed, and the server's own token when any did (a server-wide
|
|
87
|
+
* approval cannot leave one tool out). Empty for a new server or an unchanged one.
|
|
88
|
+
*/
|
|
89
|
+
withdrawnBySave(next: {
|
|
90
|
+
name: string;
|
|
91
|
+
tools: ReadonlyArray<{
|
|
92
|
+
name: string;
|
|
93
|
+
schemaHash: string;
|
|
94
|
+
}>;
|
|
95
|
+
}): Promise<string[]>;
|
|
96
|
+
/** Every approval token that names `server` (the server's own and each of its tools'). */
|
|
97
|
+
tokensOf(server: string): Promise<string[]>;
|
|
98
|
+
private cells;
|
|
99
|
+
private axes;
|
|
100
|
+
private judge;
|
|
101
|
+
private ledgers;
|
|
102
|
+
private approvalOf;
|
|
103
|
+
/**
|
|
104
|
+
* Apply `next` to both ledgers' `excludes`, serialized. `next` answers the new list or `null` for
|
|
105
|
+
* no change. A missing ledger refuses the edit: the pack is seeded at boot, so its absence means
|
|
106
|
+
* the store is not the engine's (fail closed, nothing half-written).
|
|
107
|
+
*/
|
|
108
|
+
private edit;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../src/mcp/policies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,eAAe,EAEf,oBAAoB,EAKpB,YAAY,EAEZ,wBAAwB,EACxB,cAAc,EACd,UAAU,EAKV,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAEnE;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,gBAAgB;IAEpD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE;gBAAjB,OAAO,EAAE,MAAM,EAAE,EAC1B,OAAO,EAAE,MAAM;CAIlB;AAED,2FAA2F;AAC3F,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAChD,gDAAgD;AAChD,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAEhD,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,kEAAmE,CAAC;AAClG,eAAO,MAAM,iBAAiB,EAAE,SAAS,YAAY,EAAsC,CAAC;AAC5F,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAAsC,CAAC;AAEtF,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACxC,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,+EAA+E;IAC/E,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AA0BD,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAOpG;AAmBD,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,KAAK,CAAuC;gBAGjC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,eAAe;IAKpC,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA6CvE;;;OAGG;IACG,cAAc,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAgC3H,SAAS,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAwBhD,gHAAgH;IAC1G,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBjD,gFAAgF;IAC1E,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOhD,gGAAgG;IAC1F,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU5D;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqB5H,0FAA0F;IACpF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOjD,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,IAAI;YAUE,KAAK;YAkCL,OAAO;IAerB,OAAO,CAAC,UAAU;IAOlB;;;;OAIG;IACH,OAAO,CAAC,IAAI;CA0Cb"}
|