Model Context Protocol (MCP) Integration

Quarkus LangChain4j supports the Model Context Protocol (MCP) for interacting with MCP-compliant servers that provide and execute tools dynamically.

Quarkus also provides a dedicated extension for building MCP servers. See:

Declarative Tool Provider Generation

Quarkus allows you to configure an MCP-backed ToolProvider declaratively via configuration properties. This provider is automatically used by AI services unless explicitly overridden.

Example configuration:

quarkus.langchain4j.mcp.github.transport-type=stdio
quarkus.langchain4j.mcp.github.command=npm,exec,@modelcontextprotocol/server-github
quarkus.langchain4j.mcp.github.environment.GITHUB_PERSONAL_ACCESS_TOKEN=<YOUR_TOKEN>

This will:

  • Start the MCP server using npm exec @modelcontextprotocol/server-github as a subprocess

  • Provide environment variables to the subprocess

  • Register a ToolProvider under the name github

  • Use this provider for all AI services unless a specific provider is configured

To enable the use of MCP tools in a method of an AI service, annotate it with @McpToolBox:

@McpToolBox("github")
String useGithub(@UserMessage String userMessage);

If no name is provided, all available MCP servers will be used:

@McpToolBox
String useAllMcpServers(@UserMessage String userMessage);

Authorization

If your MCP server uses the Streamable HTTP or HTTP/SSE transport, it may require client authorization using bearer tokens or API keys.

To support this, implement the McpClientAuthProvider interface to inject credentials dynamically:

@ApplicationScoped
public class MyMcpAuthProvider implements McpClientAuthProvider {

    @Override
    public String getAuthorization(Input input) {
        String token = retrieveToken(input);
        return "Bearer " + token;
    }

    private String retrieveToken(Input input) {
        // Logic to extract token from DB, session, etc.
    }
}
The Input object gives you access to the HTTP request context (URI, method, headers).

Propagating OIDC Access Tokens

If your application uses OpenID Connect (OIDC) and the user has authenticated, you can automatically propagate the user’s access token to the MCP server by adding:

<dependency>
    <groupId>io.quarkiverse.langchain4j</groupId>
    <artifactId>quarkus-langchain4j-oidc-mcp-auth-provider</artifactId>
</dependency>

This allows the MCP client to act on behalf of the authenticated user (e.g., when calling GitHub APIs).

Logging

MCP clients configured declaratively in Quarkus support log message observation.

Quarkus replaces the default MCP log handler with one that:

  • Logs messages via the application logger

  • Fires CDI events for each log message

To react to these events:

public void onMcpLog(@Observes @McpClientName("github") McpLogMessage logMessage) {
    // React to log message
}

The McpLogMessage class (dev.langchain4j.mcp.client.logging.McpLogMessage) includes:

  • The log message (JsonNode)

  • Log level

  • Logger name

You can omit @McpClientName if you want to listen to log messages from all clients.

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

Whether the MCP extension should automatically generate a ToolProvider that is wired up to all the configured MCP clients. The default is true if at least one MCP client is configured, false otherwise.

Environment variable: QUARKUS_LANGCHAIN4J_MCP_GENERATE_TOOL_PROVIDER

boolean

true

File containing the MCP servers configuration in the Claude Desktop format. This configuration can only be used to configure stdio transport type MCP servers.

This file is read at build time which means that which MCP servers the client will use, is determined at build time. However, specific configuration of each MCP server can be overridden at runtime.

Environment variable: QUARKUS_LANGCHAIN4J_MCP_CONFIG_FILE

string

Whether the MCP extension should automatically register a health check for configured MCP clients. The default is true if at least one MCP client is configured, false otherwise.

Environment variable: QUARKUS_LANGCHAIN4J_MCP_HEALTH_ENABLED

boolean

true

Configured MCP clients

Type

Default

Transport type

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__TRANSPORT_TYPE

stdio, http, streamable-http

stdio

The URL of the SSE endpoint. This only applies to MCP clients using the HTTP transport.

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__URL

string

The command to execute to spawn the MCP server process. This only applies to MCP clients using the STDIO transport.

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__COMMAND

list of string

Environment variables for the spawned MCP server process. This only applies to MCP clients using the STDIO transport.

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__ENVIRONMENT__ENV_VAR_

Map<String,String>

Whether to log requests

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__LOG_REQUESTS

boolean

false

Whether to log responses

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__LOG_RESPONSES

boolean

false

Timeout for tool executions performed by the MCP client

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__TOOL_EXECUTION_TIMEOUT

Duration 

60S

Timeout for resource-related operations (retrieving a list of resources as well as the actual contents of resources).

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__RESOURCES_TIMEOUT

Duration 

60S

Timeout for pinging the MCP server process to check if it’s still alive. If a ping times out, the client’s health check will start failing.

Environment variable: QUARKUS_LANGCHAIN4J_MCP__CLIENT_NAME__PING_TIMEOUT

Duration 

10S

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.