spring-projects / spring-projects/spring-ai

MCP Gateway / Multi-Server MCP Proxy

Open
#5,382 0 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

mcp
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 7h
Merged PRs (30d)
6

Description

Expected Behavior

Spring AI should support an MCP Gateway / Multi-Server MCP Proxy use case.

The goal is to centralize the following capabilities:

  • MCP tool listing
  • MCP tool invocation
  • Authorization
  • Logging
  • Monitoring
  • Alerting
  • Connectivity

This is intended for scenarios where each business domain has its own dedicated MCP Server (with domain-specific MCP tools), and all of those tools should be accessible through a single, centralized MCP Gateway.

Example Setup - Each domain (e.g., flights, hotels, cars) has its own MCP Server. The MCP Gateway should be able to:

  • List all MCP tools exposed by each MCP Server
  • Invoke any MCP tool through the gateway
Image

Current Behavior

  • MCP tool listing works correctly.
  • MCP tool invocation returns a repackaged response instead of the original response.
    • The MCP tool response differs when:
    • Invoking an MCP Server directly

I created an example MCP Gateway here:
https://github.com/dominikcebula/spring-ai-travel-agent/tree/feature/mcp-gateway/mcp-gateway

MCP clients are configured here:
https://github.com/dominikcebula/spring-ai-travel-agent/blob/feature/mcp-gateway/mcp-gateway/src/main/resources/application.yml

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            cars-mcp-server:
              url: ${CARS_MCP_URL:http://localhost:8011}
            flights-mcp-server:
              url: ${FLIGHTS_MCP_URL:http://localhost:8021}
            hotels-mcp-server:
              url: ${HOTELS_MCP_URL:http://localhost:8031}
      server:
        name: ${spring.application.name}
        protocol: STREAMABLE
  application:
    name: mcp-gateway
server:
  port: 8060

When invoking a tool through the MCP Gateway, the response looks like this:

Image

Instead of receiving the expected JSON payload, the response is repackaged into a single-element structure with a "text" key.

When invoking the same MCP tool directly on the MCP Server, the response is correct:

Image

Context

  • How has this issue affected you?

    • I’m unable to build an MCP Gateway that behaves correctly.
  • What are you trying to accomplish?

    • Build an MCP Gateway / Multi-Server MCP Proxy that centralizes MCP tool listing, tool invocation, authorization, logging, monitoring, alerting, and connectivity.
  • What alternatives have you considered?

  • Are you aware of any workarounds?

    • One possible workaround would be to wrap each MCP client with an additional “MCP Client Unwrapping Proxy” to unwrap the repackaged response. However, this feels like a hack rather than a proper solution.

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 with the linked mcp-gateway example and its application.yml MCP client configuration, then compare the same tool invocation through the gateway and directly against an MCP server. Trace where the gateway response is repackaged and verify completion by preserving the original JSON payload while retaining multi-server tool listing and invocation.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.