Java implementation of the Model Context Protocol (MCP) client for the LangChain4j framework, enabling integration with MCP servers for tools, resources, and prompts
LangChain4j MCP is a Java implementation of the Model Context Protocol (MCP) client for the LangChain4j framework. It enables Java applications to communicate with MCP servers and integrate their tools, resources, and prompts into LangChain4j-based AI applications.
// 1. Create transport
StdioMcpTransport transport = StdioMcpTransport.builder()
.command(List.of("npx", "-y", "@modelcontextprotocol/server-example"))
.build();
// 2. Create MCP client
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.build();
// 3. Create tool provider
McpToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(client)
.build();
// 4. Integrate with LangChain4j
MyAssistant assistant = AiServices.builder(MyAssistant.class)
.chatLanguageModel(model)
.toolProvider(toolProvider)
.build();
// 5. Clean up
client.close();Add the following dependency to your Maven pom.xml:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mcp</artifactId>
<version>1.11.0</version>
</dependency>For Gradle:
implementation 'dev.langchain4j:langchain4j-mcp:1.11.0'// Client
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
// Tool Provider
import dev.langchain4j.mcp.McpToolProvider;
// Transports
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.mcp.client.transport.websocket.WebSocketMcpTransport;
import dev.langchain4j.mcp.client.transport.http.StreamableHttpMcpTransport;
// Data Models
import dev.langchain4j.mcp.client.McpResource;
import dev.langchain4j.mcp.client.McpPrompt;
import dev.langchain4j.mcp.client.McpRoot;
// Exceptions
import dev.langchain4j.mcp.client.McpException;
import dev.langchain4j.mcp.client.IllegalResponseException;The library is organized into several key modules:
Core McpClient interface and DefaultMcpClient implementation for communicating with MCP servers.
Key Interface:
interface McpClient extends AutoCloseable {
String key();
List<ToolSpecification> listTools();
ToolExecutionResult executeTool(ToolExecutionRequest request);
List<McpResource> listResources();
McpReadResourceResult readResource(String uri);
List<McpPrompt> listPrompts();
McpGetPromptResult getPrompt(String name, Map<String, Object> arguments);
void checkHealth();
void setRoots(List<McpRoot> roots);
void close();
}Multiple transport protocols (stdio, WebSocket, HTTP/SSE) for server communication.
Transport Selection Guide:
// Stdio Transport
class StdioMcpTransport implements McpTransport {
static Builder builder();
}
// WebSocket Transport
class WebSocketMcpTransport implements McpTransport {
static Builder builder();
void reloadSslContext(SSLContext sslContext);
}
// HTTP Transport (Recommended)
class StreamableHttpMcpTransport implements McpTransport {
static Builder builder();
}McpToolProvider for integrating MCP tools into LangChain4j's agent framework.
class McpToolProvider implements ToolProvider {
void addMcpClient(McpClient client);
void removeMcpClient(McpClient client);
void addFilter(BiPredicate<McpClient, ToolSpecification> filter);
void setFilter(BiPredicate<McpClient, ToolSpecification> filter);
void setToolNameMapper(BiFunction<McpClient, ToolSpecification, String> mapper);
ToolProviderResult provideTools(ToolProviderRequest request);
}Classes representing MCP resources, prompts, roots, and content types.
record McpResource(String uri, String name, String description, String mimeType) {}
record McpPrompt(String name, String description, List<McpPromptArgument> arguments) {}
record McpRoot(String name, String uri) {}
sealed interface McpResourceContents permits McpTextResourceContents, McpBlobResourceContents {}
sealed interface McpPromptContent permits McpTextContent, McpImageContent, McpEmbeddedResource {}Client for discovering and querying MCP servers from the registry.
interface McpRegistryClient {
McpServerList listServers(McpServerListRequest request);
McpGetServerResponse getSpecificServerVersion(String serverName, String version);
McpServerList getAllVersionsOfServer(String serverName);
McpRegistryHealth healthCheck();
}Presentation layer for exposing MCP resources as executable tools.
interface McpResourcesAsToolsPresenter {
ToolSpecification createListResourcesSpecification();
ToolExecutor createListResourcesExecutor(List<McpClient> clients);
ToolSpecification createGetResourceSpecification();
ToolExecutor createGetResourceExecutor(List<McpClient> clients);
}→ Resources as Tools Documentation
Monitor and react to MCP client events and log messages.
interface McpClientListener {
void beforeExecuteTool(McpCallContext context);
void afterExecuteTool(McpCallContext context, ToolExecutionResult result, Map<String, Object> rawResult);
void onExecuteToolError(McpCallContext context, Throwable error);
// ... resource and prompt methods
}
interface McpLogMessageHandler {
void handleLogMessage(McpLogMessage message);
}→ Logging and Listeners Documentation
Specialized exceptions for MCP protocol errors.
class McpException extends LangChain4jException {
McpException(int errorCode, String errorMessage);
int errorCode();
String errorMessage();
}
class IllegalResponseException extends LangChain4jException {
IllegalResponseException(String message);
}| Operation | Default Timeout |
|---|---|
| Initialization | 30 seconds |
| Tool execution | 60 seconds |
| Resources | 60 seconds |
| Prompts | 60 seconds |
| Ping | 10 seconds |
| Reconnect interval | 5 seconds |
| Health check interval | 30 seconds (when enabled) |
The library uses MCP protocol version 2025-11-25 by default. This can be customized via the client builder:
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.protocolVersion("2025-11-25")
.build();Tool list caching is enabled by default to reduce unnecessary server requests. Use evictToolListCache() to manually clear the cache or disable caching via the builder:
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.cacheToolList(false) // Disable caching
.build();
// Or manually evict cache
client.evictToolListCache();// Create clients for different MCP servers
McpClient weatherClient = DefaultMcpClient.builder()
.transport(weatherTransport)
.key("weather-server")
.build();
McpClient filesystemClient = DefaultMcpClient.builder()
.transport(filesystemTransport)
.key("filesystem-server")
.build();
// Combine into single tool provider
McpToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(weatherClient, filesystemClient)
.build();// Filter tools by name
McpToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(client)
.filterToolNames("read_file", "write_file")
.build();
// Custom filter predicate
toolProvider.addFilter((mcpClient, toolSpec) ->
toolSpec.name().startsWith("safe_")
);McpHeadersSupplier headersSupplier = context -> {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + getToken());
headers.put("X-Request-ID", UUID.randomUUID().toString());
return headers;
};
StreamableHttpMcpTransport transport = StreamableHttpMcpTransport.builder()
.url("https://mcp-server.example.com")
.customHeaders(headersSupplier)
.build();// Enable automatic health checks
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.autoHealthCheck(true)
.autoHealthCheckInterval(Duration.ofSeconds(30))
.build();
// Manual health check
try {
client.checkHealth();
System.out.println("Server is healthy");
} catch (Exception e) {
System.err.println("Server health check failed: " + e.getMessage());
}Always close clients when done:
try (McpClient client = DefaultMcpClient.builder()
.transport(transport)
.build()) {
// Use the client
List<ToolSpecification> tools = client.listTools();
} // Automatically closedimport dev.langchain4j.mcp.*;
import dev.langchain4j.mcp.client.*;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class McpExample {
interface Assistant {
String chat(String message);
}
public static void main(String[] args) {
// 1. Create MCP transport (subprocess)
StdioMcpTransport transport = StdioMcpTransport.builder()
.command(List.of("npx", "-y", "@modelcontextprotocol/server-filesystem",
"/path/to/allowed/directory"))
.build();
// 2. Create MCP client with custom configuration
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.key("filesystem-server")
.toolExecutionTimeout(Duration.ofSeconds(120))
.autoHealthCheck(true)
.build();
// 3. Create tool provider with filtering
McpToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(client)
.filter((mcpClient, toolSpec) ->
!toolSpec.name().contains("delete")) // Exclude delete operations
.build();
// 4. Create chat model
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4")
.build();
// 5. Create AI assistant with MCP tools
Assistant assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.toolProvider(toolProvider)
.build();
// 6. Use the assistant
String response = assistant.chat("List the files in the directory");
System.out.println(response);
// 7. Clean up
client.close();
}
}evictToolListCache() when server capabilities changeFor high-throughput scenarios with HTTP transport:
// Create shared HTTP client with connection pooling
HttpClient sharedHttpClient = createPooledHttpClient();
StreamableHttpMcpTransport transport = StreamableHttpMcpTransport.builder()
.url("https://mcp-server.example.com")
.httpClient(sharedHttpClient) // Note: Check if this option exists
.build();Adjust timeouts based on expected operation duration:
McpClient client = DefaultMcpClient.builder()
.transport(transport)
.toolExecutionTimeout(Duration.ofMinutes(5)) // Long-running tools
.resourcesTimeout(Duration.ofSeconds(30)) // Quick resources
.build();try (McpClient client = DefaultMcpClient.builder()
.transport(transport)
.build()) {
// Attempt tool execution
ToolExecutionResult result = client.executeTool(request);
} catch (McpException e) {
// Handle MCP protocol errors
System.err.println("MCP Error Code: " + e.errorCode());
System.err.println("MCP Error Message: " + e.errorMessage());
} catch (IllegalResponseException e) {
// Handle malformed responses
System.err.println("Invalid server response: " + e.getMessage());
} catch (Exception e) {
// Handle other errors (network, timeout, etc.)
System.err.println("Unexpected error: " + e.getMessage());
}Always use authentication for remote servers:
StreamableHttpMcpTransport transport = StreamableHttpMcpTransport.builder()
.url("https://mcp-server.example.com")
.customHeaders(Map.of(
"Authorization", "Bearer " + securelyStoredToken,
"X-API-Key", apiKey
))
.build();For WebSocket and HTTP transports, always use secure connections in production:
// Good: Secure WebSocket
WebSocketMcpTransport transport = WebSocketMcpTransport.builder()
.url("wss://mcp-server.example.com/mcp") // Note: wss:// not ws://
.sslContext(customSslContext)
.build();Restrict available tools to prevent unauthorized operations:
McpToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(client)
.filter((mcpClient, toolSpec) -> {
// Only allow read operations
return toolSpec.name().startsWith("read_") ||
toolSpec.name().startsWith("get_") ||
toolSpec.name().startsWith("list_");
})
.build();client.listTools() returns expected toolsMcpException: Server-reported error, check error code/messageIllegalResponseException: Protocol mismatch, verify MCP server version compatibilityMcpClient: Thread-safe for concurrent operationsMcpToolProvider: Thread-safe for concurrent tool provisioningThe legacy HttpMcpTransport is deprecated. Migrate to StreamableHttpMcpTransport:
// OLD (Deprecated)
HttpMcpTransport oldTransport = HttpMcpTransport.builder()
.sseUrl("https://server.com/sse")
.build();
// NEW (Recommended)
StreamableHttpMcpTransport newTransport = StreamableHttpMcpTransport.builder()
.url("https://server.com/mcp") // Single URL instead of sseUrl
.build();Install with Tessl CLI
npx tessl i tessl/maven-dev-langchain4j--langchain4j-mcp@1.11.0