spring-projects / spring-projects/spring-ai

Support selective MCP client injection with @McpClient annotation

Open
#5,201 1 comment 0 reactions 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

Support selective MCP client injection with @McpClient annotation

Problem Statement

When building AI agents with Spring AI's MCP (Model Context Protocol) client, I need to connect different LLM agents to different MCP servers. The current implementation only provides a List<McpSyncClient> bean, which doesn't support selective injection.

Current Limitation
// Current: Only way to get MCP clients
@Autowired
List<McpSyncClient> allClients;  // Gets ALL clients, no way to select specific one
Real-World Use Case

In a multi-agent system, you might have:

  • Database Agent → needs database server (SQL query tool)
  • File Agent → needs filesystem server (file operations)
  • API Agent → needs external-api server (REST calls)

Each agent should only have access to its designated MCP server's tools. Injecting all clients and filtering manually is:

  1. Error-prone (wrong server selected at runtime)
  2. Verbose (boilerplate filtering code everywhere)
  3. Not idiomatic Spring (should use DI, not manual lookup)

Proposed Solution

Add a @McpClient("connectionName") qualifier annotation for selective injection:

// Proposed: Select specific client by connection name
@Bean
public ChatClient fileAgent(
    ChatClient.Builder builder,
    @McpClient("filesystem") McpSyncClient fsClient
) {
    return builder
        .defaultTools(new SyncMcpToolCallbackProvider(List.of(fsClient)))
        .build();
}

The connectionName corresponds to the key in application properties:

spring.ai.mcp.client.sse.connections.database.url=http://localhost:8080/sse
spring.ai.mcp.client.streamable-http.connections.filesystem.url=http://localhost:9090/mcp

Benefits

  • Declarative injection — No manual filtering code needed
  • Standard Spring DI pattern — Replaces anti-pattern with @McpClient qualifier
  • Easier testing — Mock individual beans instead of entire list

Compatibility

  • Non-breaking: Existing List<McpSyncClient> bean remains unchanged
  • Fallback: Standard @Qualifier("connectionName") also works
  • Scope: Supports both SSE and Streamable HTTP transports

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 by tracing the MCP client configuration that creates the current List bean and how connection names from the SSE and Streamable HTTP application properties are represented. Define the annotation and injection behavior, while preserving list injection and standard @Qualifier support; done means agents can receive only the named client through the proposed annotation.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.