@sonoma-security/mcp-gateway 0.1.12 → 0.1.14
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__/config.test.js +140 -2
- package/dist/__tests__/config.test.js.map +1 -1
- 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/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/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.map +1 -1
- package/dist/auth/upstream-oauth.js +8 -5
- 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 +48 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +122 -27
- package/dist/config.js.map +1 -1
- package/dist/gateway.d.ts +15 -0
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +302 -68
- package/dist/gateway.js.map +1 -1
- package/dist/http-proxy.d.ts +126 -0
- package/dist/http-proxy.d.ts.map +1 -0
- package/dist/http-proxy.js +875 -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/sonoma-client.d.ts +17 -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 +14 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Proxy Server for MCP Gateway
|
|
3
|
+
*
|
|
4
|
+
* Transparent HTTP passthrough that forwards all MCP traffic (including OAuth
|
|
5
|
+
* discovery, auth headers, SSE streams) to upstream servers. Parses JSON-RPC
|
|
6
|
+
* request/response bodies for telemetry and policy enforcement.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Client (http://localhost:{port}/proxy/{serverName}/mcp)
|
|
10
|
+
* -> HTTP Proxy (parse JSON-RPC, enforce policy, record telemetry)
|
|
11
|
+
* -> Upstream MCP Server (https://mcp.example.com/mcp)
|
|
12
|
+
*
|
|
13
|
+
* Unlike the previous MCP-level proxy (which terminated MCP sessions and
|
|
14
|
+
* created its own Server/Transport), this is a true HTTP passthrough.
|
|
15
|
+
* OAuth, SSE, session headers all flow through untouched.
|
|
16
|
+
*/
|
|
17
|
+
import { type Server } from "node:http";
|
|
18
|
+
/**
|
|
19
|
+
* Bind an HTTP server to the given port immediately, returning both the server
|
|
20
|
+
* and a promise that resolves once it's listening. The server responds to any
|
|
21
|
+
* request with 503 Service Unavailable until `adoptHttpServer` swaps in a real
|
|
22
|
+
* handler. This lets the caller hold the port during slow startup work (auth,
|
|
23
|
+
* policy fetch, upstream connections) so clients probing the port get
|
|
24
|
+
* "service starting" instead of ECONNREFUSED.
|
|
25
|
+
*
|
|
26
|
+
* On EADDRINUSE, the bind is retried for up to ~10s. The launchd/Scheduled
|
|
27
|
+
* Task supervisor races its own bootout against the new process, and the
|
|
28
|
+
* old owner can hold the socket briefly during teardown. Without the retry
|
|
29
|
+
* the fresh daemon crashes immediately, and each crash-loop wipes any
|
|
30
|
+
* in-memory MCP session state, stranding clients with stale session IDs.
|
|
31
|
+
*/
|
|
32
|
+
export declare function preListenHttpServer(port: number): {
|
|
33
|
+
server: Server;
|
|
34
|
+
listening: Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
export interface HttpProxyCallbacks {
|
|
37
|
+
/** Resolve a server name to its upstream URL */
|
|
38
|
+
getUpstreamUrl(serverName: string): string | undefined;
|
|
39
|
+
/** Check if a server has a connected stdio upstream (no URL, command-based) */
|
|
40
|
+
hasStdioUpstream(serverName: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Forward a JSON-RPC request to a stdio upstream and return the JSON-RPC response.
|
|
43
|
+
* Used for servers that have no URL (command-based / stdio transports).
|
|
44
|
+
*/
|
|
45
|
+
forwardJsonRpc(serverName: string, method: string, params?: unknown): Promise<{
|
|
46
|
+
result?: unknown;
|
|
47
|
+
error?: {
|
|
48
|
+
code: number;
|
|
49
|
+
message: string;
|
|
50
|
+
data?: unknown;
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
/** Check if a tool is blocked by policy. Returns true if blocked. */
|
|
54
|
+
isToolBlocked(serverName: string, toolName: string): boolean;
|
|
55
|
+
/** Record a tool call event for telemetry */
|
|
56
|
+
recordToolCall(event: {
|
|
57
|
+
serverName: string;
|
|
58
|
+
toolName: string;
|
|
59
|
+
durationMs: number;
|
|
60
|
+
status: "success" | "error" | "blocked";
|
|
61
|
+
errorMessage?: string;
|
|
62
|
+
argumentKeys?: string[];
|
|
63
|
+
}): void;
|
|
64
|
+
/** Debug logging */
|
|
65
|
+
log(message: string): void;
|
|
66
|
+
}
|
|
67
|
+
export declare class HttpProxyServer {
|
|
68
|
+
private httpServer;
|
|
69
|
+
private callbacks;
|
|
70
|
+
private port;
|
|
71
|
+
private lastOAuthServerName;
|
|
72
|
+
private upstreamAsEndpoints;
|
|
73
|
+
constructor(port: number, callbacks: HttpProxyCallbacks, preboundServer?: Server);
|
|
74
|
+
private preboundAdopted;
|
|
75
|
+
start(): Promise<void>;
|
|
76
|
+
stop(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the proxy URL for a specific server.
|
|
79
|
+
* Plugins should rewrite their URLs to this endpoint.
|
|
80
|
+
*/
|
|
81
|
+
getProxyUrl(serverName: string): string;
|
|
82
|
+
private handleRequest;
|
|
83
|
+
/**
|
|
84
|
+
* Forward OAuth discovery requests to the upstream server.
|
|
85
|
+
* Rewrites the `resource` field in oauth-protected-resource responses
|
|
86
|
+
* to match the proxy URL so the SDK's validation passes.
|
|
87
|
+
*/
|
|
88
|
+
private forwardOAuthDiscovery;
|
|
89
|
+
/**
|
|
90
|
+
* Forward root-level OAuth requests (/token, /register) to the upstream.
|
|
91
|
+
* Rewrites the `resource` parameter from the proxy URL to the upstream's
|
|
92
|
+
* canonical resource URI (RFC 8707) so the upstream AS accepts the token
|
|
93
|
+
* request bound to the resource it knows about.
|
|
94
|
+
*/
|
|
95
|
+
private forwardRootOAuth;
|
|
96
|
+
/**
|
|
97
|
+
* Build synthetic OAuth authorization server metadata for stdio-bridged servers.
|
|
98
|
+
* Points all OAuth endpoints back to this proxy so the full flow completes locally.
|
|
99
|
+
*/
|
|
100
|
+
private buildStdioAuthServerMetadata;
|
|
101
|
+
/**
|
|
102
|
+
* Handle OAuth endpoints for stdio-bridged servers.
|
|
103
|
+
* Synthesizes valid responses so Claude Code's proactive auth flow succeeds
|
|
104
|
+
* without requiring actual user authentication. The bridge ignores the
|
|
105
|
+
* Authorization header, so the dummy token is harmless.
|
|
106
|
+
*/
|
|
107
|
+
private handleStdioOAuth;
|
|
108
|
+
/**
|
|
109
|
+
* Bridge an HTTP MCP request to a stdio upstream via JSON-RPC.
|
|
110
|
+
*
|
|
111
|
+
* For command-based (stdio) servers that have no HTTP URL, we parse the
|
|
112
|
+
* incoming JSON-RPC request, forward it through the gateway's MCP Client
|
|
113
|
+
* connection, and return the response as HTTP.
|
|
114
|
+
*
|
|
115
|
+
* Handles: initialize, tools/list, tools/call, resources/list, etc.
|
|
116
|
+
* Also synthesizes MCP server metadata for the initial handshake.
|
|
117
|
+
*/
|
|
118
|
+
private bridgeToStdio;
|
|
119
|
+
/**
|
|
120
|
+
* Forward an MCP request to the upstream server.
|
|
121
|
+
* For POST requests, parses the JSON-RPC body to detect tools/call for
|
|
122
|
+
* policy enforcement and telemetry. All other requests pass through as-is.
|
|
123
|
+
*/
|
|
124
|
+
private forwardMcpRequest;
|
|
125
|
+
}
|
|
126
|
+
//# 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;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAEjG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA0B9F;AAED,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,+EAA+E;IAC/E,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9C;;;OAGG;IACH,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,GACf,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC5F,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,oBAAoB;IACpB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,IAAI,CAAS;IAMrB,OAAO,CAAC,mBAAmB,CAAqB;IAIhD,OAAO,CAAC,mBAAmB,CAOtB;gBAEO,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,cAAc,CAAC,EAAE,MAAM;IAahF,OAAO,CAAC,eAAe,CAAS;IAE1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;YAIzB,aAAa;IAqJ3B;;;;OAIG;YACW,qBAAqB;IA2HnC;;;;;OAKG;YACW,gBAAgB;IA2E9B;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAcpC;;;;;OAKG;YACW,gBAAgB;IA8F9B;;;;;;;;;OASG;YACW,aAAa;IA2I3B;;;;OAIG;YACW,iBAAiB;CAkMhC"}
|