CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-mcp

Spring Framework integration for Model Context Protocol (MCP), providing Spring AI function calling capabilities and Spring-friendly abstractions for MCP clients and MCP servers

Overview
Eval results
Files

server-integration.mddocs/reference/

Spring AI Server Integration

Convert Spring AI tool callbacks to MCP server specifications for exposing Spring functions as MCP tools. This allows you to create MCP servers that expose Spring AI functions to other applications.

Import

import org.springframework.ai.mcp.McpToolUtils;
import org.springframework.ai.tool.ToolCallback;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpStatelessServerFeatures;
import org.springframework.util.MimeType;

Synchronous Server Tool Specifications

Convert Multiple Callbacks

// Convert list of callbacks
static List<McpServerFeatures.SyncToolSpecification> toSyncToolSpecification(
    List<ToolCallback> toolCallbacks)

// Convert varargs callbacks
static List<McpServerFeatures.SyncToolSpecification> toSyncToolSpecifications(
    ToolCallback... toolCallbacks)

Converts a list of Spring AI tool callbacks to MCP synchronous tool specifications.

Usage Example

import org.springframework.ai.tool.ToolCallback;
import io.modelcontextprotocol.server.McpServerFeatures;

// Define your Spring AI tool callbacks
ToolCallback weatherCallback = // ... your weather tool
ToolCallback databaseCallback = // ... your database tool
ToolCallback filesystemCallback = // ... your filesystem tool

// Convert to MCP sync tool specifications
List<McpServerFeatures.SyncToolSpecification> syncSpecs =
    McpToolUtils.toSyncToolSpecifications(
        weatherCallback,
        databaseCallback,
        filesystemCallback
    );

Convert Single Callback

static McpServerFeatures.SyncToolSpecification toSyncToolSpecification(
    ToolCallback toolCallback)

Converts a single Spring AI tool callback to an MCP synchronous tool specification.

Usage Example

ToolCallback myCallback = // ... your callback

McpServerFeatures.SyncToolSpecification spec =
    McpToolUtils.toSyncToolSpecification(myCallback);

Convert with MIME Type

static McpServerFeatures.SyncToolSpecification toSyncToolSpecification(
    ToolCallback toolCallback, MimeType mimeType)

Converts a tool callback with a specific MIME type for the output content. Useful when tools return non-text content like images.

Parameters

  • toolCallback: The Spring AI tool callback to convert
  • mimeType: The MIME type of the output (e.g., "image/png", "application/json")

Usage Example

import org.springframework.util.MimeType;

// Tool that returns an image
ToolCallback imageGeneratorCallback = // ... image generation tool

McpServerFeatures.SyncToolSpecification imageSpec =
    McpToolUtils.toSyncToolSpecification(
        imageGeneratorCallback,
        MimeType.valueOf("image/png")
    );

// Tool that returns JSON
ToolCallback jsonCallback = // ... JSON-returning tool

McpServerFeatures.SyncToolSpecification jsonSpec =
    McpToolUtils.toSyncToolSpecification(
        jsonCallback,
        MimeType.valueOf("application/json")
    );

Stateless Synchronous Specifications

static McpStatelessServerFeatures.SyncToolSpecification toStatelessSyncToolSpecification(
    ToolCallback toolCallback, MimeType mimeType)

Converts a tool callback to a stateless synchronous MCP tool specification. Stateless specifications don't maintain server-side state between calls.

Usage Example

McpStatelessServerFeatures.SyncToolSpecification statelessSpec =
    McpToolUtils.toStatelessSyncToolSpecification(callback, null);

Asynchronous Server Tool Specifications

Convert Multiple Callbacks

// Convert list of callbacks
static List<McpServerFeatures.AsyncToolSpecification> toAsyncToolSpecifications(
    List<ToolCallback> toolCallbacks)

// Convert varargs callbacks
static List<McpServerFeatures.AsyncToolSpecification> toAsyncToolSpecifications(
    ToolCallback... toolCallbacks)

Converts Spring AI tool callbacks to MCP asynchronous tool specifications using Project Reactor.

Usage Example

List<ToolCallback> callbacks = List.of(callback1, callback2, callback3);

