lucianschw-dev adds a /eu-law-chat endpoint with an MCP dispatcher hook in chatTools.ts
The backend gets a second chat endpoint wired to an external MCP server over HTTP. The cleanest piece is a new `mcpTools` parameter on `runLLMStream` that lets any caller route named tool calls to an external dispatcher without touching the main tool-dispatch logic.
3f39cef1 adds three things.
chatTools.ts gains an optional mcpTools parameter on runLLMStream. Pass it { names: string[], dispatch: async (calls) => results[] } and the stream loop will intercept any tool call whose name is in names, send it to your dispatcher, and merge the results back before returning. Tool calls not in the set go through the existing runToolCalls path as before. Error handling is per-call - a dispatcher failure produces an error JSON result for that call rather than aborting the stream. 54 lines changed, no restructuring of the surrounding logic.
euLawMcp.ts (137 lines, new) is the HTTP client for the MCP server. It speaks MCP's Streamable HTTP transport: each invocation opens an initialize handshake, calls tools/call, reads the SSE response, and closes - stateless, no persistent connection. dispatchEuLawCalls is the function passed to mcpTools.dispatch in the route handler.
euLawChat.ts (764 lines, new) is structurally a near-copy of the existing /chat handler. It carries EU_LAW_SYSTEM_PROMPT_EXTRA, four tool schemas matching the eu-law MCP v0.1.1 tool set, and hooks them to dispatchEuLawCalls via the mcpTools slot. The MCP server runs on port 4040; the URL is configured via EU_LAW_MCP_URL in .env.
The 764-line duplication is the obvious problem. Every fix to the base /chat handler has to be manually mirrored into euLawChat.ts. A shared base handler with injectable system prompt and tool dispatcher would be the refactor, but lucianschw-dev has not done that.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?