CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-dev-langchain4j--langchain4j-mcp

Java implementation of the Model Context Protocol (MCP) client for the LangChain4j framework, enabling integration with MCP servers for tools, resources, and prompts

Overview
Eval results
Files

index.mddocs/

LangChain4j MCP

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.

Quick Start

// 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();

Package Information

  • Package Name: langchain4j-mcp
  • Group ID: dev.langchain4j
  • Artifact ID: langchain4j-mcp
  • Package Type: Maven
  • Language: Java
  • Version: 1.11.0
  • License: Apache-2.0

Installation

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'

Core Imports

// 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;

Architecture Overview

The library is organized into several key modules:

1. Client Layer

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();
}

→ Client Documentation

2. Transport Layer

Multiple transport protocols (stdio, WebSocket, HTTP/SSE) for server communication.

Transport Selection Guide:

  • Stdio → Local executables, subprocess control needed
  • WebSocket → Remote servers, real-time bidirectional communication
  • HTTP → Remote servers, standard web protocols, firewall-friendly
// 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();
}

→ Transport Documentation

3. Tool Provider

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);
}

→ Tool Provider Documentation

4. Data Models

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 {}

→ Data Models Documentation

5. Registry Client

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();
}

→ Registry Documentation

6. Resources as Tools

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

7. Logging and Listeners

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

8. Exception Handling

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);
}

→ Exception Documentation

Configuration

Default Timeouts

OperationDefault Timeout
Initialization30 seconds
Tool execution60 seconds
Resources60 seconds
Prompts60 seconds
Ping10 seconds
Reconnect interval5 seconds
Health check interval30 seconds (when enabled)

Protocol Version

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

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();

Common Usage Patterns

Pattern 1: Multiple MCP Servers

// 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();

Pattern 2: Tool Filtering

// 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_")
);

Pattern 3: Dynamic Headers with Authentication

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();

Pattern 4: Health Monitoring

// 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());
}

Pattern 5: Resource Cleanup

Always close clients when done:

try (McpClient client = DefaultMcpClient.builder()
        .transport(transport)
        .build()) {

    // Use the client
    List<ToolSpecification> tools = client.listTools();

} // Automatically closed

Complete Example

import 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();
    }
}

Performance Considerations

Caching

  • Tool list caching: Enabled by default, reduces server roundtrips
  • Eviction: Call evictToolListCache() when server capabilities change

Connection Pooling

For 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();

Timeouts

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();

Error Handling Best Practices

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());
}

Security Considerations

Authentication

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();

SSL/TLS

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();

Tool Filtering

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();

Troubleshooting

Connection Fails

  • Stdio: Verify command path and permissions
  • WebSocket: Check URL, firewall, and proxy settings
  • HTTP: Verify URL accessibility and authentication

Tools Not Available

  1. Check client.listTools() returns expected tools
  2. Verify tool filtering isn't excluding tools
  3. Check MCP server is running and healthy

Performance Issues

  1. Enable tool list caching (default)
  2. Adjust timeouts for long-running operations
  3. Consider connection pooling for HTTP transport
  4. Monitor health checks frequency

Response Errors

  • McpException: Server-reported error, check error code/message
  • IllegalResponseException: Protocol mismatch, verify MCP server version compatibility

Thread Safety

  • McpClient: Thread-safe for concurrent operations
  • McpToolProvider: Thread-safe for concurrent tool provisioning
  • Transport implementations: Check specific transport documentation

Migration Notes

From HttpMcpTransport to StreamableHttpMcpTransport

The 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();

Further Reading

Install with Tessl CLI

npx tessl i tessl/maven-dev-langchain4j--langchain4j-mcp@1.11.0

docs

client.md

data-models.md

exceptions.md

index.md

logging-listeners.md

registry.md

resources-as-tools.md

tool-provider.md

transports.md

tile.json