java-sdk/mcp-docs/0.6.0-MIGRATION-GUIDE.md
Dariusz Jędrzejczyk 6839d3b740 Refactor McpClient for async and sync interactions
Introduce new builder patterns and enhance type safety

- Add new builder patterns for McpClient and McpServer with sync/async variants
- Introduce dedicated McpClientFeatures and McpServerFeatures classes
- Enhance type safety and reactive support with proper Mono integration
- Add migration guide for 0.6.0 release
- Mark old builder methods as deprecated
- Update documentation to reflect new APIs

BREAKING CHANGE: The old builder patterns using McpClient.using() and McpServer.using()
are now deprecated in favor of new sync() and async() builders that provide
better type safety and clearer sync/async separation. Follow the migration guide.

Resolves #48

Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Co-authored-by: Christian Tzolov <ctzolov@vmware.com>
2025-01-23 12:27:06 +01:00

6.5 KiB

Spring AI MCP 0.5.0 Migration Guide

This guide outlines the steps required to migrate your code to Spring AI MCP 0.6.0.

Key Changes

  • New builder patterns for McpClient and McpServer
  • Introduction of dedicated feature classes for sync/async operations
  • Enhanced type safety and reactive support
  • Deprecated methods and classes marked for removal

Client Migration

Creating Clients

Before:

// Sync client
McpClient.using(transport)
    .requestTimeout(Duration.ofSeconds(5))
    .sync();

// Async client
McpClient.using(transport)
    .requestTimeout(Duration.ofSeconds(5))
    .async();

After:

// Sync client
McpClient.sync(transport)
    .requestTimeout(Duration.ofSeconds(5))
    .build();

// Async client
McpClient.async(transport)
    .requestTimeout(Duration.ofSeconds(5))
    .build();

Change Consumers

Before:

// Sync client
McpClient.using(transport)
    .toolsChangeConsumer(tools -> handleTools(tools))
    .resourcesChangeConsumer(resources -> handleResources(resources))
    .promptsChangeConsumer(prompts -> handlePrompts(prompts))
    .sync();

// Async client
McpClient.using(transport)
    .toolsChangeConsumer(tools -> handleTools(tools))
    .resourcesChangeConsumer(resources -> handleResources(resources))
    .promptsChangeConsumer(prompts -> handlePrompts(prompts))
    .async();

After:

// Sync client
McpClient.sync(transport)
    .toolsChangeConsumer(tools -> handleTools(tools))
    .resourcesChangeConsumer(resources -> handleResources(resources))
    .promptsChangeConsumer(prompts -> handlePrompts(prompts))
    .build();

// Async client
McpClient.async(transport)
    .toolsChangeConsumer(tools -> Mono.fromRunnable(() -> handleTools(tools)))
    .resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> handleResources(resources)))
    .promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> handlePrompts(prompts)))
    .build();

Sampling Handlers

Before:

// Sync client
McpClient.using(transport)
    .sampling(request -> new CreateMessageResult("response"))
    .sync();

// Async client
McpClient.using(transport)
    .sampling(request -> new CreateMessageResult("response"))
    .async();

After:

// Sync client
McpClient.sync(transport)
    .sampling(request -> new CreateMessageResult("response"))
    .build();

// Async client
McpClient.async(transport)
    .sampling(request -> Mono.just(new CreateMessageResult("response")))
    .build();

Server Migration

Creating Servers

Before:

// Sync server
McpServer.using(transport)
    .serverInfo("test-server", "1.0.0")
    .sync();

// Async server
McpServer.using(transport)
    .serverInfo("test-server", "1.0.0")
    .async();

After:

// Sync server
McpServer.sync(transport)
    .serverInfo("test-server", "1.0.0")
    .build();

// Async server
McpServer.async(transport)
    .serverInfo("test-server", "1.0.0")
    .build();

Tool Registration

Before:

// Using ToolRegistration record
new ToolRegistration(
    new Tool("calculator", "Performs calculations", schema),
    args -> new CallToolResult("result")
);

After:

// Sync server
new McpServerFeatures.SyncToolRegistration(
    new Tool("calculator", "Performs calculations", schema),
    args -> new CallToolResult("result")
);

// Async server
new McpServerFeatures.AsyncToolRegistration(
    new Tool("calculator", "Performs calculations", schema),
    args -> Mono.just(new CallToolResult("result"))
);

Resource Registration

Before:

// Using ResourceRegistration record
new ResourceRegistration(
    new Resource("docs", "Documentation", "text/markdown"),
    request -> new ReadResourceResult(content)
);

After:

// Sync server
new McpServerFeatures.SyncResourceRegistration(
    new Resource("docs", "Documentation", "text/markdown"),
    request -> new ReadResourceResult(content)
);

// Async server
new McpServerFeatures.AsyncResourceRegistration(
    new Resource("docs", "Documentation", "text/markdown"),
    request -> Mono.just(new ReadResourceResult(content))
);

Prompt Registration

Before:

// Using PromptRegistration record
new PromptRegistration(
    new Prompt("analyze", "Code analysis"),
    request -> new GetPromptResult("result")
);

After:

// Sync server
new McpServerFeatures.SyncPromptRegistration(
    new Prompt("analyze", "Code analysis"),
    request -> new GetPromptResult("result")
);

// Async server
new McpServerFeatures.AsyncPromptRegistration(
    new Prompt("analyze", "Code analysis"),
    request -> Mono.just(new GetPromptResult("result"))
);

Spring Integration Changes

Tool Helper Changes

Before:

ToolHelper.toToolRegistration(functionCallback);
ToolHelper.toToolRegistration(functionCallbacks);

After:

ToolHelper.toSyncToolRegistration(functionCallback);
ToolHelper.toSyncToolRegistration(functionCallbacks);

Deprecated APIs

The following APIs are deprecated and will be removed in a future release:

  • McpClient.using() - Use McpClient.sync() or McpClient.async() instead
  • McpServer.using() - Use McpServer.sync() or McpServer.async() instead
  • McpServer.ToolRegistration - Use McpServerFeatures.SyncToolRegistration or McpServerFeatures.AsyncToolRegistration instead
  • McpServer.ResourceRegistration - Use McpServerFeatures.SyncResourceRegistration or McpServerFeatures.AsyncResourceRegistration instead
  • McpServer.PromptRegistration - Use McpServerFeatures.SyncPromptRegistration or McpServerFeatures.AsyncPromptRegistration instead
  • ToolHelper.toToolRegistration() - Use ToolHelper.toSyncToolRegistration() instead

Benefits of Migration

  1. Improved Type Safety: The new builder patterns and feature classes provide better compile-time type checking.

  2. Clear Async/Sync Separation: Distinct builders and features for sync and async operations make the code intent clearer.

  3. Enhanced Reactive Support: Async operations now properly integrate with Project Reactor's Mono type.

  4. Better Error Handling: More consistent error handling across sync and async operations.

  5. Simplified Configuration: Builder patterns provide a more intuitive way to configure clients and servers.

Additional Notes

  • The migration primarily focuses on builder patterns and feature organization
  • Functional behavior remains the same after migration
  • Async operations now properly integrate with Project Reactor
  • All deprecated APIs will continue to work but will be removed in a future release