Skip to content

add support for Streamable HTTP server #294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 19, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ const App = () => {
const [sseUrl, setSseUrl] = useState<string>(() => {
return localStorage.getItem("lastSseUrl") || "http://localhost:3001/sse";
});
const [transportType, setTransportType] = useState<"stdio" | "sse">(() => {
const [transportType, setTransportType] = useState<
"stdio" | "sse" | "streamable-http"
>(() => {
return (
(localStorage.getItem("lastTransportType") as "stdio" | "sse") || "stdio"
(localStorage.getItem("lastTransportType") as
| "stdio"
| "sse"
| "streamable-http") || "stdio"
);
});
const [logLevel, setLogLevel] = useState<LoggingLevel>("debug");
Expand Down
7 changes: 4 additions & 3 deletions client/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import {

interface SidebarProps {
connectionStatus: ConnectionStatus;
transportType: "stdio" | "sse";
setTransportType: (type: "stdio" | "sse") => void;
transportType: "stdio" | "sse" | "streamable-http";
setTransportType: (type: "stdio" | "sse" | "streamable-http") => void;
command: string;
setCommand: (command: string) => void;
args: string;
Expand Down Expand Up @@ -117,7 +117,7 @@ const Sidebar = ({
</label>
<Select
value={transportType}
onValueChange={(value: "stdio" | "sse") =>
onValueChange={(value: "stdio" | "sse" | "streamable-http") =>
setTransportType(value)
}
>
Expand All @@ -127,6 +127,7 @@ const Sidebar = ({
<SelectContent>
<SelectItem value="stdio">STDIO</SelectItem>
<SelectItem value="sse">SSE</SelectItem>
<SelectItem value="streamable-http">Streamable HTTP</SelectItem>
</SelectContent>
</Select>
</div>
Expand Down
2 changes: 1 addition & 1 deletion client/src/lib/hooks/useConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { getMCPServerRequestTimeout } from "@/utils/configUtils";
import { InspectorConfig } from "../configurationTypes";

interface UseConnectionOptions {
transportType: "stdio" | "sse";
transportType: "stdio" | "sse" | "streamable-http";
command: string;
args: string;
sseUrl: string;
Expand Down
8 changes: 8 additions & 0 deletions server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from "@modelcontextprotocol/sdk/client/stdio.js";
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import express from "express";
import { findActualExecutable } from "spawn-rx";
import mcpProxy from "./mcpProxy.js";
Expand Down Expand Up @@ -94,6 +95,13 @@ const createTransport = async (req: express.Request): Promise<Transport> => {

console.log("Connected to SSE transport");
return transport;
} else if (transportType === "streamable-http") {
const transport = new StreamableHTTPClientTransport(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To Auth feature works you should send headers to the server

Suggested change
const transport = new StreamableHTTPClientTransport(
const STREAMABLE_HTTP_HEADERS_PASSTHROUGH = ["authorization"];
const headers: HeadersInit = {};
for (const key of STREAMABLE_HTTP_HEADERS_PASSTHROUGH) {
if (req.headers[key] === undefined) {
continue;
}
const value = req.headers[key];
headers[key] = Array.isArray(value) ? value[value.length - 1] : value;
}
const transport = new StreamableHTTPClientTransport(

Copy link
Contributor Author

@shivdeepak shivdeepak Apr 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I have added the recommended changes and tested them. They work well.

MCP Inspector
Screenshot 2025-04-17 at 9 28 21 PM

Req/Resp Headers
Screenshot 2025-04-17 at 9 27 49 PM
Screenshot 2025-04-17 at 9 28 02 PM

new URL(query.url as string),
);
await transport.start();
console.log("Connected to Streamable HTTP transport");
return transport;
} else {
console.error(`Invalid transport type: ${transportType}`);
throw new Error("Invalid transport type specified");
Expand Down