mcp-proxy 5.8.1 → 5.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Client, InMemoryEventStore, ReadBuffer, Server, __commonJS, __toESM, proxyServer, serializeMessage, startHTTPServer } from "../stdio-9KZaSDCW.js";
2
+ import { Client, InMemoryEventStore, ReadBuffer, Server, __commonJS, __toESM, proxyServer, serializeMessage, startHTTPServer } from "../stdio-CsjPjeWC.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
5
5
  import { format, inspect } from "util";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import http from "http";
1
+ import http, { IncomingMessage } from "http";
2
2
  import { EventStore } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
3
  import { JSONRPCMessage, ServerCapabilities } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
@@ -7,8 +7,26 @@ import { SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.
7
7
  import { StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
8
8
  import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
9
9
 
10
+ //#region src/authentication.d.ts
11
+ interface AuthConfig {
12
+ apiKey?: string;
13
+ oauth?: {
14
+ protectedResource?: {
15
+ resource?: string;
16
+ };
17
+ };
18
+ }
19
+ declare class AuthenticationMiddleware {
20
+ private config;
21
+ constructor(config?: AuthConfig);
22
+ getUnauthorizedResponse(): {
23
+ body: string;
24
+ headers: Record<string, string>;
25
+ };
26
+ validateRequest(req: IncomingMessage): boolean;
27
+ }
28
+ //#endregion
10
29
  //#region src/InMemoryEventStore.d.ts
11
-
12
30
  /**
13
31
  * Simple in-memory implementation of the EventStore interface for resumability
14
32
  * This is primarily intended for examples and testing, not for production use
@@ -68,6 +86,7 @@ declare const startHTTPServer: <T extends ServerLike>({
68
86
  enableJsonResponse,
69
87
  eventStore,
70
88
  host,
89
+ oauth,
71
90
  onClose,
72
91
  onConnect,
73
92
  onUnhandledRequest,
@@ -82,6 +101,7 @@ declare const startHTTPServer: <T extends ServerLike>({
82
101
  enableJsonResponse?: boolean;
83
102
  eventStore?: EventStore;
84
103
  host?: string;
104
+ oauth?: AuthConfig["oauth"];
85
105
  onClose?: (server: T) => Promise<void>;
86
106
  onConnect?: (server: T) => Promise<void>;
87
107
  onUnhandledRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
@@ -129,5 +149,5 @@ type TransportEvent = {
129
149
  };
130
150
  declare const tapTransport: (transport: Transport, eventHandler: (event: TransportEvent) => void) => Transport;
131
151
  //#endregion
132
- export { InMemoryEventStore, ServerType, proxyServer, startHTTPServer, startStdioServer, tapTransport };
152
+ export { type AuthConfig, AuthenticationMiddleware, InMemoryEventStore, ServerType, proxyServer, startHTTPServer, startStdioServer, tapTransport };
133
153
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Client, InMemoryEventStore, JSONRPCMessageSchema, LATEST_PROTOCOL_VERSION, NEVER, ReadBuffer, Server, ZodIssueCode, anyType, arrayType, booleanType, isInitializedNotification, isJSONRPCRequest, isJSONRPCResponse, numberType, objectType, proxyServer, serializeMessage, startHTTPServer, stringType } from "./stdio-9KZaSDCW.js";
1
+ import { AuthenticationMiddleware, Client, InMemoryEventStore, JSONRPCMessageSchema, LATEST_PROTOCOL_VERSION, NEVER, ReadBuffer, Server, ZodIssueCode, anyType, arrayType, booleanType, isInitializedNotification, isJSONRPCRequest, isJSONRPCResponse, numberType, objectType, proxyServer, serializeMessage, startHTTPServer, stringType } from "./stdio-CsjPjeWC.js";
2
2
  import process from "node:process";
3
3
 
4
4
  //#region node_modules/.pnpm/eventsource-parser@3.0.6/node_modules/eventsource-parser/dist/index.js
@@ -1850,5 +1850,5 @@ const tapTransport = (transport, eventHandler) => {
1850
1850
  };
1851
1851
 
1852
1852
  //#endregion
1853
- export { InMemoryEventStore, ServerType, proxyServer, startHTTPServer, startStdioServer, tapTransport };
1853
+ export { AuthenticationMiddleware, InMemoryEventStore, ServerType, proxyServer, startHTTPServer, startStdioServer, tapTransport };
1854
1854
  //# sourceMappingURL=index.js.map
@@ -29,6 +29,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  }) : target, mod));
30
30
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
31
31
 
32
+ //#endregion
33
+ //#region src/authentication.ts
34
+ var AuthenticationMiddleware = class {
35
+ constructor(config = {}) {
36
+ this.config = config;
37
+ }
38
+ getUnauthorizedResponse() {
39
+ const headers = { "Content-Type": "application/json" };
40
+ if (this.config.oauth?.protectedResource?.resource) headers["WWW-Authenticate"] = `Bearer resource_metadata="${this.config.oauth.protectedResource.resource}/.well-known/oauth-protected-resource"`;
41
+ return {
42
+ body: JSON.stringify({
43
+ error: {
44
+ code: 401,
45
+ message: "Unauthorized: Invalid or missing API key"
46
+ },
47
+ id: null,
48
+ jsonrpc: "2.0"
49
+ }),
50
+ headers
51
+ };
52
+ }
53
+ validateRequest(req) {
54
+ if (!this.config.apiKey) return true;
55
+ const apiKey = req.headers["x-api-key"];
56
+ if (!apiKey || typeof apiKey !== "string") return false;
57
+ return apiKey === this.config.apiKey;
58
+ }
59
+ };
60
+
32
61
  //#endregion
33
62
  //#region src/InMemoryEventStore.ts
34
63
  /**
@@ -14968,33 +14997,6 @@ var StreamableHTTPServerTransport = class {
14968
14997
  }
14969
14998
  };
14970
14999
 
14971
- //#endregion
14972
- //#region src/authentication.ts
14973
- var AuthenticationMiddleware = class {
14974
- constructor(config = {}) {
14975
- this.config = config;
14976
- }
14977
- getUnauthorizedResponse() {
14978
- return {
14979
- body: JSON.stringify({
14980
- error: {
14981
- code: 401,
14982
- message: "Unauthorized: Invalid or missing API key"
14983
- },
14984
- id: null,
14985
- jsonrpc: "2.0"
14986
- }),
14987
- headers: { "Content-Type": "application/json" }
14988
- };
14989
- }
14990
- validateRequest(req) {
14991
- if (!this.config.apiKey) return true;
14992
- const apiKey = req.headers["x-api-key"];
14993
- if (!apiKey || typeof apiKey !== "string") return false;
14994
- return apiKey === this.config.apiKey;
14995
- }
14996
- };
14997
-
14998
15000
  //#endregion
14999
15001
  //#region src/startHTTPServer.ts
15000
15002
  const getBody = (request) => {
@@ -15024,6 +15026,10 @@ const createJsonRpcErrorResponse = (code, message) => {
15024
15026
  jsonrpc: "2.0"
15025
15027
  });
15026
15028
  };
15029
+ const getWWWAuthenticateHeader = (oauth) => {
15030
+ if (!oauth?.protectedResource?.resource) return;
15031
+ return `Bearer resource_metadata="${oauth.protectedResource.resource}/.well-known/oauth-protected-resource"`;
15032
+ };
15027
15033
  const handleResponseError = (error, res) => {
15028
15034
  if (error instanceof Response) {
15029
15035
  const fixedHeaders = {};
@@ -15045,7 +15051,7 @@ const cleanupServer = async (server, onClose) => {
15045
15051
  console.error("[mcp-proxy] error closing server", error);
15046
15052
  }
15047
15053
  };
15048
- const handleStreamRequest = async ({ activeTransports, authenticate, createServer, enableJsonResponse, endpoint, eventStore, onClose, onConnect, req, res, stateless }) => {
15054
+ const handleStreamRequest = async ({ activeTransports, authenticate, createServer, enableJsonResponse, endpoint, eventStore, oauth, onClose, onConnect, req, res, stateless }) => {
15049
15055
  if (req.method === "POST" && new URL(req.url, "http://localhost").pathname === endpoint) {
15050
15056
  try {
15051
15057
  const sessionId = Array.isArray(req.headers["mcp-session-id"]) ? req.headers["mcp-session-id"][0] : req.headers["mcp-session-id"];
@@ -15057,6 +15063,8 @@ const handleStreamRequest = async ({ activeTransports, authenticate, createServe
15057
15063
  if (!authResult || typeof authResult === "object" && "authenticated" in authResult && !authResult.authenticated) {
15058
15064
  const errorMessage = authResult && typeof authResult === "object" && "error" in authResult && typeof authResult.error === "string" ? authResult.error : "Unauthorized: Authentication failed";
15059
15065
  res.setHeader("Content-Type", "application/json");
15066
+ const wwwAuthHeader = getWWWAuthenticateHeader(oauth);
15067
+ if (wwwAuthHeader) res.setHeader("WWW-Authenticate", wwwAuthHeader);
15060
15068
  res.writeHead(401).end(JSON.stringify({
15061
15069
  error: {
15062
15070
  code: -32e3,
@@ -15071,6 +15079,8 @@ const handleStreamRequest = async ({ activeTransports, authenticate, createServe
15071
15079
  const errorMessage = error instanceof Error ? error.message : "Unauthorized: Authentication error";
15072
15080
  console.error("Authentication error:", error);
15073
15081
  res.setHeader("Content-Type", "application/json");
15082
+ const wwwAuthHeader = getWWWAuthenticateHeader(oauth);
15083
+ if (wwwAuthHeader) res.setHeader("WWW-Authenticate", wwwAuthHeader);
15074
15084
  res.writeHead(401).end(JSON.stringify({
15075
15085
  error: {
15076
15086
  code: -32e3,
@@ -15118,6 +15128,8 @@ const handleStreamRequest = async ({ activeTransports, authenticate, createServe
15118
15128
  const errorMessage = error instanceof Error ? error.message : String(error);
15119
15129
  if (errorMessage.includes("Authentication") || errorMessage.includes("Invalid JWT") || errorMessage.includes("Token") || errorMessage.includes("Unauthorized")) {
15120
15130
  res.setHeader("Content-Type", "application/json");
15131
+ const wwwAuthHeader = getWWWAuthenticateHeader(oauth);
15132
+ if (wwwAuthHeader) res.setHeader("WWW-Authenticate", wwwAuthHeader);
15121
15133
  res.writeHead(401).end(JSON.stringify({
15122
15134
  error: {
15123
15135
  code: -32e3,
@@ -15149,6 +15161,8 @@ const handleStreamRequest = async ({ activeTransports, authenticate, createServe
15149
15161
  const errorMessage = error instanceof Error ? error.message : String(error);
15150
15162
  if (errorMessage.includes("Authentication") || errorMessage.includes("Invalid JWT") || errorMessage.includes("Token") || errorMessage.includes("Unauthorized")) {
15151
15163
  res.setHeader("Content-Type", "application/json");
15164
+ const wwwAuthHeader = getWWWAuthenticateHeader(oauth);
15165
+ if (wwwAuthHeader) res.setHeader("WWW-Authenticate", wwwAuthHeader);
15152
15166
  res.writeHead(401).end(JSON.stringify({
15153
15167
  error: {
15154
15168
  code: -32e3,
@@ -15275,10 +15289,13 @@ const handleSSERequest = async ({ activeTransports, createServer, endpoint, onCl
15275
15289
  }
15276
15290
  return false;
15277
15291
  };
15278
- const startHTTPServer = async ({ apiKey, authenticate, createServer, enableJsonResponse, eventStore, host = "::", onClose, onConnect, onUnhandledRequest, port, sseEndpoint = "/sse", stateless, streamEndpoint = "/mcp" }) => {
15292
+ const startHTTPServer = async ({ apiKey, authenticate, createServer, enableJsonResponse, eventStore, host = "::", oauth, onClose, onConnect, onUnhandledRequest, port, sseEndpoint = "/sse", stateless, streamEndpoint = "/mcp" }) => {
15279
15293
  const activeSSETransports = {};
15280
15294
  const activeStreamTransports = {};
15281
- const authMiddleware = new AuthenticationMiddleware({ apiKey });
15295
+ const authMiddleware = new AuthenticationMiddleware({
15296
+ apiKey,
15297
+ oauth
15298
+ });
15282
15299
  /**
15283
15300
  * @author https://dev.classmethod.jp/articles/mcp-sse/
15284
15301
  */
@@ -15324,6 +15341,7 @@ const startHTTPServer = async ({ apiKey, authenticate, createServer, enableJsonR
15324
15341
  enableJsonResponse,
15325
15342
  endpoint: streamEndpoint,
15326
15343
  eventStore,
15344
+ oauth,
15327
15345
  onClose,
15328
15346
  onConnect,
15329
15347
  req,
@@ -21538,5 +21556,5 @@ function serializeMessage(message) {
21538
21556
  }
21539
21557
 
21540
21558
  //#endregion
21541
- export { Client, InMemoryEventStore, JSONRPCMessageSchema, LATEST_PROTOCOL_VERSION, NEVER, ReadBuffer, Server, ZodIssueCode, __commonJS, __toESM, anyType, arrayType, booleanType, isInitializedNotification, isJSONRPCRequest, isJSONRPCResponse, numberType, objectType, proxyServer, serializeMessage, startHTTPServer, stringType };
21542
- //# sourceMappingURL=stdio-9KZaSDCW.js.map
21559
+ export { AuthenticationMiddleware, Client, InMemoryEventStore, JSONRPCMessageSchema, LATEST_PROTOCOL_VERSION, NEVER, ReadBuffer, Server, ZodIssueCode, __commonJS, __toESM, anyType, arrayType, booleanType, isInitializedNotification, isJSONRPCRequest, isJSONRPCResponse, numberType, objectType, proxyServer, serializeMessage, startHTTPServer, stringType };
21560
+ //# sourceMappingURL=stdio-CsjPjeWC.js.map