feat(mcp): DingDuff connector support — OAuth redirect discovery and chat case retrieval - #331
Open
duncanmcqueen wants to merge 2 commits into
Open
Conversation
… chat case retrieval DingDuff's MCP server 302s its well-known OAuth metadata to a path-scoped issuer, which the MCP SDK's own discovery cannot follow. - guardedFetch now follows redirects hop by hop: each 3xx target is re-validated against the SSRF guard (HTTPS-only, private-IP and metadata-host blocks, DNS-pinned dispatcher), credentials are stripped on cross-origin hops, and redirected POSTs become GETs per the fetch spec. Redirects are never auto-followed by undici (redirect: manual on every hop). - discoverOAuthServerState + the OAuthClientProvider.discoveryState hook hand the SDK pre-discovered metadata, so OAuth connectors whose well-known documents live behind a redirect can complete the flow. - Chat: when DingDuff MCP tools are present on a turn, the built-in CourtListener tools are withheld and the system prompt directs case retrieval, case reading, and document lookup at the DingDuff tools, so the two case-law sources are never mixed in one turn.
|
|
Author
|
Being a lawyer a bit here (and did accept it), but the CLA says this:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for DingDuff as a user MCP connector, so the assistant can use DingDuff tools for case retrieval, case reading, and case-specific document lookup directly from chat.
Two changes make this work:
1. OAuth discovery behind redirects (
backend/src/lib/mcp/client.ts,oauth.ts)DingDuff's server 302s its well-known OAuth metadata to a path-scoped issuer, and the MCP SDK's own discovery does not follow redirects, so the OAuth flow could not complete.
guardedFetchnow follows redirects hop by hop instead of refusing them outright: every 3xx target is re-validated against the existing SSRF guard (HTTPS-only, private-IP/metadata-host blocks, DNS-pinned dispatcher), credentials are stripped on cross-origin hops (per the fetch spec), and redirected POSTs are converted to GET with the body dropped. Undici still never auto-follows (redirect: "manual"on every hop), so no redirect can smuggle egress past the guard.discoverOAuthServerStateplus the SDK'sOAuthClientProvider.discoveryStatehook hand the SDK pre-discovered metadata, so connectors whose well-known documents live behind a redirect complete the flow.2. Chat integration (
backend/src/lib/chat/streaming.ts)When DingDuff MCP tools are present on a turn, the built-in CourtListener tools are withheld and the system prompt directs case retrieval at the DingDuff tools, so the two case-law sources are never mixed within a single turn.
Tests
client.ssrf.test.ts: redirect following with per-hop re-validation, refusal to follow a redirect to a blocked address, credential stripping on cross-origin redirects, and POST→GET conversion.tsc --noEmitclean.Notes