Skip to content

Streamable http support #32

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 2 commits into from
Apr 30, 2025
Merged

Streamable http support #32

merged 2 commits into from
Apr 30, 2025

Conversation

geelen
Copy link
Owner

@geelen geelen commented Apr 17, 2025

Update: this is testable! Use mcp-remote@next in your config and it should pull v0.1.0-0. I'll continue publishing prereleases on the next tag to get some real world feedback until it's ready.

This depends on the changes in modelcontextprotocol/typescript-sdk#351 which aren't released yet, so marking this as draft for now. It's also extremely under-tested, since there's now a lot of combinations of servers/transports/auth schemes

The new API all comes under the --transport CLI flag, which has 4 values: http-first (the default), sse-first, http-only and sse-only. For -first flags, we try one type of transport then fall back to the other. That's done by looking for a 405 for sse-first and a 404 for http-first, then trying the other. It's not exactly airtight but it appears to work for the first few things i've tested.

image

image

The tricky thing is combining this with auth, of course, where a transport can fail either because it's unauthed or it's using the wrong transport. Claude has done its best with some guidance from me, and I'd almost believe it was done if I had a good test setup to verify. Will work on that next.

@geelen
Copy link
Owner Author

geelen commented Apr 24, 2025

Fixed a bug, defaulting now to the SSE transport, able to mount the same server using both SSE and HTTP:

{
  "mcpServers": {
    "streamable-no-auth": {
      "command": "node",
      "args": [
        "mcp-remote@next",
        "http://localhost:8788/mcp"
      ]
    },
    "sse-fallback": {
      "command": "npx",
      "args": [
        "mcp-remote@next",
        "http://localhost:8788/sse"
      ]
    }
  }
}

That pairs with the updates here to make it easy to serve both: geelen/mcp-remote-examples#17

export default new OAuthProvider({
  apiHandlers: {
    '/sse': MyMCP.serveSSE('/sse'),
    '/mcp': MyMCP.serve('/mcp'),
  },
  defaultHandler: GitHubHandler,
  authorizeEndpoint: '/authorize',
  tokenEndpoint: '/token',
  clientRegistrationEndpoint: '/register',
})

This is feeling a lot better now, I think it's likely ready to release on Monday but I'd still love to put in some more tests.

@liriID
Copy link

liriID commented Apr 29, 2025

note the SSE fallback doesn't work well with this example where the endpoint does support GET http method:

https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#streamable-http

because we expect to get 405 in case of trying SSE on a server working with streamable http

@zxkane
Copy link

zxkane commented Apr 30, 2025

Tested on proxying this streamable HTTP-only server, works really well!

@geelen
Copy link
Owner Author

geelen commented Apr 30, 2025

note the SSE fallback doesn't work well with this example where the endpoint does support GET http method:

https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#streamable-http

because we expect to get 405 in case of trying SSE on a server working with streamable http

Ugh of course, that's annoying. You'll have to use --transport http-first then.

I actually wanted to default to the new transport anyway but the .start method doesn't do anything, so there's nothing to trigger the fallback logic. But if the SSE GET doesn't reliably trigger a 405 then... 🤔

Maybe instead of expecting the transport to explode with a known error, I just fire a separate POST to figure out what kind of server it is? That might... be way better, damn.

@geelen geelen marked this pull request as ready for review April 30, 2025 11:43
geelen added 2 commits April 30, 2025 21:57
This adds a new CLI argument, --transport, with the following values: http-first (the default), http-only, sse-first, and sse-only. Any of the -first tags attempts to connect to the URL as either an HTTP or SSE server and falls back to the other.
@geelen geelen merged commit 5a38b58 into main Apr 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants