The MCP Server is a foundational component in the Model Context Protocol (MCP) architecture that provides tools, resources, and capabilities to clients. It implements the server-side of the protocol, responsible for:
Exposing tools that clients can discover and execute
Managing resources with URI-based access patterns
Providing prompt templates and handling prompt requests
Supporting capability negotiation with clients
Implementing server-side protocol operations
Managing concurrent client connections
Providing structured logging and notifications
The server supports both synchronous and asynchronous APIs, allowing for flexible integration in different application contexts.
Copy
// Create a server with custom configurationMcpSyncServer syncServer = McpServer.sync(transport) .serverInfo("my-server", "1.0.0") .capabilities(ServerCapabilities.builder() .resources(true) // Enable resource support .tools(true) // Enable tool support .prompts(true) // Enable prompt support .logging() // Enable logging support .build()) .build();// Initialize the serversyncServer.initialize();// Register tools, resources, and promptssyncServer.addTool(syncToolRegistration);syncServer.addResource(syncResourceRegistration);syncServer.addPrompt(syncPromptRegistration);// Send logging notificationssyncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build());// Close the server when donesyncServer.close();
Copy
// Create a server with custom configurationMcpSyncServer syncServer = McpServer.sync(transport) .serverInfo("my-server", "1.0.0") .capabilities(ServerCapabilities.builder() .resources(true) // Enable resource support .tools(true) // Enable tool support .prompts(true) // Enable prompt support .logging() // Enable logging support .build()) .build();// Initialize the serversyncServer.initialize();// Register tools, resources, and promptssyncServer.addTool(syncToolRegistration);syncServer.addResource(syncResourceRegistration);syncServer.addPrompt(syncPromptRegistration);// Send logging notificationssyncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build());// Close the server when donesyncServer.close();
Copy
// Create an async server with custom configurationMcpAsyncServer asyncServer = McpServer.async(transport) .serverInfo("my-server", "1.0.0") .capabilities(ServerCapabilities.builder() .resources(true) // Enable resource support .tools(true) // Enable tool support .prompts(true) // Enable prompt support .logging() // Enable logging support .build()) .build();// Initialize the serverasyncServer.initialize() .doOnSuccess(v -> logger.info("Server initialized")) .subscribe();// Register tools, resources, and promptsasyncServer.addTool(asyncToolRegistration) .doOnSuccess(v -> logger.info("Tool registered")) .subscribe();asyncServer.addResource(asyncResourceRegistration) .doOnSuccess(v -> logger.info("Resource registered")) .subscribe();asyncServer.addPrompt(asyncPromptRegistration) .doOnSuccess(v -> logger.info("Prompt registered")) .subscribe();// Send logging notificationsasyncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build());// Close the server when doneasyncServer.close() .doOnSuccess(v -> logger.info("Server closed")) .subscribe();
The transport layer in the MCP SDK is responsible for handling the communication between clients and servers. It provides different implementations to support various communication protocols and patterns. The SDK includes several built-in transport implementations:
Create in-process based transport:
Copy
StdioServerTransport transport = new StdioServerTransport(new ObjectMapper());
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
Key features:
Bidirectional communication through stdin/stdout
Process-based integration support
Simple setup and configuration
Lightweight implementation
Create in-process based transport:
Copy
StdioServerTransport transport = new StdioServerTransport(new ObjectMapper());
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
Key features:
Bidirectional communication through stdin/stdout
Process-based integration support
Simple setup and configuration
Lightweight implementation
Creates WebFlux-based SSE server transport. Requires the mcp-spring-webflux dependency.
Implements the MCP HTTP with SSE transport specification, providing:
Server-side event streaming
Integration with Spring WebMVC
Support for traditional web applications
Synchronous operation handling
Creates a Servlet-based SSE server transport. It is included in the core mcp module.
The HttpServletSseServerTransport can be used with any Servlet container.
To use it with a Spring Web application, you can register it as a Servlet bean:
Copy
@Configuration@EnableWebMvcpublic class McpServerConfig implements WebMvcConfigurer { @Bean public HttpServletSseServerTransport servletSseServerTransport() { return new HttpServletSseServerTransport(new ObjectMapper(), "/mcp/message"); } @Bean public ServletRegistrationBean customServletBean(HttpServletSseServerTransport servlet) { return new ServletRegistrationBean(servlet); }}
Implements the MCP HTTP with SSE transport specification using the traditional Servlet API, providing:
Asynchronous message handling using Servlet 6.0 async support
Session management for multiple client connections
Two types of endpoints:
SSE endpoint (/sse) for server-to-client events
Message endpoint (configurable) for client-to-server requests
The server can be configured with various capabilities:
Copy
var capabilities = ServerCapabilities.builder() .resources(false, true) // Resource support with list changes notifications .tools(true) // Tool support with list changes notifications .prompts(true) // Prompt support with list changes notifications .logging() // Enable logging support (enabled by default with loging level INFO) .build();
The server provides structured logging capabilities that allow sending log messages to clients with different severity levels:
Copy
// Send a log message to clientsserver.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Custom log message") .build());
Clients can control the minimum logging level they receive through the mcpClient.setLoggingLevel(level) request. Messages below the set level will be filtered out.
Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7)
The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.