




















@@ -156,7 +156,7 @@ export function validateMcpLoopbackRequest(params: {
156156return null;
157157}
158158159-if (params.req.method === "GET") {
159+if (params.req.method === "GET" || params.req.method === "DELETE") {
160160// Origin validation first (matches the POST path): a browser loopback request is
161161// rejected before bearer auth, so the local-loopback Origin boundary holds even for
162162// unauthenticated browser requests.
@@ -171,39 +171,27 @@ export function validateMcpLoopbackRequest(params: {
171171params.res.end(JSON.stringify({ error: "unauthorized" }));
172172return null;
173173}
174-logMcpLoopbackHttp("sse-open", { method: "GET", path: url.pathname });
175-params.res.writeHead(200, {
176-"Content-Type": "text/event-stream",
177-"Cache-Control": "no-cache",
178-Connection: "keep-alive",
179-});
180-params.res.flushHeaders();
181-params.res.write(":\n\n");
182-params.onSseResponse?.(params.res);
183-params.req.on("close", () => {
184-if (!params.res.writableEnded) {
185-params.res.end();
186-}
187-});
188-return null;
189-}
174+if (params.req.method === "GET") {
175+logMcpLoopbackHttp("sse-open", { method: "GET", path: url.pathname });
176+params.res.writeHead(200, {
177+"Content-Type": "text/event-stream",
178+"Cache-Control": "no-cache",
179+Connection: "keep-alive",
180+});
181+params.res.flushHeaders();
182+params.res.write(":\n\n");
183+params.onSseResponse?.(params.res);
184+params.req.on("close", () => {
185+if (!params.res.writableEnded) {
186+params.res.end();
187+}
188+});
189+return null;
190+}
190191191-if (params.req.method === "DELETE") {
192192// Streamable HTTP session teardown. The loopback server is stateless — it owns no
193193// session lifecycle — so this is an auth-gated no-op acknowledgement: clients that
194194// send DELETE when closing the transport get a clean 200 rather than a 405.
195-// Origin validation first (matches the POST/GET paths), before bearer auth.
196-if (rejectsBrowserLoopbackRequest(params.req)) {
197-params.res.writeHead(403, { "Content-Type": "application/json" });
198-params.res.end(JSON.stringify({ error: "forbidden" }));
199-return null;
200-}
201-const sender = resolveMcpSender(params);
202-if (!sender) {
203-params.res.writeHead(401, { "Content-Type": "application/json" });
204-params.res.end(JSON.stringify({ error: "unauthorized" }));
205-return null;
206-}
207195logMcpLoopbackHttp("session-delete", { method: "DELETE", path: url.pathname });
208196params.res.writeHead(200, { "Content-Type": "application/json" });
209197params.res.end(JSON.stringify({ ok: true }));
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。