-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Feature description
Description
Add support for configuring a Micronaut MCP application as a "hub" that aggregates primitives (tools, prompts, resources) from multiple remote MCP servers and exposes them through a single unified MCP server interface.
Motivation
Currently, when working with multiple MCP servers, clients need to connect to each server individually. This proposal would allow a Micronaut application to act as a central hub that:
- Connects to multiple remote MCP servers as a client
- Aggregates all primitives (tools, prompts, resources) from those servers
- Exposes them through a single unified MCP server interface
- Provides a single point of entry for MCP clients
This simplifies the client-side architecture and enables centralized management of multiple MCP servers.
Proposed Solution
Configuration
Enable hub mode through configuration:
micronaut:
mcp:
server:
hub: true # Enable hub mode
transport: HTTP
info:
name: 'mcp-hub'
version: '1.0.0'
client:
http:
server-a:
url: 'https://servera.com/mcp'
server-b:
url: 'https://serverb.com/modelcontextprotocol'
server-c:
url: 'https://serverc.com/mcp'Behavior
When micronaut.mcp.server.hub=true:
- The application will initialize MCP clients for all configured remote servers
- During startup, fetch all primitives from each remote server:
- Tools (via
tools/listand handletools/callrequests) - Prompts (via
prompts/listand handleprompts/getrequests) - Resources (via
resources/listand handleresources/readrequests) - Resource templates (from
resources/templates)
- Tools (via
- Expose all aggregated primitives through the hub's MCP server interface
- Route incoming requests to the appropriate remote server
Name Collision Handling
When multiple servers expose primitives with the same name, we need a strategy. Proposed options (to be discussed):
Option 1: Prefix with server name
- Tool:
server-a:fenEvaluation,server-b:fenEvaluation - Resource:
server-a://resource-uri,server-b://resource-uri - Prompt:
server-a:chess-statistics,server-b:chess-statistics
Option 2: Configuration-based priority
micronaut:
mcp:
server:
hub:
enabled: true
conflict-resolution: FIRST_WINS # or LAST_WINS, PREFIX, ERROROption 3: Metadata enrichment
- Keep original names but add server information in descriptions/metadata
- Allow clients to see which server provides each primitive
Security Configuration
Document how to configure security for remote MCP clients using BeanCreatedEventListener:
@Singleton
class McpClientSecurityConfiguration implements BeanCreatedEventListener<McpClient> {
@Override
public McpClient onCreated(BeanCreatedEvent<McpClient> event) {
McpClient client = event.getBean();
// Configure authentication for server-a
// e.g., add headers, tokens, etc.
return client;
}
}Request Routing
The hub should:
- Maintain a mapping of primitives to their source servers
- Forward
tools/call,prompts/get,resources/readrequests to the appropriate remote server - Handle errors gracefully (e.g., when a remote server is unavailable)
Server Capabilities
The hub's ServerCapabilities should reflect the aggregated capabilities of all connected servers:
- Tools: Union of all remote tools
- Prompts: Union of all remote prompts (considering
listChangedsettings) - Resources: Union of all remote resources (considering
subscribeandlistChangedsettings)
Implementation Considerations
-
Startup Performance: Fetching primitives from multiple servers during startup could be slow
- Consider async initialization
- Provide configuration for timeout settings
- Support lazy loading of primitives
-
Dynamic Updates: How to handle when remote servers add/remove primitives
- Support for MCP notification protocol (
notifications/tools/list_changed, etc.) - Periodic polling as fallback
- Configuration for refresh intervals
- Support for MCP notification protocol (
-
Error Handling: What happens when a remote server is unavailable
- Continue serving primitives from available servers
- Cache last-known primitives
- Report degraded status through health endpoints
-
Transport Compatibility:
- Initial implementation should support HTTP transport
- Future: Consider STDIO transport support (though less common for remote servers)
-
Testing: Provide utilities for testing hub configurations
- Mock remote MCP servers
- Integration tests with embedded servers
Documentation Updates
The documentation should include:
- New section on "MCP Hub" functionality
- Configuration examples for hub mode
- Security configuration examples
- Name collision handling strategies
- Performance considerations and best practices
- Examples of common hub architectures
Open Questions
- Should the hub support filtering which primitives to expose from each server?
- How should the hub handle versioning differences between remote servers?
- Should the hub support primitive transformation/adaptation (e.g., modifying tool schemas)?