List<McpServerFeatures.AsyncToolSpecification> asyncSpecs =
    McpToolUtils.toAsyncToolSpecifications(callbacks);

Convert Single Callback

static McpServerFeatures.AsyncToolSpecification toAsyncToolSpecification(
    ToolCallback toolCallback)

Converts a single tool callback to an asynchronous MCP tool specification.

Usage Example

McpServerFeatures.AsyncToolSpecification asyncSpec =
    McpToolUtils.toAsyncToolSpecification(callback);

Convert with MIME Type

static McpServerFeatures.AsyncToolSpecification toAsyncToolSpecification(
    ToolCallback toolCallback, MimeType mimeType)

Converts a tool callback to an async specification with a specific output MIME type.

Usage Example

McpServerFeatures.AsyncToolSpecification asyncImageSpec =
    McpToolUtils.toAsyncToolSpecification(
        imageCallback,
        MimeType.valueOf("image/jpeg")
    );

Stateless Asynchronous Specifications

static McpStatelessServerFeatures.AsyncToolSpecification toStatelessAsyncToolSpecification(
    ToolCallback toolCallback, MimeType mimeType)

Converts a tool callback to a stateless asynchronous MCP tool specification.

Usage Example

McpStatelessServerFeatures.AsyncToolSpecification statelessAsyncSpec =
    McpToolUtils.toStatelessAsyncToolSpecification(callback, null);

Creating an MCP Server

Synchronous MCP Server

import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;
import org.springframework.ai.tool.ToolCallback;

// Define your Spring AI tools
ToolCallback weatherTool = // ... weather tool implementation
ToolCallback databaseTool = // ... database tool implementation

// Convert to MCP specifications
List<McpServerFeatures.SyncToolSpecification> toolSpecs =
    McpToolUtils.toSyncToolSpecifications(weatherTool, databaseTool);

// Create MCP server
McpSyncServer mcpServer = McpServer.sync()
    .serverInfo(McpSchema.Implementation.builder()
        .name("my-spring-ai-server")
        .version("1.0.0")
        .build())
    .capabilities(McpSchema.ServerCapabilities.builder()
        .tools(McpSchema.ServerCapabilities.Tools.builder().build())
        .build())
    .tools(toolSpecs)
    .build();

// The server is now ready to accept connections and expose the Spring AI tools

Asynchronous MCP Server

import reactor.core.publisher.Mono;

// Define your Spring AI tools
List<ToolCallback> callbacks = List.of(tool1, tool2, tool3);

// Convert to async MCP specifications
List<McpServerFeatures.AsyncToolSpecification> asyncToolSpecs =
    McpToolUtils.toAsyncToolSpecifications(callbacks);

// Create async MCP server
McpAsyncServer asyncServer = McpServer.async()
    .serverInfo(McpSchema.Implementation.builder()
        .name("my-async-spring-ai-server")
        .version("1.0.0")
        .build())
    .capabilities(McpSchema.ServerCapabilities.builder()
        .tools(McpSchema.ServerCapabilities.Tools.builder().build())
        .build())
    .tools(asyncToolSpecs)
    .build();

Complete Example: Spring AI Function as MCP Server

import org.springframework.ai.mcp.McpToolUtils;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.stereotype.Component;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;

@Component
public class SpringAiMcpServer {

    private final McpSyncServer mcpServer;

    public SpringAiMcpServer(List<ToolCallback> allToolCallbacks) {
        // Convert all Spring AI tool callbacks to MCP specifications
        List<McpServerFeatures.SyncToolSpecification> mcpToolSpecs =
            McpToolUtils.toSyncToolSpecification(allToolCallbacks);

        // Create MCP server exposing these tools
        this.mcpServer = McpServer.sync()
            .serverInfo(McpSchema.Implementation.builder()
                .name("spring-ai-mcp-server")
                .version("1.0.0")
                .title("Spring AI Functions Server")
                .build())
            .capabilities(McpSchema.ServerCapabilities.builder()
                .tools(McpSchema.ServerCapabilities.Tools.builder()
                    .listChanged(true)  // Support tool list changes
                    .build())
                .logging(McpSchema.ServerCapabilities.Logging.builder().build())
                .build())
            .tools(mcpToolSpecs)
            .build();
    }

