sunpeak 0.18.12 → 0.18.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.
@@ -44,6 +44,7 @@ export async function start(projectRoot = process.cwd(), args = []) {
44
44
  }
45
45
 
46
46
  const jsonLogs = args.includes('--json-logs');
47
+ const sse = args.includes('--sse');
47
48
 
48
49
  // Import production server from sunpeak
49
50
  const isTemplate = projectRoot.endsWith('/template') || projectRoot.endsWith('\\template');
@@ -191,7 +192,7 @@ export async function start(projectRoot = process.cwd(), args = []) {
191
192
  console.log(`\nStarting ${name} v${version} on ${host}:${port}...`);
192
193
 
193
194
  startProductionHttpServer(
194
- { name, version, serverInfo: serverConfig, tools, resources, auth },
195
+ { name, version, serverInfo: serverConfig, tools, resources, auth, ...(sse ? { enableJsonResponse: false } : {}) },
195
196
  { port, host }
196
197
  );
197
198
  }
@@ -7570,7 +7570,7 @@ var toRequestError = (e) => {
7570
7570
  return new RequestError(e.message, { cause: e });
7571
7571
  };
7572
7572
  var GlobalRequest = global.Request;
7573
- var Request = class extends GlobalRequest {
7573
+ var Request$1 = class extends GlobalRequest {
7574
7574
  constructor(input, options) {
7575
7575
  if (typeof input === "object" && getRequestCache in input) input = input[getRequestCache]();
7576
7576
  if (typeof options?.body?.getReader !== "undefined") options.duplex ??= "half";
@@ -7595,7 +7595,7 @@ var newRequestFromIncoming = (method, url, headers, incoming, abortController) =
7595
7595
  };
7596
7596
  if (method === "TRACE") {
7597
7597
  init.method = "GET";
7598
- const req = new Request(url, init);
7598
+ const req = new Request$1(url, init);
7599
7599
  Object.defineProperty(req, "method", { get() {
7600
7600
  return "TRACE";
7601
7601
  } });
@@ -7618,7 +7618,7 @@ var newRequestFromIncoming = (method, url, headers, incoming, abortController) =
7618
7618
  }
7619
7619
  } });
7620
7620
  } else init.body = stream.Readable.toWeb(incoming);
7621
- return new Request(url, init);
7621
+ return new Request$1(url, init);
7622
7622
  };
7623
7623
  var getRequestCache = Symbol("getRequestCache");
7624
7624
  var requestCache = Symbol("requestCache");
@@ -7675,7 +7675,7 @@ var requestPrototype = {
7675
7675
  return this[getRequestCache]()[k]();
7676
7676
  } });
7677
7677
  });
7678
- Object.setPrototypeOf(requestPrototype, Request.prototype);
7678
+ Object.setPrototypeOf(requestPrototype, Request$1.prototype);
7679
7679
  var newRequest = (incoming, defaultHostname) => {
7680
7680
  const req = Object.create(requestPrototype);
7681
7681
  req[incomingKey] = incoming;
@@ -7926,8 +7926,8 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
7926
7926
  };
