spring-projects / spring-projects/spring-ai

MCP Client Streamable HTTP Transport Does Not Support URL Query Parameters

Open
#6,505 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 7h
Merged PRs (30d)
6

Description

Spring AI MCP Client Streamable HTTP Transport Does Not Support URL Query Parameters

Description

When using Spring AI MCP Client with streamable-http transport to connect to remote MCP servers that require authentication via URL query parameters (such as Amap/Gaode Maps MCP Server), the query parameters are stripped from the final request URL, causing authentication failures.

Background

Many remote MCP servers use URL query parameters for authentication. For example:

  • Amap MCP Server: https://mcp.amap.com/mcp?key=YOUR_API_KEY
  • Other third-party MCP services with API key authentication

The current Spring AI MCP Client implementation splits the URL into url (base URL) and endpoint (path), but query parameters in either field are not preserved in the final HTTP request.

Current Behavior

When configuring:

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            amap:
              url: https://mcp.amap.com/mcp?key=YOUR_API_KEY
              # or
              url: https://mcp.amap.com
              endpoint: /mcp?key=YOUR_API_KEY

The actual HTTP request is sent to https://mcp.amap.com/mcp without the key query parameter, resulting in authentication errors like:

INVALID_USER_KEY

Root Cause

In StreamableHttpWebFluxTransportAutoConfiguration.java:

var webClientBuilder = webClientBuilderTemplate.clone().baseUrl(url);
String streamableHttpEndpoint = Objects.requireNonNullElse(
    serverParameters.getValue().endpoint(), "/mcp");

var transportBuilder = WebClientStreamableHttpTransport.builder(webClientBuilder)
    .endpoint(streamableHttpEndpoint)
    // ...

The WebClient.baseUrl() method parses the URL but only uses scheme, host, and port. When WebClientStreamableHttpTransport later calls .uri(endpoint), it overrides the path and query parameters.

Expected Behavior

The MCP Client should preserve query parameters from either:

  1. The url field (e.g., https://mcp.amap.com/mcp?key=xxx)
  2. The endpoint field (e.g., /mcp?key=xxx)

Or provide an alternative way to configure query parameters for authentication.

Possible Solutions

  1. Parse and preserve query parameters from url or endpoint in WebClientStreamableHttpTransport
  2. Add a new configuration property for query parameters:
    spring:
      ai:
        mcp:
          client:
            streamable-http:
              connections:
                amap:
                  url: https://mcp.amap.com
                  endpoint: /mcp
                  query-params:
                    key: YOUR_API_KEY
    
  3. Support full URL in endpoint without splitting

Workaround

Currently, the only workaround is to implement a custom McpClientTransport that handles query parameters correctly, which requires significant boilerplate code.

Environment

  • Spring AI Version: 1.1.2 (also affects 2.0.0)
  • Java Version: 21
  • Transport: WebFlux Streamable HTTP

Related Issues

  • SSE transport supports query parameters in sse-endpoint field
  • Streamable HTTP transport should have feature parity with SSE transport

Additional Context

This issue affects all users trying to connect to remote MCP servers that use URL query parameter authentication, which is a common pattern for third-party API services.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in StreamableHttpWebFluxTransportAutoConfiguration.java and trace how url, endpoint, and WebClientStreamableHttpTransport combine into the request URI. Check how WebClient.baseUrl() and the transport’s .uri(endpoint) handle query parameters; done means streamable HTTP requests preserve parameters supplied through either configuration field without breaking the existing endpoint behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.