    public McpSyncServer getMcpServer() {
        return mcpServer;
    }
}

// Spring Configuration
@Configuration
public class ToolConfiguration {

    @Bean
    public ToolCallback weatherToolCallback() {
        return ToolCallback.builder()
            .name("get_weather")
            .description("Get current weather for a location")
            .inputSchema(/* ... */)
            .function((input) -> {
                // Implementation
                return "Weather data: " + input;
            })
            .build();
    }

    @Bean
    public ToolCallback databaseQueryCallback() {
        return ToolCallback.builder()
            .name("query_database")
            .description("Query the database")
            .inputSchema(/* ... */)
            .function((input) -> {
                // Implementation
                return "Query results: " + input;
            })
            .build();
    }

    @Bean
    public SpringAiMcpServer springAiMcpServer(List<ToolCallback> allCallbacks) {
        return new SpringAiMcpServer(allCallbacks);
    }
}

Image Output Example

import org.springframework.util.MimeType;
import java.util.Base64;

// Tool that generates images
ToolCallback imageGeneratorTool = ToolCallback.builder()
    .name("generate_image")
    .description("Generate an image based on a description")
    .inputSchema(/* ... */)
    .function((description) -> {
        // Generate image (simplified)
        byte[] imageBytes = generateImage(description);
        // Return base64 encoded image
        return Base64.getEncoder().encodeToString(imageBytes);
    })
    .build();

// Convert with image MIME type
McpServerFeatures.SyncToolSpecification imageToolSpec =
    McpToolUtils.toSyncToolSpecification(
        imageGeneratorTool,
        MimeType.valueOf("image/png")
    );

// Use in MCP server
McpSyncServer imageServer = McpServer.sync()
    .serverInfo(/* ... */)
    .capabilities(/* ... */)
    .tools(List.of(imageToolSpec))
    .build();

WebMVC Integration Example

import io.modelcontextprotocol.server.spring.McpSpringWebMvc;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import org.springframework.context.annotation.Bean;

@Configuration
public class McpWebMvcConfiguration {

    @Bean
    public RouterFunction<ServerResponse> mcpServerRoutes(
            SpringAiMcpServer springAiMcpServer) {

        // Expose MCP server via HTTP using Spring WebMVC
        return McpSpringWebMvc.createRouterFunction(
            "/mcp",  // Base path
            springAiMcpServer.getMcpServer()
        );
    }
}

// The Spring AI functions are now accessible via HTTP at /mcp
// Other applications can connect to this endpoint as an MCP client

WebFlux Integration Example

import io.modelcontextprotocol.server.spring.McpSpringWebFlux;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.context.annotation.Bean;

@Configuration
public class McpWebFluxConfiguration {

    @Bean
    public RouterFunction<ServerResponse> mcpAsyncServerRoutes(
            List<ToolCallback> toolCallbacks) {

        // Convert to async specifications
        List<McpServerFeatures.AsyncToolSpecification> asyncSpecs =
            McpToolUtils.toAsyncToolSpecifications(toolCallbacks);

        // Create async server
        McpAsyncServer asyncServer = McpServer.async()
            .serverInfo(/* ... */)
            .capabilities(/* ... */)
            .tools(asyncSpecs)
            .build();

        // Expose via WebFlux
        return McpSpringWebFlux.createRouterFunction(
            "/mcp-async",
            asyncServer
        );
    }
}

Error Handling in Server Tools

When Spring AI tool callbacks throw exceptions, they are automatically converted to MCP error responses:

ToolCallback errorHandlingTool = ToolCallback.builder()
    .name("risky_operation")
    .description("An operation that might fail")
    .inputSchema(/* ... */)
    .function((input) -> {
        try {
            // Risky operation
            return performOperation(input);
        } catch (Exception e) {
            // Exception is caught by McpToolUtils conversion
            // and returned as MCP error response
            throw new RuntimeException("Operation failed: " + e.getMessage());
        }
    })
    .build();

Related Components

  • MCP Tool Utilities - Conversion utility methods
  • Synchronous Tool Callbacks - Creating tool callbacks
  • Asynchronous Tool Callbacks - Creating async callbacks

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-ai--spring-ai-mcp@1.1.0

docs

index.md

tile.json