Skip to content

Commit 4f6440f

Browse files
geoandjmartisk
authored andcommitted
Move MCP URL and command to runtime config
1 parent cb61158 commit 4f6440f

File tree

6 files changed

+70
-31
lines changed

6 files changed

+70
-31
lines changed

mcp/deployment/src/main/java/io/quarkiverse/langchain4j/mcp/deployment/McpProcessor.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
import dev.langchain4j.service.tool.ToolProvider;
1616
import io.quarkiverse.langchain4j.mcp.runtime.McpClientName;
1717
import io.quarkiverse.langchain4j.mcp.runtime.McpRecorder;
18-
import io.quarkiverse.langchain4j.mcp.runtime.config.McpClientConfig;
19-
import io.quarkiverse.langchain4j.mcp.runtime.config.McpConfiguration;
18+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpBuildTimeConfiguration;
19+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpClientBuildTimeConfig;
20+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpRuntimeConfiguration;
2021
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
2122
import io.quarkus.deployment.annotations.BuildProducer;
2223
import io.quarkus.deployment.annotations.BuildStep;
@@ -31,13 +32,14 @@ public class McpProcessor {
3132

3233
@BuildStep
3334
@Record(ExecutionTime.RUNTIME_INIT)
34-
public void registerMcpClients(McpConfiguration mcpConfiguration,
35+
public void registerMcpClients(McpBuildTimeConfiguration mcpBuildTimeConfiguration,
36+
McpRuntimeConfiguration mcpRuntimeConfiguration,
3537
BuildProducer<SyntheticBeanBuildItem> beanProducer,
3638
McpRecorder recorder) {
37-
if (mcpConfiguration.clients() != null && !mcpConfiguration.clients().isEmpty()) {
39+
if (mcpBuildTimeConfiguration.clients() != null && !mcpBuildTimeConfiguration.clients().isEmpty()) {
3840
// generate MCP clients
3941
List<AnnotationInstance> qualifiers = new ArrayList<>();
40-
for (Map.Entry<String, McpClientConfig> client : mcpConfiguration.clients()
42+
for (Map.Entry<String, McpClientBuildTimeConfig> client : mcpBuildTimeConfiguration.clients()
4143
.entrySet()) {
4244
AnnotationInstance qualifier = AnnotationInstance.builder(MCP_CLIENT_NAME)
4345
.add("value", client.getKey())
@@ -51,12 +53,13 @@ public void registerMcpClients(McpConfiguration mcpConfiguration,
5153
.unremovable()
5254
// TODO: should we allow other scopes?
5355
.scope(ApplicationScoped.class)
54-
.supplier(recorder.mcpClientSupplier(client.getKey(), mcpConfiguration))
56+
.supplier(
57+
recorder.mcpClientSupplier(client.getKey(), mcpBuildTimeConfiguration, mcpRuntimeConfiguration))
5558
.done());
5659
}
5760
// generate a tool provider if configured to do so
58-
if (mcpConfiguration.generateToolProvider().orElse(true)) {
59-
Set<String> mcpClientNames = mcpConfiguration.clients().keySet();
61+
if (mcpBuildTimeConfiguration.generateToolProvider().orElse(true)) {
62+
Set<String> mcpClientNames = mcpBuildTimeConfiguration.clients().keySet();
6063
SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem
6164
.configure(TOOL_PROVIDER)
6265
.addType(ClassType.create(TOOL_PROVIDER))

mcp/runtime/src/main/java/io/quarkiverse/langchain4j/mcp/runtime/McpRecorder.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import dev.langchain4j.mcp.client.transport.McpTransport;
1313
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
1414
import dev.langchain4j.service.tool.ToolProvider;
15-
import io.quarkiverse.langchain4j.mcp.runtime.config.McpClientConfig;
16-
import io.quarkiverse.langchain4j.mcp.runtime.config.McpConfiguration;
15+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpBuildTimeConfiguration;
16+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpClientBuildTimeConfig;
17+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpClientRuntimeConfig;
18+
import io.quarkiverse.langchain4j.mcp.runtime.config.McpRuntimeConfiguration;
1719
import io.quarkiverse.langchain4j.mcp.runtime.http.QuarkusHttpMcpTransport;
1820
import io.quarkus.arc.SyntheticCreationalContext;
1921
import io.quarkus.runtime.annotations.Recorder;
@@ -22,37 +24,39 @@
2224
@Recorder
2325
public class McpRecorder {
2426

25-
public Supplier<McpClient> mcpClientSupplier(String key, McpConfiguration configuration) {
27+
public Supplier<McpClient> mcpClientSupplier(String key, McpBuildTimeConfiguration buildTimeConfiguration,
28+
McpRuntimeConfiguration mcpRuntimeConfiguration) {
2629
return new Supplier<McpClient>() {
2730
@Override
2831
public McpClient get() {
2932
McpTransport transport = null;
30-
McpClientConfig config = configuration.clients().get(key);
31-
switch (config.transportType()) {
33+
McpClientBuildTimeConfig buildTimeConfig = buildTimeConfiguration.clients().get(key);
34+
McpClientRuntimeConfig runtimeConfig = mcpRuntimeConfiguration.clients().get(key);
35+
switch (buildTimeConfig.transportType()) {
3236
case STDIO:
33-
List<String> command = config.command().orElseThrow(() -> new ConfigurationException(
37+
List<String> command = runtimeConfig.command().orElseThrow(() -> new ConfigurationException(
3438
"MCP client configuration named " + key + " is missing the 'command' property"));
3539
transport = new StdioMcpTransport.Builder()
3640
.command(command)
37-
.logEvents(config.logResponses().orElse(false))
38-
.environment(config.environment())
41+
.logEvents(runtimeConfig.logResponses().orElse(false))
42+
.environment(runtimeConfig.environment())
3943
.build();
4044
break;
4145
case HTTP:
4246
transport = new QuarkusHttpMcpTransport.Builder()
43-
.sseUrl(config.url().orElseThrow(() -> new ConfigurationException(
47+
.sseUrl(runtimeConfig.url().orElseThrow(() -> new ConfigurationException(
4448
"MCP client configuration named " + key + " is missing the 'url' property")))
45-
.logRequests(config.logRequests().orElse(false))
46-
.logResponses(config.logResponses().orElse(false))
49+
.logRequests(runtimeConfig.logRequests().orElse(false))
50+
.logResponses(runtimeConfig.logResponses().orElse(false))
4751
.build();
4852
break;
4953
default:
50-
throw new IllegalArgumentException("Unknown transport type: " + config.transportType());
54+
throw new IllegalArgumentException("Unknown transport type: " + buildTimeConfig.transportType());
5155
}
5256
return new DefaultMcpClient.Builder()
5357
.transport(transport)
54-
.toolExecutionTimeout(config.toolExecutionTimeout())
55-
.resourcesTimeout(config.resourcesTimeout())
58+
.toolExecutionTimeout(runtimeConfig.toolExecutionTimeout())
59+
.resourcesTimeout(runtimeConfig.resourcesTimeout())
5660
// TODO: it should be possible to choose a log handler class via configuration
5761
.logHandler(new QuarkusDefaultMcpLogHandler(key))
5862
.build();

mcp/runtime/src/main/java/io/quarkiverse/langchain4j/mcp/runtime/config/McpConfiguration.java renamed to mcp/runtime/src/main/java/io/quarkiverse/langchain4j/mcp/runtime/config/McpBuildTimeConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
1515
@ConfigMapping(prefix = "quarkus.langchain4j.mcp")
16-
public interface McpConfiguration {
16+
public interface McpBuildTimeConfiguration {
1717

1818
/**
1919
* Configured MCP clients
2020
*/
2121
@ConfigDocSection
2222
@ConfigDocMapKey("client-name")
2323
@WithParentName
24-
Map<String, McpClientConfig> clients();
24+
Map<String, McpClientBuildTimeConfig> clients();
2525

2626
/**
2727
* Whether the MCP extension should automatically generate a ToolProvider that
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.quarkiverse.langchain4j.mcp.runtime.config;
2+
3+
import io.quarkus.runtime.annotations.ConfigGroup;
4+
import io.smallrye.config.WithDefault;
5+
6+
@ConfigGroup
7+
public interface McpClientBuildTimeConfig {
8+
9+
/**
10+
* Transport type
11+
*/
12+
@WithDefault("stdio")
13+
McpTransportType transportType();
14+
}

mcp/runtime/src/main/java/io/quarkiverse/langchain4j/mcp/runtime/config/McpClientConfig.java renamed to mcp/runtime/src/main/java/io/quarkiverse/langchain4j/mcp/runtime/config/McpClientRuntimeConfig.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,7 @@
1111
import io.smallrye.config.WithDefault;
1212

1313
@ConfigGroup
14-
public interface McpClientConfig {
15-
16-
/**
17-
* Transport type
18-
*/
19-
@WithDefault("stdio")
20-
McpTransportType transportType();
14+
public interface McpClientRuntimeConfig {
2115

2216
/**
2317
* The URL of the SSE endpoint. This only applies to MCP clients using the HTTP transport.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.quarkiverse.langchain4j.mcp.runtime.config;
2+
3+
import java.util.Map;
4+
5+
import io.quarkus.runtime.annotations.ConfigDocMapKey;
6+
import io.quarkus.runtime.annotations.ConfigDocSection;
7+
import io.quarkus.runtime.annotations.ConfigPhase;
8+
import io.quarkus.runtime.annotations.ConfigRoot;
9+
import io.smallrye.config.ConfigMapping;
10+
import io.smallrye.config.WithParentName;
11+
12+
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
13+
@ConfigMapping(prefix = "quarkus.langchain4j.mcp")
14+
public interface McpRuntimeConfiguration {
15+
16+
/**
17+
* Configured MCP clients
18+
*/
19+
@ConfigDocSection
20+
@ConfigDocMapKey("client-name")
21+
@WithParentName
22+
Map<String, McpClientRuntimeConfig> clients();
23+
24+
}

0 commit comments

Comments
 (0)