@sonoma-security/mcp-gateway 0.1.11 → 0.1.13
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/__tests__/plugin-discovery.test.d.ts +12 -0
- package/dist/__tests__/plugin-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-discovery.test.js +367 -0
- package/dist/__tests__/plugin-discovery.test.js.map +1 -0
- package/dist/__tests__/tool-blocking.test.d.ts +2 -0
- package/dist/__tests__/tool-blocking.test.d.ts.map +1 -0
- package/dist/__tests__/tool-blocking.test.js +256 -0
- package/dist/__tests__/tool-blocking.test.js.map +1 -0
- package/dist/auth/client.d.ts.map +1 -1
- package/dist/auth/client.js +49 -6
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/keychain.d.ts +34 -0
- package/dist/auth/keychain.d.ts.map +1 -0
- package/dist/auth/keychain.js +305 -0
- package/dist/auth/keychain.js.map +1 -0
- package/dist/auth/server.d.ts +15 -3
- package/dist/auth/server.d.ts.map +1 -1
- package/dist/auth/server.js +110 -23
- package/dist/auth/server.js.map +1 -1
- package/dist/auth/storage.d.ts +5 -6
- package/dist/auth/storage.d.ts.map +1 -1
- package/dist/auth/storage.js +72 -21
- package/dist/auth/storage.js.map +1 -1
- package/dist/auth/upstream-oauth.d.ts +2 -0
- package/dist/auth/upstream-oauth.d.ts.map +1 -1
- package/dist/auth/upstream-oauth.js +58 -8
- package/dist/auth/upstream-oauth.js.map +1 -1
- package/dist/auth/upstream-token-store.d.ts +18 -6
- package/dist/auth/upstream-token-store.d.ts.map +1 -1
- package/dist/auth/upstream-token-store.js +127 -35
- package/dist/auth/upstream-token-store.js.map +1 -1
- package/dist/cli.js +16 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -7
- package/dist/config.js.map +1 -1
- package/dist/gateway.d.ts +17 -0
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +302 -66
- package/dist/gateway.js.map +1 -1
- package/dist/http-proxy.d.ts +76 -0
- package/dist/http-proxy.d.ts.map +1 -0
- package/dist/http-proxy.js +316 -0
- package/dist/http-proxy.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pattern-matcher.d.ts +25 -0
- package/dist/pattern-matcher.d.ts.map +1 -1
- package/dist/pattern-matcher.js +65 -0
- package/dist/pattern-matcher.js.map +1 -1
- package/dist/prompt-guard.d.ts +24 -0
- package/dist/prompt-guard.d.ts.map +1 -0
- package/dist/prompt-guard.js +161 -0
- package/dist/prompt-guard.js.map +1 -0
- package/dist/sonoma-client.d.ts +28 -1
- package/dist/sonoma-client.d.ts.map +1 -1
- package/dist/sonoma-client.js +67 -43
- package/dist/sonoma-client.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Proxy Server for MCP Gateway
|
|
3
|
+
*
|
|
4
|
+
* Exposes per-server HTTP endpoints that transparently proxy MCP requests
|
|
5
|
+
* to upstream servers. This allows plugins to keep their skills active
|
|
6
|
+
* while traffic flows through the gateway for policy enforcement and telemetry.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Plugin (http://localhost:{port}/proxy/{serverName}) -> HTTP Proxy -> Upstream MCP Server
|
|
10
|
+
*
|
|
11
|
+
* Each upstream server gets its own MCP Server + StreamableHTTPServerTransport,
|
|
12
|
+
* which delegates tools/list and tools/call to the upstream Client connection
|
|
13
|
+
* managed by the parent McpGateway.
|
|
14
|
+
*/
|
|
15
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
16
|
+
export interface HttpProxyUpstream {
|
|
17
|
+
name: string;
|
|
18
|
+
client: Client;
|
|
19
|
+
connected: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface HttpProxyCallbacks {
|
|
22
|
+
/** Get the current list of upstream connections */
|
|
23
|
+
getUpstreams(): Map<string, HttpProxyUpstream>;
|
|
24
|
+
/** Check if a tool is blocked by policy. Returns true if blocked. */
|
|
25
|
+
isToolBlocked(serverName: string, toolName: string): boolean;
|
|
26
|
+
/** Record a tool call event for telemetry */
|
|
27
|
+
recordToolCall(event: {
|
|
28
|
+
serverName: string;
|
|
29
|
+
toolName: string;
|
|
30
|
+
durationMs: number;
|
|
31
|
+
status: "success" | "error" | "blocked";
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
argumentKeys?: string[];
|
|
34
|
+
}): void;
|
|
35
|
+
/** Get server names that are pending OAuth authentication */
|
|
36
|
+
getPendingAuthServers?(): Set<string>;
|
|
37
|
+
/** Get the upstream URL for a server (used for OAuth discovery forwarding) */
|
|
38
|
+
getUpstreamUrl?(serverName: string): string | undefined;
|
|
39
|
+
/** Debug logging */
|
|
40
|
+
log(message: string): void;
|
|
41
|
+
}
|
|
42
|
+
export declare class HttpProxyServer {
|
|
43
|
+
private httpServer;
|
|
44
|
+
private callbacks;
|
|
45
|
+
private sessions;
|
|
46
|
+
private port;
|
|
47
|
+
constructor(port: number, callbacks: HttpProxyCallbacks);
|
|
48
|
+
start(): Promise<void>;
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Get the proxy URL for a specific server.
|
|
52
|
+
* Plugins should rewrite their URLs to this endpoint.
|
|
53
|
+
*/
|
|
54
|
+
getProxyUrl(serverName: string): string;
|
|
55
|
+
private handleRequest;
|
|
56
|
+
/**
|
|
57
|
+
* Forward OAuth protected resource metadata from the upstream server.
|
|
58
|
+
*
|
|
59
|
+
* The MCP SDK queries /.well-known/oauth-protected-resource{path} to discover
|
|
60
|
+
* where to send the user for authentication. We forward this from the real
|
|
61
|
+
* upstream (e.g., mcp.slack.com) but rewrite the `resource` field to match
|
|
62
|
+
* the proxy URL so the SDK's validation passes.
|
|
63
|
+
*/
|
|
64
|
+
private handleOAuthDiscovery;
|
|
65
|
+
/**
|
|
66
|
+
* Create a new MCP Server that proxies requests to an upstream Client.
|
|
67
|
+
* Each session gets its own Server + Transport pair.
|
|
68
|
+
*
|
|
69
|
+
* The session is created immediately even if the upstream isn't connected yet.
|
|
70
|
+
* tools/list returns empty tools in that case, and tool calls return errors.
|
|
71
|
+
* When the upstream connects, the gateway sends toolListChanged which triggers
|
|
72
|
+
* the client to re-fetch tools.
|
|
73
|
+
*/
|
|
74
|
+
private createProxySession;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=http-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-proxy.d.ts","sourceRoot":"","sources":["../src/http-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAcH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC/C,qEAAqE;IACrE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7D,6CAA6C;IAC7C,cAAc,CAAC,KAAK,EAAE;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;QACxC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,6DAA6D;IAC7D,qBAAqB,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACtC,8EAA8E;IAC9E,cAAc,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACxD,oBAAoB;IACpB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAWD,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,IAAI,CAAS;gBAET,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB;IAMjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;YAIzB,aAAa;IAmF3B;;;;;;;OAOG;YACW,oBAAoB;IAkDlC;;;;;;;;OAQG;YACW,kBAAkB;CA4JjC"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Proxy Server for MCP Gateway
|
|
3
|
+
*
|
|
4
|
+
* Exposes per-server HTTP endpoints that transparently proxy MCP requests
|
|
5
|
+
* to upstream servers. This allows plugins to keep their skills active
|
|
6
|
+
* while traffic flows through the gateway for policy enforcement and telemetry.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Plugin (http://localhost:{port}/proxy/{serverName}) -> HTTP Proxy -> Upstream MCP Server
|
|
10
|
+
*
|
|
11
|
+
* Each upstream server gets its own MCP Server + StreamableHTTPServerTransport,
|
|
12
|
+
* which delegates tools/list and tools/call to the upstream Client connection
|
|
13
|
+
* managed by the parent McpGateway.
|
|
14
|
+
*/
|
|
15
|
+
import { createServer } from "node:http";
|
|
16
|
+
import { randomUUID } from "node:crypto";
|
|
17
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
18
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
19
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
20
|
+
const TOOL_CALL_TIMEOUT_MS = 30_000;
|
|
21
|
+
export class HttpProxyServer {
|
|
22
|
+
httpServer;
|
|
23
|
+
callbacks;
|
|
24
|
+
sessions = new Map();
|
|
25
|
+
port;
|
|
26
|
+
constructor(port, callbacks) {
|
|
27
|
+
this.port = port;
|
|
28
|
+
this.callbacks = callbacks;
|
|
29
|
+
this.httpServer = createServer(this.handleRequest.bind(this));
|
|
30
|
+
}
|
|
31
|
+
async start() {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
this.httpServer.on("error", reject);
|
|
34
|
+
this.httpServer.listen(this.port, () => {
|
|
35
|
+
this.callbacks.log(`HTTP proxy server listening on port ${this.port}`);
|
|
36
|
+
resolve();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async stop() {
|
|
41
|
+
// Close all sessions
|
|
42
|
+
for (const [sessionId, session] of this.sessions) {
|
|
43
|
+
try {
|
|
44
|
+
await session.transport.close();
|
|
45
|
+
await session.server.close();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Ignore close errors
|
|
49
|
+
}
|
|
50
|
+
this.sessions.delete(sessionId);
|
|
51
|
+
}
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
this.httpServer.close(() => resolve());
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the proxy URL for a specific server.
|
|
58
|
+
* Plugins should rewrite their URLs to this endpoint.
|
|
59
|
+
*/
|
|
60
|
+
getProxyUrl(serverName) {
|
|
61
|
+
return `http://localhost:${this.port}/proxy/${encodeURIComponent(serverName)}/mcp`;
|
|
62
|
+
}
|
|
63
|
+
async handleRequest(req, res) {
|
|
64
|
+
const url = new URL(req.url ?? "/", `http://localhost:${this.port}`);
|
|
65
|
+
// CORS headers for local access
|
|
66
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
67
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
68
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Last-Event-ID");
|
|
69
|
+
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
70
|
+
if (req.method === "OPTIONS") {
|
|
71
|
+
res.writeHead(204);
|
|
72
|
+
res.end();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Forward OAuth protected resource discovery to the upstream server so the
|
|
76
|
+
// MCP SDK learns where the real authorization endpoint is (e.g., slack.com)
|
|
77
|
+
// instead of constructing localhost:19880/authorize which doesn't exist.
|
|
78
|
+
if (url.pathname.startsWith("/.well-known/oauth-protected-resource")) {
|
|
79
|
+
await this.handleOAuthDiscovery(url, res);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Return 404 for /authorize and other .well-known endpoints.
|
|
83
|
+
if (url.pathname.startsWith("/.well-known/") || url.pathname === "/authorize") {
|
|
84
|
+
res.writeHead(404);
|
|
85
|
+
res.end();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Parse /proxy/{serverName}/mcp
|
|
89
|
+
const match = url.pathname.match(/^\/proxy\/([^/]+)\/mcp$/);
|
|
90
|
+
if (!match) {
|
|
91
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
92
|
+
res.end(JSON.stringify({ error: "Not found. Use /proxy/{serverName}/mcp" }));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const serverName = decodeURIComponent(match[1]);
|
|
96
|
+
// Get or create session
|
|
97
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
98
|
+
if (req.method === "GET" || req.method === "DELETE") {
|
|
99
|
+
// SSE or session termination: route to existing session
|
|
100
|
+
if (sessionId && this.sessions.has(sessionId)) {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guarded by this.sessions.has(sessionId) above
|
|
102
|
+
const session = this.sessions.get(sessionId);
|
|
103
|
+
await session.transport.handleRequest(req, res);
|
|
104
|
+
if (req.method === "DELETE") {
|
|
105
|
+
this.sessions.delete(sessionId);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (req.method === "DELETE") {
|
|
110
|
+
res.writeHead(200);
|
|
111
|
+
res.end();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// GET without session: not valid
|
|
115
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
116
|
+
res.end(JSON.stringify({ error: "Session required for GET requests" }));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// POST: create new session or route to existing
|
|
120
|
+
if (sessionId && this.sessions.has(sessionId)) {
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guarded by this.sessions.has(sessionId) above
|
|
122
|
+
await this.sessions.get(sessionId).transport.handleRequest(req, res);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// New session: create a proxy MCP server for this server name.
|
|
126
|
+
// The session is created immediately (even if the upstream isn't connected
|
|
127
|
+
// yet) so the MCP handshake completes and Claude Code marks it as
|
|
128
|
+
// "connected". tools/list will return empty until the upstream connects,
|
|
129
|
+
// then we send toolListChanged.
|
|
130
|
+
const session = await this.createProxySession(serverName);
|
|
131
|
+
await session.transport.handleRequest(req, res);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Forward OAuth protected resource metadata from the upstream server.
|
|
135
|
+
*
|
|
136
|
+
* The MCP SDK queries /.well-known/oauth-protected-resource{path} to discover
|
|
137
|
+
* where to send the user for authentication. We forward this from the real
|
|
138
|
+
* upstream (e.g., mcp.slack.com) but rewrite the `resource` field to match
|
|
139
|
+
* the proxy URL so the SDK's validation passes.
|
|
140
|
+
*/
|
|
141
|
+
async handleOAuthDiscovery(url, res) {
|
|
142
|
+
// Extract server name from path suffix: /.well-known/oauth-protected-resource/proxy/{name}/mcp
|
|
143
|
+
const pathMatch = url.pathname.match(/^\/\.well-known\/oauth-protected-resource\/proxy\/([^/]+)\/mcp$/);
|
|
144
|
+
if (!pathMatch) {
|
|
145
|
+
res.writeHead(404);
|
|
146
|
+
res.end();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const serverName = decodeURIComponent(pathMatch[1]);
|
|
150
|
+
const upstreamUrl = this.callbacks.getUpstreamUrl?.(serverName);
|
|
151
|
+
if (!upstreamUrl) {
|
|
152
|
+
res.writeHead(404);
|
|
153
|
+
res.end();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const upstreamOrigin = new URL(upstreamUrl).origin;
|
|
158
|
+
const discoveryUrl = `${upstreamOrigin}/.well-known/oauth-protected-resource`;
|
|
159
|
+
const response = await fetch(discoveryUrl, {
|
|
160
|
+
headers: { Accept: "application/json" },
|
|
161
|
+
redirect: "follow",
|
|
162
|
+
});
|
|
163
|
+
if (!response.ok) {
|
|
164
|
+
res.writeHead(response.status);
|
|
165
|
+
res.end();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const metadata = await response.json();
|
|
169
|
+
// Rewrite the resource field to match the proxy URL so the SDK's
|
|
170
|
+
// "protected resource does not match" validation passes
|
|
171
|
+
metadata.resource = `http://localhost:${this.port}/proxy/${encodeURIComponent(serverName)}/mcp`;
|
|
172
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
173
|
+
res.end(JSON.stringify(metadata));
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
res.writeHead(502);
|
|
177
|
+
res.end();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a new MCP Server that proxies requests to an upstream Client.
|
|
182
|
+
* Each session gets its own Server + Transport pair.
|
|
183
|
+
*
|
|
184
|
+
* The session is created immediately even if the upstream isn't connected yet.
|
|
185
|
+
* tools/list returns empty tools in that case, and tool calls return errors.
|
|
186
|
+
* When the upstream connects, the gateway sends toolListChanged which triggers
|
|
187
|
+
* the client to re-fetch tools.
|
|
188
|
+
*/
|
|
189
|
+
async createProxySession(serverName) {
|
|
190
|
+
const callbacks = this.callbacks;
|
|
191
|
+
const server = new Server({
|
|
192
|
+
name: `sonoma-proxy-${serverName}`,
|
|
193
|
+
version: "0.1.0",
|
|
194
|
+
}, {
|
|
195
|
+
capabilities: {
|
|
196
|
+
tools: { listChanged: true },
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
// Proxy tools/list: forward to upstream client if connected, empty otherwise
|
|
200
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
201
|
+
const upstream = callbacks.getUpstreams().get(serverName);
|
|
202
|
+
if (!upstream?.connected) {
|
|
203
|
+
return { tools: [] };
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
const result = await upstream.client.listTools();
|
|
207
|
+
return { tools: result.tools };
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
callbacks.log(`Failed to list tools from ${serverName}: ${error}`);
|
|
211
|
+
return { tools: [] };
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// Proxy tools/call: check policy, forward to upstream, record telemetry
|
|
215
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
216
|
+
const { name: toolName, arguments: args } = request.params;
|
|
217
|
+
const startTime = Date.now();
|
|
218
|
+
// Check policy before forwarding
|
|
219
|
+
if (callbacks.isToolBlocked(serverName, toolName)) {
|
|
220
|
+
callbacks.recordToolCall({
|
|
221
|
+
serverName,
|
|
222
|
+
toolName,
|
|
223
|
+
durationMs: Date.now() - startTime,
|
|
224
|
+
status: "blocked",
|
|
225
|
+
argumentKeys: args ? Object.keys(args) : [],
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
isError: true,
|
|
229
|
+
content: [
|
|
230
|
+
{
|
|
231
|
+
type: "text",
|
|
232
|
+
text: `Tool ${serverName}.${toolName} is blocked by organization policy`,
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const upstream = callbacks.getUpstreams().get(serverName);
|
|
238
|
+
if (!upstream?.connected) {
|
|
239
|
+
return {
|
|
240
|
+
isError: true,
|
|
241
|
+
content: [
|
|
242
|
+
{
|
|
243
|
+
type: "text",
|
|
244
|
+
text: `Server ${serverName} is not connected yet. Please wait for the connection to be established.`,
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const callPromise = upstream.client.callTool({
|
|
251
|
+
name: toolName,
|
|
252
|
+
arguments: args,
|
|
253
|
+
});
|
|
254
|
+
const callTimeout = new Promise((_, reject) => {
|
|
255
|
+
setTimeout(() => reject(new Error(`Tool call timeout after ${TOOL_CALL_TIMEOUT_MS}ms`)), TOOL_CALL_TIMEOUT_MS);
|
|
256
|
+
});
|
|
257
|
+
const result = await Promise.race([callPromise, callTimeout]);
|
|
258
|
+
callbacks.recordToolCall({
|
|
259
|
+
serverName,
|
|
260
|
+
toolName,
|
|
261
|
+
durationMs: Date.now() - startTime,
|
|
262
|
+
status: "success",
|
|
263
|
+
argumentKeys: args ? Object.keys(args) : [],
|
|
264
|
+
});
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
269
|
+
callbacks.recordToolCall({
|
|
270
|
+
serverName,
|
|
271
|
+
toolName,
|
|
272
|
+
durationMs: Date.now() - startTime,
|
|
273
|
+
status: "error",
|
|
274
|
+
errorMessage,
|
|
275
|
+
argumentKeys: args ? Object.keys(args) : [],
|
|
276
|
+
});
|
|
277
|
+
return {
|
|
278
|
+
isError: true,
|
|
279
|
+
content: [
|
|
280
|
+
{
|
|
281
|
+
type: "text",
|
|
282
|
+
text: `Error calling ${serverName}.${toolName}: ${errorMessage}`,
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
const transport = new StreamableHTTPServerTransport({
|
|
289
|
+
sessionIdGenerator: () => randomUUID(),
|
|
290
|
+
});
|
|
291
|
+
// Track session by ID once the transport assigns one
|
|
292
|
+
transport.onclose = () => {
|
|
293
|
+
if (transport.sessionId) {
|
|
294
|
+
this.sessions.delete(transport.sessionId);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
await server.connect(transport);
|
|
298
|
+
const session = { server, transport, serverName };
|
|
299
|
+
// Store session after transport is connected (sessionId is set during handleRequest)
|
|
300
|
+
// We'll store it by the transport's sessionId after the first request
|
|
301
|
+
if (transport.sessionId) {
|
|
302
|
+
this.sessions.set(transport.sessionId, session);
|
|
303
|
+
}
|
|
304
|
+
// Also set up a hook to store the session once the ID is assigned
|
|
305
|
+
const origHandleRequest = transport.handleRequest.bind(transport);
|
|
306
|
+
transport.handleRequest = async (req, res, body) => {
|
|
307
|
+
await origHandleRequest(req, res, body);
|
|
308
|
+
if (transport.sessionId && !this.sessions.has(transport.sessionId)) {
|
|
309
|
+
this.sessions.set(transport.sessionId, session);
|
|
310
|
+
callbacks.log(`HTTP proxy session created: ${transport.sessionId} -> ${serverName}`);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
return session;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=http-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-proxy.js","sourceRoot":"","sources":["../src/http-proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* Proxies MCP servers and reports telemetry to Sonoma.
|
|
6
6
|
*/
|
|
7
7
|
export { McpGateway } from "./gateway.js";
|
|
8
|
+
export { isToolBlockedByPolicy, matchesToolPattern, getPatternSpecificity, isValidToolPattern } from "./pattern-matcher.js";
|
|
9
|
+
export type { PolicyRuleForBlocking } from "./pattern-matcher.js";
|
|
10
|
+
export { HttpProxyServer } from "./http-proxy.js";
|
|
8
11
|
export { loadConfig, findClaudeDesktopConfig, createTestConfig, autoDetectConfig, getMcpConfigPaths, type McpConfigLocation } from "./config.js";
|
|
9
12
|
export type { GatewayConfig, McpServerConfig, ToolCallEvent, ToolInfo, UpstreamServer, } from "./types.js";
|
|
10
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjJ,YAAY,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC5H,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjJ,YAAY,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,5 +5,7 @@
|
|
|
5
5
|
* Proxies MCP servers and reports telemetry to Sonoma.
|
|
6
6
|
*/
|
|
7
7
|
export { McpGateway } from "./gateway.js";
|
|
8
|
+
export { isToolBlockedByPolicy, matchesToolPattern, getPatternSpecificity, isValidToolPattern } from "./pattern-matcher.js";
|
|
9
|
+
export { HttpProxyServer } from "./http-proxy.js";
|
|
8
10
|
export { loadConfig, findClaudeDesktopConfig, createTestConfig, autoDetectConfig, getMcpConfigPaths } from "./config.js";
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAA0B,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE5H,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAA0B,MAAM,aAAa,CAAC"}
|
|
@@ -44,4 +44,29 @@ export declare function getPatternSpecificity(pattern: string | null): number;
|
|
|
44
44
|
* @returns true if the pattern is valid
|
|
45
45
|
*/
|
|
46
46
|
export declare function isValidToolPattern(pattern: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Policy rule shape used for tool blocking evaluation.
|
|
49
|
+
* Matches the PolicyRule type from sonoma-client but avoids circular imports.
|
|
50
|
+
*/
|
|
51
|
+
export interface PolicyRuleForBlocking {
|
|
52
|
+
identifier: string;
|
|
53
|
+
status: string;
|
|
54
|
+
toolPattern: string | null;
|
|
55
|
+
priority: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Pure-function implementation of tool-level policy blocking.
|
|
59
|
+
*
|
|
60
|
+
* Evaluates a list of policy rules against a (serverName, toolName) pair
|
|
61
|
+
* to determine whether the tool call should be blocked.
|
|
62
|
+
*
|
|
63
|
+
* Resolution order:
|
|
64
|
+
* 1. Collect all rules whose identifier matches serverName, packageName, URL, or extra aliases.
|
|
65
|
+
* 2. For each rule, check if toolPattern matches (null = server-level).
|
|
66
|
+
* 3. Sort by priority (higher wins), then pattern specificity (more specific wins).
|
|
67
|
+
* 4. At the top priority/specificity level, deny wins (blocked takes precedence).
|
|
68
|
+
*
|
|
69
|
+
* @returns true if the tool is blocked, false if allowed
|
|
70
|
+
*/
|
|
71
|
+
export declare function isToolBlockedByPolicy(policyList: PolicyRuleForBlocking[], serverName: string, toolName: string, packageName?: string | null, url?: string | null, extraIdentifiers?: string[]): boolean;
|
|
47
72
|
//# sourceMappingURL=pattern-matcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pattern-matcher.d.ts","sourceRoot":"","sources":["../src/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CA0B7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAW3D"}
|
|
1
|
+
{"version":3,"file":"pattern-matcher.d.ts","sourceRoot":"","sources":["../src/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CA0B7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAW3D;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,qBAAqB,EAAE,EACnC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,EAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAC1B,OAAO,CAyDT"}
|
package/dist/pattern-matcher.js
CHANGED
|
@@ -95,4 +95,69 @@ export function isValidToolPattern(pattern) {
|
|
|
95
95
|
const validPattern = /^[a-zA-Z0-9_\-*./]+$/;
|
|
96
96
|
return validPattern.test(pattern);
|
|
97
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Pure-function implementation of tool-level policy blocking.
|
|
100
|
+
*
|
|
101
|
+
* Evaluates a list of policy rules against a (serverName, toolName) pair
|
|
102
|
+
* to determine whether the tool call should be blocked.
|
|
103
|
+
*
|
|
104
|
+
* Resolution order:
|
|
105
|
+
* 1. Collect all rules whose identifier matches serverName, packageName, URL, or extra aliases.
|
|
106
|
+
* 2. For each rule, check if toolPattern matches (null = server-level).
|
|
107
|
+
* 3. Sort by priority (higher wins), then pattern specificity (more specific wins).
|
|
108
|
+
* 4. At the top priority/specificity level, deny wins (blocked takes precedence).
|
|
109
|
+
*
|
|
110
|
+
* @returns true if the tool is blocked, false if allowed
|
|
111
|
+
*/
|
|
112
|
+
export function isToolBlockedByPolicy(policyList, serverName, toolName, packageName, url, extraIdentifiers) {
|
|
113
|
+
// Build set of identifiers: packageName, server name, URL, and aliases
|
|
114
|
+
const serverIdentifiers = new Set();
|
|
115
|
+
if (packageName)
|
|
116
|
+
serverIdentifiers.add(packageName);
|
|
117
|
+
serverIdentifiers.add(serverName);
|
|
118
|
+
if (url)
|
|
119
|
+
serverIdentifiers.add(url);
|
|
120
|
+
if (extraIdentifiers) {
|
|
121
|
+
for (const id of extraIdentifiers)
|
|
122
|
+
serverIdentifiers.add(id);
|
|
123
|
+
}
|
|
124
|
+
// Find all matching rules (server-level and tool-level)
|
|
125
|
+
const matchingRules = policyList.filter((rule) => {
|
|
126
|
+
// Check if server identifier matches (or rule is global with "*")
|
|
127
|
+
const serverMatches = serverIdentifiers.has(rule.identifier) || rule.identifier === "*";
|
|
128
|
+
if (!serverMatches)
|
|
129
|
+
return false;
|
|
130
|
+
// Check tool pattern match
|
|
131
|
+
if (!rule.toolPattern) {
|
|
132
|
+
// Server-level rule - applies to all tools on this server
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
// Tool-level rule - check if pattern matches the tool name
|
|
136
|
+
return matchesToolPattern(toolName, rule.toolPattern);
|
|
137
|
+
});
|
|
138
|
+
// No matching rules = not blocked (unlisted servers are allowed)
|
|
139
|
+
if (matchingRules.length === 0) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
// Sort rules by priority (higher first), then by pattern specificity (more specific first)
|
|
143
|
+
const sortedRules = [...matchingRules].sort((a, b) => {
|
|
144
|
+
// First sort by explicit priority (higher wins)
|
|
145
|
+
if (a.priority !== b.priority)
|
|
146
|
+
return b.priority - a.priority;
|
|
147
|
+
// Then by pattern specificity (more specific wins)
|
|
148
|
+
const specA = getPatternSpecificity(a.toolPattern);
|
|
149
|
+
const specB = getPatternSpecificity(b.toolPattern);
|
|
150
|
+
return specB - specA;
|
|
151
|
+
});
|
|
152
|
+
// Get the highest priority rule
|
|
153
|
+
const topRule = sortedRules[0];
|
|
154
|
+
// Find if there's a deny rule at the same priority level
|
|
155
|
+
const topPriority = topRule.priority;
|
|
156
|
+
const topSpecificity = getPatternSpecificity(topRule.toolPattern);
|
|
157
|
+
const denyAtTopLevel = sortedRules.find((r) => r.status === "blocked" &&
|
|
158
|
+
r.priority === topPriority &&
|
|
159
|
+
getPatternSpecificity(r.toolPattern) === topSpecificity);
|
|
160
|
+
// Block if any matching rule says "blocked" (deny wins at same priority)
|
|
161
|
+
return !!denyAtTopLevel;
|
|
162
|
+
}
|
|
98
163
|
//# sourceMappingURL=pattern-matcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pattern-matcher.js","sourceRoot":"","sources":["../src/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,OAAe;IAClE,0BAA0B;IAC1B,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAEtC,0CAA0C;IAC1C,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEjC,wEAAwE;IACxE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,gCAAgC;IAChC,2CAA2C;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;IAC9D,qCAAqC;IACrC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;IAEzD,IAAI,CAAC;QACH,yFAAyF;QACzF,8FAA8F;QAC9F,gGAAgG;QAChG,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAsB;IAC1D,sCAAsC;IACtC,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC;IAEvB,qBAAqB;IACrB,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC;IAE9B,yEAAyE;IACzE,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;QAC5D,OAAO,EAAE,GAAG,iBAAiB,CAAC;IAChC,CAAC;IAED,6CAA6C;IAC7C,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,6BAA6B;IAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAEpD,+BAA+B;IAC/B,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvC,+CAA+C;IAC/C,qEAAqE;IACrE,MAAM,YAAY,GAAG,sBAAsB,CAAC;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC"}
|
|
1
|
+
{"version":3,"file":"pattern-matcher.js","sourceRoot":"","sources":["../src/pattern-matcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Guard Evaluator (standalone, no server-side imports)
|
|
3
|
+
*
|
|
4
|
+
* Evaluates prompt guards against tool call content using in-memory
|
|
5
|
+
* regex matching. Used by the remote gateway to enforce guards synced
|
|
6
|
+
* from the policy endpoint.
|
|
7
|
+
*/
|
|
8
|
+
import type { PromptGuardRule } from "./sonoma-client.js";
|
|
9
|
+
export interface PromptGuardEvaluation {
|
|
10
|
+
blocked: boolean;
|
|
11
|
+
blockReason: string | null;
|
|
12
|
+
results: Array<{
|
|
13
|
+
guardId: string;
|
|
14
|
+
guardName: string;
|
|
15
|
+
action: "block" | "warn" | "log";
|
|
16
|
+
reason: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Evaluate prompt guards against serialized tool call content.
|
|
21
|
+
* Filters to only guards that run on the remote gateway.
|
|
22
|
+
*/
|
|
23
|
+
export declare function evaluatePromptGuards(guards: PromptGuardRule[], content: string): PromptGuardEvaluation;
|
|
24
|
+
//# sourceMappingURL=prompt-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-guard.d.ts","sourceRoot":"","sources":["../src/prompt-guard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,KAAK,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;QACjC,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AA+ID;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EAAE,EACzB,OAAO,EAAE,MAAM,GACd,qBAAqB,CA0BvB"}
|