Quarkus extension for integrating Model Context Protocol (MCP) client capabilities with LangChain4j
A Quarkus extension that enables comprehensive Model Context Protocol (MCP) client support for LangChain4j applications. MCP is an open standard that allows AI applications to seamlessly integrate with external data sources, tools, and services, enabling dynamic discovery and execution of tools provided by MCP-compliant servers at runtime.
io.quarkiverse.langchain4j:quarkus-langchain4j-mcppom.xml:<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-mcp</artifactId>
<version>1.7.4</version>
</dependency>import io.quarkiverse.langchain4j.mcp.runtime.McpToolBox;
import io.quarkiverse.langchain4j.mcp.runtime.McpClientName;
import io.quarkiverse.langchain4j.mcp.auth.McpClientAuthProvider;
import io.quarkiverse.langchain4j.RegisterAiService;
import jakarta.inject.Inject;import io.quarkiverse.langchain4j.RegisterAiService;
import io.quarkiverse.langchain4j.mcp.runtime.McpToolBox;
import dev.langchain4j.service.UserMessage;
@RegisterAiService
public interface FileAssistant {
// Enable tools from the "filesystem" MCP server
@McpToolBox("filesystem")
String chat(@UserMessage String message);
}Configuration for STDIO transport (spawns local MCP server):
quarkus.langchain4j.mcp.filesystem.transport-type=stdio
quarkus.langchain4j.mcp.filesystem.command=npm,exec,@modelcontextprotocol/server-filesystem,/path/to/directory@RegisterAiService
public interface MultiSystemAssistant {
// Use tools from both "github" and "filesystem" servers
@McpToolBox({"github", "filesystem"})
String collaborate(@UserMessage String userMessage);
// Use tools from all configured MCP servers
@McpToolBox
String useAllTools(@UserMessage String userMessage);
}import dev.langchain4j.mcp.client.McpClient;
import io.quarkiverse.langchain4j.mcp.runtime.McpClientName;
import jakarta.inject.Inject;
@ApplicationScoped
public class McpService {
@Inject
@McpClientName("github")
McpClient githubClient;
public void listTools() {
var tools = githubClient.listTools();
// Work with tools directly
}
}import dev.langchain4j.mcp.client.registry.McpRegistryClient;
import io.quarkiverse.langchain4j.mcp.runtime.McpRegistryClientName;
import jakarta.inject.Inject;
@ApplicationScoped
public class ServerDiscovery {
@Inject
@McpRegistryClientName("default")
McpRegistryClient registryClient;
public void discoverServers() {
var servers = registryClient.listServers();
// Explore available MCP servers from registry
}
}The extension provides a layered architecture:
@McpToolBox, @McpClientName for declarative MCP integrationEnable MCP tools in LangChain4j AI services using declarative annotations. Control which MCP servers provide tools to specific AI service methods.
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface McpToolBox {
String[] value() default {};
}Build-time and runtime configuration for MCP clients, including transport types, timeouts, logging, and health checks.
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
@ConfigMapping(prefix = "quarkus.langchain4j.mcp")
public interface McpRuntimeConfiguration {
Map<String, McpClientRuntimeConfig> clients();
Map<String, McpRegistryClientRuntimeConfig> registryClients();
Optional<Boolean> exposeResourcesAsTools();
}@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
@ConfigMapping(prefix = "quarkus.langchain4j.mcp")
public interface McpBuildTimeConfiguration {
Map<String, McpClientBuildTimeConfig> clients();
Map<String, Map<String, String>> registryClients();
Optional<Boolean> generateToolProvider();
Optional<String> configFile();
boolean mpHealthEnabled();
}Support for multiple MCP transport types: STDIO (local subprocess), HTTP with SSE, Streamable HTTP (recommended), and WebSocket.
public enum McpTransportType {
STDIO,
HTTP,
STREAMABLE_HTTP,
WEBSOCKET
}Pluggable authentication provider interface for supplying credentials to MCP servers, with support for client-specific and global providers.
public interface McpClientAuthProvider {
String getAuthorization(Input input);
interface Input {
String method();
URI uri();
Map<String, List<Object>> headers();
}
static Optional<McpClientAuthProvider> resolve(String mcpClientName) { ... }
}Health checks, Micrometer metrics, request/response logging, OpenTelemetry tracing, and CDI events for MCP server logs.
public class McpClientHealthCheck implements HealthCheck {
public HealthCheckResponse call() { ... }
}public class MetricsMcpListener implements McpClientListener {
// Metrics: mcp.client.tool.call.duration
// mcp.client.resource.get.duration
// mcp.client.prompt.get.duration
}Quarkus Dev UI integration for interactive tool testing, exploration, and execution with example parameters.
public class McpClientsJsonRpcService {
List<McpClientInfo> clientInfos();
String executeTool(String clientName, String toolName, String arguments);
}Access to the official Model Context Protocol registry for discovering available MCP servers programmatically.
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RUNTIME)
@Qualifier
public @interface McpRegistryClientName {
String value();
}// CDI qualifier for MCP client injection
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RUNTIME)
@Qualifier
@Repeatable(McpClientNames.class)
public @interface McpClientName {
String value();
}
// Nested literal class for programmatic annotation creation
class Literal extends AnnotationLiteral<McpClientName> implements McpClientName {
public static Literal of(String value) { ... }
String value();
}// Container for multiple @McpClientName annotations
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RUNTIME)
@Qualifier
public @interface McpClientNames {
McpClientName[] value();
}
// Nested literal class for programmatic annotation creation
class Literal extends AnnotationLiteral<McpClientNames> implements McpClientNames {
public static Literal of(McpClientName... names) { ... }
McpClientName[] value();
}// CDI qualifier for MCP registry client injection
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RUNTIME)
@Qualifier
public @interface McpRegistryClientName {
String value();
}
// Nested literal class for programmatic annotation creation
class Literal extends AnnotationLiteral<McpRegistryClientName> implements McpRegistryClientName {
public static Literal of(String value) { ... }
String value();
}// Launch parameters for local MCP servers (STDIO)
public record LocalLaunchParams(
List<String> command,
Map<String, String> envVars
) {}quarkus.langchain4j.mcp.filesystem.transport-type=stdio
quarkus.langchain4j.mcp.filesystem.command=npm,exec,@modelcontextprotocol/server-filesystem,/path/to/dir
quarkus.langchain4j.mcp.filesystem.environment.NODE_ENV=productionquarkus.langchain4j.mcp.remote.transport-type=streamable-http
quarkus.langchain4j.mcp.remote.url=https://mcp-server.example.com/mcp
quarkus.langchain4j.mcp.remote.tool-execution-timeout=30squarkus.langchain4j.mcp.api.transport-type=http
quarkus.langchain4j.mcp.api.url=https://api.example.com/mcp/ssequarkus.langchain4j.mcp.ws.transport-type=websocket
quarkus.langchain4j.mcp.ws.url=ws://localhost:8080/mcp# Static headers
quarkus.langchain4j.mcp.github.header.X-API-Key=your-api-keyquarkus.langchain4j.mcp.github.tool-execution-timeout=60s
quarkus.langchain4j.mcp.github.resources-timeout=60s
quarkus.langchain4j.mcp.github.ping-timeout=10squarkus.langchain4j.mcp.github.log-requests=true
quarkus.langchain4j.mcp.github.log-responses=truequarkus.langchain4j.mcp.github.metrics-enabled=truequarkus.langchain4j.mcp.expose-resources-as-tools=truequarkus.langchain4j.mcp.registry-client.default.base-url=https://registry.modelcontextprotocol.io
quarkus.langchain4j.mcp.registry-client.default.read-timeout=10sInstall with Tessl CLI
npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-mcp@1.7.0