Merge pull request #470 from cliffhall/send-delete-on-streamable-http-disconnect

Send HTTP DELETE on streamable transport disconnect
This commit is contained in:
Cliff Hall 2025-06-02 10:05:30 -04:00 • committed by GitHub
commit 7df0ac40c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 9 deletions

View file

@ -45,6 +45,7 @@ import {
} from "@/utils/configUtils"; } from "@/utils/configUtils";
import { getMCPServerRequestTimeout } from "@/utils/configUtils"; import { getMCPServerRequestTimeout } from "@/utils/configUtils";
import { InspectorConfig } from "../configurationTypes"; import { InspectorConfig } from "../configurationTypes";
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
interface UseConnectionOptions { interface UseConnectionOptions {
transportType: "stdio" | "sse" | "streamable-http"; transportType: "stdio" | "sse" | "streamable-http";
@ -83,6 +84,9 @@ export function useConnection({
const [serverCapabilities, setServerCapabilities] = const [serverCapabilities, setServerCapabilities] =
useState<ServerCapabilities | null>(null); useState<ServerCapabilities | null>(null);
const [mcpClient, setMcpClient] = useState<Client | null>(null); const [mcpClient, setMcpClient] = useState<Client | null>(null);
const [clientTransport, setClientTransport] = useState<Transport | null>(
null,
);
const [requestHistory, setRequestHistory] = useState< const [requestHistory, setRequestHistory] = useState<
{ request: string; response?: string }[] { request: string; response?: string }[]
>([]); >([]);
@ -384,14 +388,6 @@ export function useConnection({
transportType, transportType,
); );
const clientTransport =
transportType === "streamable-http"
? new StreamableHTTPClientTransport(mcpProxyServerUrl as URL, {
sessionId: undefined,
...transportOptions,
})
: new SSEClientTransport(mcpProxyServerUrl as URL, transportOptions);
if (onNotification) { if (onNotification) {
[ [
CancelledNotificationSchema, CancelledNotificationSchema,
@ -421,7 +417,20 @@ export function useConnection({
let capabilities; let capabilities;
try { try {
await client.connect(clientTransport); const transport =
transportType === "streamable-http"
? new StreamableHTTPClientTransport(mcpProxyServerUrl as URL, {
sessionId: undefined,
...transportOptions,
})
: new SSEClientTransport(
mcpProxyServerUrl as URL,
transportOptions,
);
await client.connect(transport as Transport);
setClientTransport(transport);
capabilities = client.getServerCapabilities(); capabilities = client.getServerCapabilities();
const initializeRequest = { const initializeRequest = {
@ -475,10 +484,15 @@ export function useConnection({
}; };
const disconnect = async () => { const disconnect = async () => {
if (transportType === "streamable-http")
await (
clientTransport as StreamableHTTPClientTransport
).terminateSession();
await mcpClient?.close(); await mcpClient?.close();
const authProvider = new InspectorOAuthClientProvider(sseUrl); const authProvider = new InspectorOAuthClientProvider(sseUrl);
authProvider.clear(); authProvider.clear();
setMcpClient(null); setMcpClient(null);
setClientTransport(null);
setConnectionStatus("disconnected"); setConnectionStatus("disconnected");
setCompletionsSupported(false); setCompletionsSupported(false);
setServerCapabilities(null); setServerCapabilities(null);

View file

@ -243,6 +243,33 @@ app.post("/mcp", async (req, res) => {
} }
}); });
app.delete("/mcp", async (req, res) => {
const sessionId = req.headers["mcp-session-id"] as string | undefined;
console.log(`Received DELETE message for sessionId ${sessionId}`);
let serverTransport: Transport | undefined;
if (sessionId) {
try {
serverTransport = serverTransports.get(
sessionId,
) as StreamableHTTPClientTransport;
if (!serverTransport) {
res.status(404).end("Transport not found for sessionId " + sessionId);
} else {
await (
serverTransport as StreamableHTTPClientTransport
).terminateSession();
webAppTransports.delete(sessionId);
serverTransports.delete(sessionId);
console.log(`Transports removed for sessionId ${sessionId}`);
}
res.status(200).end();
} catch (error) {
console.error("Error in /mcp route:", error);
res.status(500).json(error);
}
}
});
app.get("/stdio", async (req, res) => { app.get("/stdio", async (req, res) => {
try { try {
console.log("New connection"); console.log("New connection");