Skip to content

Conversation

@mattzcarey
Copy link
Contributor

Use-case is to make a persistent server for a whole team to use. This server should maintain state across multiple interactions. Hence the routing needs to work explicitly.

I can't seem to make sse work. There is an arbitrary limit on the number of clients connected to a single server of 1 which doesnt seem to be present in the MCP spec. This confused me and would love some guidance from those who understand it better.

@changeset-bot
Copy link

changeset-bot bot commented May 6, 2025

⚠️ No Changeset found

Latest commit: de2ae3c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cmsparks
Copy link
Contributor

cmsparks commented May 7, 2025

I suspect you're running into this issue where you have multiple clients on the same session: #172

The issue is that one DO instance is intended to manage a single session+transport IIRC. But as you mentioned, maybe that's not spec-compliant, but not certain

Use-case is to make a persistent server for a whole team to use. This server should maintain state across multiple interactions. Hence the routing needs to work explicitly.

FWIW I've done this by having a DO sidecar to handle state per user (see: https://github.com/cloudflare/mcp-server-cloudflare/blob/main/apps/sandbox-container/server/containerMcp.ts), but it seems like it might be useful to have the option to route sessions to certain DOs

@mattzcarey
Copy link
Contributor Author

I suspect you're running into this issue where you have multiple clients on the same session: #172

The issue is that one DO instance is intended to manage a single session+transport IIRC. But as you mentioned, maybe that's not spec-compliant, but not certain

Use-case is to make a persistent server for a whole team to use. This server should maintain state across multiple interactions. Hence the routing needs to work explicitly.

FWIW I've done this by having a DO sidecar to handle state per user (see: https://github.com/cloudflare/mcp-server-cloudflare/blob/main/apps/sandbox-container/server/containerMcp.ts), but it seems like it might be useful to have the option to route sessions to certain DOs

Hey, thanks for your reply and link. It's a nice idea and would probably work quite well for me. Would you propose I do that? or would you be happy to add the idea behind this PR?

@mattzcarey mattzcarey force-pushed the feat/route-by-agent branch from f0fb470 to 12225f1 Compare May 7, 2025 09:12
@mattzcarey mattzcarey force-pushed the feat/route-by-agent branch from 0ebb6ca to de2ae3c Compare May 7, 2025 09:16
@gching
Copy link

gching commented May 7, 2025

Ran into this same issue to just given how DO works. Another thing we could do is expose an option like name or session on both serve and serveSSE that would be used as the name lookup for a specific DO

A hacky way I've been doing is overriding the session ID used for the MCP session to be the user ID of users

EDIT: Thinking about it more, overriding the session ID isn't sound since it might affect how the MCP server handles responses. Actually that container MCP code is amazing 👀 it actually makes more sense / cleaner to use a separate DO for each user versus forcing the McpAgent DO to be user specific maybe... with that said I think if we do want to let users dictate which DO to lookup, we could do something as above

@meowingtiger
Copy link

meowingtiger commented May 21, 2025

Hey, I wanted similar feature (i.e route every user back to the same MCP they created). I don't think the current solution in the PR is the best way to go, instead I think serveSSE/serve should provide a way to run something like preFetch function to determine how the routing happens or even just allow multiple users to use the same sessionId. This will be a more general solution. I managed to do somerthing like this by wrapping serveSSE but there is a limitation of only one websocket connection in the MCPAgent code, I was able to remove that limitation locally and the following code worked.

// Replace mcpClass.serveSSE in your application with the following wrapper to set consistent sessionId
const getFetchProxy = (route: string, mcpClass: typeof McpAgent, binding: string) => {
	const mcpFetch = mcpClass.serveSSE(route, { binding });

	return {
		fetch: async (req: Request, env: any, ctx: ExecutionContext) => {
			const url = new URL(req.url);
			url.searchParams.set("sessionId", "test1");
			const newReq = new Request(url.toString(), req);
			return await mcpFetch.fetch(newReq, env, ctx);
		}
	}
}

This way we can support not just a single named server but arbitrary policies like one MCP server per user or a group sharing MCP servers based on definition from the app database.

Is this something on the horizon or should I contribute? The only change I made in the MCPAgent code is removing the one websocket connection limit.

@mattzcarey
Copy link
Contributor Author

Closing this as it seems like it would add too much complexity and goes against how MCP is shaping up on a protocol level. I am using the sidecar DO method described above by @cmsparks

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