7927
7927
  var getRequestListener = (fetchCallback, options = {}) => {
7928
7928
  const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
7929
- if (options.overrideGlobalObjects !== false && global.Request !== Request) {
7930
- Object.defineProperty(global, "Request", { value: Request });
7929
+ if (options.overrideGlobalObjects !== false && global.Request !== Request$1) {
7930
+ Object.defineProperty(global, "Request", { value: Request$1 });
7931
7931
  Object.defineProperty(global, "Response", { value: Response2 });
7932
7932
  }
7933
7933
  return async (incoming, outgoing) => {
@@ -9870,6 +9870,39 @@ var CORS_HEADERS = {
9870
9870
  "Access-Control-Allow-Headers": "content-type, accept, authorization, mcp-session-id, ngrok-skip-browser-warning",
9871
9871
  "Access-Control-Expose-Headers": "mcp-session-id"
9872
9872
  };
9873
+ /** Convert a Node.js IncomingMessage to a minimal Web Standard Request (body is passed separately). */
9874
+ function nodeReqToWebRequest(req) {
9875
+ const url = new node_url.URL(req.url, `http://${req.headers.host ?? "localhost"}`);
9876
+ const headers = new Headers();
9877
+ for (const [key, value] of Object.entries(req.headers)) if (value != null) headers.set(key, Array.isArray(value) ? value.join(", ") : value);
9878
+ return new Request(url.toString(), {
9879
+ method: req.method,
9880
+ headers
9881
+ });
9882
+ }
9883
+ /** Pipe a Web Standard Response (including streaming SSE) back to a Node.js ServerResponse. */
9884
+ async function pipeWebResponseToNode(webResponse, res) {
9885
+ const headers = {};
9886
+ webResponse.headers.forEach((value, key) => {
9887
+ headers[key] = value;
9888
+ });
9889
+ res.writeHead(webResponse.status, headers);
9890
+ if (!webResponse.body) {
9891
+ res.end();
9892
+ return;
9893
+ }
9894
+ const reader = webResponse.body.getReader();
9895
+ res.on("close", () => reader.cancel());
9896
+ try {
9897
+ for (;;) {
9898
+ const { done, value } = await reader.read();
9899
+ if (done) break;
9900
+ if (!res.destroyed) res.write(value);
9901
+ }
9902
+ } finally {
9903
+ if (!res.destroyed) res.end();
9904
+ }
9905
+ }
9873
9906
  /**
9874
9907
  * Create a request handler that manages MCP sessions over Streamable HTTP.
9875
9908
  *
@@ -9921,15 +9954,18 @@ function createMcpHandler(config) {
9921
9954
  res.end();
9922
9955
  return;
9923
9956
  }
9924
- for (const [key, value] of Object.entries(CORS_HEADERS)) res.setHeader(key, value);
9957
+ let authInfo;
9925
9958
  if (authFn) {
9926
- const authInfo = await authFn(req);
9927
- if (!authInfo) {
9928
- res.writeHead(401, { "WWW-Authenticate": "Bearer" });
9959
+ const result = await authFn(req);
9960
+ if (!result) {
9961
+ res.writeHead(401, {
9962
+ ...CORS_HEADERS,
9963
+ "WWW-Authenticate": "Bearer"
9964
+ });
9929
9965
  res.end("Unauthorized");
9930
9966
  return;
9931
9967
  }
9932
- req.auth = authInfo;
9968
+ authInfo = result;
9933
9969
  }
9934
9970
  let parsedBody;
9935
9971
  if (req.method === "POST") {
@@ -9955,6 +9991,7 @@ function createMcpHandler(config) {
9955
9991
  return;
9956
9992
  }
9957
9993
  }
9994
+ const webRequest = nodeReqToWebRequest(req);
9958
9995
  const sessionId = req.headers["mcp-session-id"];
9959
9996
  if (sessionId) {
9960
9997
  const session = sessions.get(sessionId);
@@ -9963,13 +10000,17 @@ function createMcpHandler(config) {
9963
10000
  return;
9964
10001
  }
9965
10002
  session.lastActivity = Date.now();
9966
- await session.transport.handleRequest(req, res, parsedBody);
10003
+ await pipeWebResponseToNode(addCorsHeaders(await session.transport.handleRequest(webRequest, {
10004
+ parsedBody,
10005
+ authInfo
10006
+ })), res);
9967
10007
  return;
9968
10008
  }
9969
10009
  if (req.method === "POST") {
9970
10010
  const server = createProductionMcpServer(config);
9971
- const transport = new StreamableHTTPServerTransport({
10011
+ const transport = new WebStandardStreamableHTTPServerTransport({
9972
10012
  sessionIdGenerator: () => (0, node_crypto.randomUUID)(),
10013
+ enableJsonResponse: config.enableJsonResponse ?? true,
9973
10014
  onsessioninitialized: (id) => {
9974
10015
  sessions.set(id, {
9975
10016
  server,
@@ -10007,7 +10048,10 @@ function createMcpHandler(config) {
10007
10048
  }
10008
10049
  };
10009
10050
  await server.connect(transport);
10010
- await transport.handleRequest(req, res, parsedBody);
10051
+ await pipeWebResponseToNode(addCorsHeaders(await transport.handleRequest(webRequest, {
10052
+ parsedBody,
10053
+ authInfo
10054
+ })), res);
10011
10055
  return;
10012
10056
  }
10013
10057
  res.writeHead(400).end("Bad Request: session ID required");
@@ -10101,6 +10145,7 @@ function createHandler(config) {
10101
10145
  });
10102
10146
  const transport = new WebStandardStreamableHTTPServerTransport({
10103
10147
  sessionIdGenerator: () => (0, node_crypto.randomUUID)(),
10148
+ enableJsonResponse: config.enableJsonResponse ?? true,
10104
10149
  onsessioninitialized: (id) => {
10105
10150
  sessions.set(id, {
10106
10151
  server,
@@ -10139,8 +10184,7 @@ function createHandler(config) {
10139
10184
  /** Add CORS headers to a response (including streaming SSE responses). */
10140
10185
  function addCorsHeaders(response) {
10141
10186
  const headers = new Headers(response.headers);
10142
- headers.set("Access-Control-Allow-Origin", "*");
10143
- headers.set("Access-Control-Expose-Headers", "mcp-session-id");
10187
+ for (const [key, value] of Object.entries(CORS_HEADERS)) headers.set(key, value);
10144
10188
  return new Response(response.body, {
10145
10189
  status: response.status,
10146
10190
  statusText: response.statusText,