Skip to content

Commit 3d012ea

Browse files
authored
Merge pull request #1828 from jmartisk/mcp-registry-client
MCP registry client integration
2 parents f60601c + 00c9d10 commit 3d012ea

File tree

10 files changed

+562
-11
lines changed

10 files changed

+562
-11
lines changed

docs/modules/ROOT/pages/includes/quarkus-langchain4j-mcp.adoc

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,137 @@ endif::add-copy-button-to-env-var[]
350350
|
351351

352352

353+
h|[[quarkus-langchain4j-mcp_section_quarkus-langchain4j-mcp-registry-client]] [.section-name.section-level0]##link:#quarkus-langchain4j-mcp_section_quarkus-langchain4j-mcp-registry-client[Configured MCP registry clients]##
354+
h|Type
355+
h|Default
356+
357+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-base-url]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-base-url[`quarkus.langchain4j.mcp.registry-client."registry-client-name".base-url`]##
358+
ifdef::add-copy-button-to-config-props[]
359+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".base-url+++[]
360+
endif::add-copy-button-to-config-props[]
361+
362+
363+
[.description]
364+
--
365+
The base URL of the MCP registry, without the API version segment. The default value points at the official registry (https://registry.modelcontextprotocol.io).
366+
367+
368+
ifdef::add-copy-button-to-env-var[]
369+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__BASE_URL+++[]
370+
endif::add-copy-button-to-env-var[]
371+
ifndef::add-copy-button-to-env-var[]
372+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__BASE_URL+++`
373+
endif::add-copy-button-to-env-var[]
374+
--
375+
|string
376+
|`https://registry.modelcontextprotocol.io`
377+
378+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-requests]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-requests[`quarkus.langchain4j.mcp.registry-client."registry-client-name".log-requests`]##
379+
ifdef::add-copy-button-to-config-props[]
380+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".log-requests+++[]
381+
endif::add-copy-button-to-config-props[]
382+
383+
384+
[.description]
385+
--
386+
Whether to log requests
387+
388+
389+
ifdef::add-copy-button-to-env-var[]
390+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_REQUESTS+++[]
391+
endif::add-copy-button-to-env-var[]
392+
ifndef::add-copy-button-to-env-var[]
393+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_REQUESTS+++`
394+
endif::add-copy-button-to-env-var[]
395+
--
396+
|boolean
397+
|`false`
398+
399+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-responses]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-responses[`quarkus.langchain4j.mcp.registry-client."registry-client-name".log-responses`]##
400+
ifdef::add-copy-button-to-config-props[]
401+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".log-responses+++[]
402+
endif::add-copy-button-to-config-props[]
403+
404+
405+
[.description]
406+
--
407+
Whether to log responses
408+
409+
410+
ifdef::add-copy-button-to-env-var[]
411+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_RESPONSES+++[]
412+
endif::add-copy-button-to-env-var[]
413+
ifndef::add-copy-button-to-env-var[]
414+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_RESPONSES+++`
415+
endif::add-copy-button-to-env-var[]
416+
--
417+
|boolean
418+
|`false`
419+
420+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-tls-configuration-name]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-tls-configuration-name[`quarkus.langchain4j.mcp.registry-client."registry-client-name".tls-configuration-name`]##
421+
ifdef::add-copy-button-to-config-props[]
422+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".tls-configuration-name+++[]
423+
endif::add-copy-button-to-config-props[]
424+
425+
426+
[.description]
427+
--
428+
The name of the TLS configuration (bucket) that this MCP client registry will use.
429+
430+
431+
ifdef::add-copy-button-to-env-var[]
432+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__TLS_CONFIGURATION_NAME+++[]
433+
endif::add-copy-button-to-env-var[]
434+
ifndef::add-copy-button-to-env-var[]
435+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__TLS_CONFIGURATION_NAME+++`
436+
endif::add-copy-button-to-env-var[]
437+
--
438+
|string
439+
|
440+
441+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-read-timeout]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-read-timeout[`quarkus.langchain4j.mcp.registry-client."registry-client-name".read-timeout`]##
442+
ifdef::add-copy-button-to-config-props[]
443+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".read-timeout+++[]
444+
endif::add-copy-button-to-config-props[]
445+
446+
447+
[.description]
448+
--
449+
The read timeout for the MCP registry's underlying http client
450+
451+
452+
ifdef::add-copy-button-to-env-var[]
453+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__READ_TIMEOUT+++[]
454+
endif::add-copy-button-to-env-var[]
455+
ifndef::add-copy-button-to-env-var[]
456+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__READ_TIMEOUT+++`
457+
endif::add-copy-button-to-env-var[]
458+
--
459+
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-langchain4j-mcp_quarkus-langchain4j[icon:question-circle[title=More information about the Duration format]]
460+
|`10s`
461+
462+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-connect-timeout]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-connect-timeout[`quarkus.langchain4j.mcp.registry-client."registry-client-name".connect-timeout`]##
463+
ifdef::add-copy-button-to-config-props[]
464+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".connect-timeout+++[]
465+
endif::add-copy-button-to-config-props[]
466+
467+
468+
[.description]
469+
--
470+
The connect timeout for the MCP registry's underlying http client
471+
472+
473+
ifdef::add-copy-button-to-env-var[]
474+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__CONNECT_TIMEOUT+++[]
475+
endif::add-copy-button-to-env-var[]
476+
ifndef::add-copy-button-to-env-var[]
477+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__CONNECT_TIMEOUT+++`
478+
endif::add-copy-button-to-env-var[]
479+
--
480+
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-langchain4j-mcp_quarkus-langchain4j[icon:question-circle[title=More information about the Duration format]]
481+
|`10s`
482+
483+
353484
|===
354485

355486
ifndef::no-duration-note[]

docs/modules/ROOT/pages/includes/quarkus-langchain4j-mcp_quarkus.langchain4j.adoc

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,137 @@ endif::add-copy-button-to-env-var[]
350350
|
351351

352352

353+
h|[[quarkus-langchain4j-mcp_section_quarkus-langchain4j-mcp-registry-client]] [.section-name.section-level0]##link:#quarkus-langchain4j-mcp_section_quarkus-langchain4j-mcp-registry-client[Configured MCP registry clients]##
354+
h|Type
355+
h|Default
356+
357+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-base-url]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-base-url[`quarkus.langchain4j.mcp.registry-client."registry-client-name".base-url`]##
358+
ifdef::add-copy-button-to-config-props[]
359+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".base-url+++[]
360+
endif::add-copy-button-to-config-props[]
361+
362+
363+
[.description]
364+
--
365+
The base URL of the MCP registry, without the API version segment. The default value points at the official registry (https://registry.modelcontextprotocol.io).
366+
367+
368+
ifdef::add-copy-button-to-env-var[]
369+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__BASE_URL+++[]
370+
endif::add-copy-button-to-env-var[]
371+
ifndef::add-copy-button-to-env-var[]
372+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__BASE_URL+++`
373+
endif::add-copy-button-to-env-var[]
374+
--
375+
|string
376+
|`https://registry.modelcontextprotocol.io`
377+
378+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-requests]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-requests[`quarkus.langchain4j.mcp.registry-client."registry-client-name".log-requests`]##
379+
ifdef::add-copy-button-to-config-props[]
380+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".log-requests+++[]
381+
endif::add-copy-button-to-config-props[]
382+
383+
384+
[.description]
385+
--
386+
Whether to log requests
387+
388+
389+
ifdef::add-copy-button-to-env-var[]
390+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_REQUESTS+++[]
391+
endif::add-copy-button-to-env-var[]
392+
ifndef::add-copy-button-to-env-var[]
393+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_REQUESTS+++`
394+
endif::add-copy-button-to-env-var[]
395+
--
396+
|boolean
397+
|`false`
398+
399+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-responses]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-log-responses[`quarkus.langchain4j.mcp.registry-client."registry-client-name".log-responses`]##
400+
ifdef::add-copy-button-to-config-props[]
401+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".log-responses+++[]
402+
endif::add-copy-button-to-config-props[]
403+
404+
405+
[.description]
406+
--
407+
Whether to log responses
408+
409+
410+
ifdef::add-copy-button-to-env-var[]
411+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_RESPONSES+++[]
412+
endif::add-copy-button-to-env-var[]
413+
ifndef::add-copy-button-to-env-var[]
414+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__LOG_RESPONSES+++`
415+
endif::add-copy-button-to-env-var[]
416+
--
417+
|boolean
418+
|`false`
419+
420+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-tls-configuration-name]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-tls-configuration-name[`quarkus.langchain4j.mcp.registry-client."registry-client-name".tls-configuration-name`]##
421+
ifdef::add-copy-button-to-config-props[]
422+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".tls-configuration-name+++[]
423+
endif::add-copy-button-to-config-props[]
424+
425+
426+
[.description]
427+
--
428+
The name of the TLS configuration (bucket) that this MCP client registry will use.
429+
430+
431+
ifdef::add-copy-button-to-env-var[]
432+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__TLS_CONFIGURATION_NAME+++[]
433+
endif::add-copy-button-to-env-var[]
434+
ifndef::add-copy-button-to-env-var[]
435+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__TLS_CONFIGURATION_NAME+++`
436+
endif::add-copy-button-to-env-var[]
437+
--
438+
|string
439+
|
440+
441+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-read-timeout]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-read-timeout[`quarkus.langchain4j.mcp.registry-client."registry-client-name".read-timeout`]##
442+
ifdef::add-copy-button-to-config-props[]
443+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".read-timeout+++[]
444+
endif::add-copy-button-to-config-props[]
445+
446+
447+
[.description]
448+
--
449+
The read timeout for the MCP registry's underlying http client
450+
451+
452+
ifdef::add-copy-button-to-env-var[]
453+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__READ_TIMEOUT+++[]
454+
endif::add-copy-button-to-env-var[]
455+
ifndef::add-copy-button-to-env-var[]
456+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__READ_TIMEOUT+++`
457+
endif::add-copy-button-to-env-var[]
458+
--
459+
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-langchain4j-mcp_quarkus-langchain4j[icon:question-circle[title=More information about the Duration format]]
460+
|`10s`
461+
462+
a| [[quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-connect-timeout]] [.property-path]##link:#quarkus-langchain4j-mcp_quarkus-langchain4j-mcp-registry-client-registry-client-name-connect-timeout[`quarkus.langchain4j.mcp.registry-client."registry-client-name".connect-timeout`]##
463+
ifdef::add-copy-button-to-config-props[]
464+
config_property_copy_button:+++quarkus.langchain4j.mcp.registry-client."registry-client-name".connect-timeout+++[]
465+
endif::add-copy-button-to-config-props[]
466+
467+
468+
[.description]
469+
--
470+
The connect timeout for the MCP registry's underlying http client
471+
472+
473+
ifdef::add-copy-button-to-env-var[]
474+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__CONNECT_TIMEOUT+++[]
475+
endif::add-copy-button-to-env-var[]
476+
ifndef::add-copy-button-to-env-var[]
477+
Environment variable: `+++QUARKUS_LANGCHAIN4J_MCP_REGISTRY_CLIENT__REGISTRY_CLIENT_NAME__CONNECT_TIMEOUT+++`
478+
endif::add-copy-button-to-env-var[]
479+
--
480+
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-langchain4j-mcp_quarkus-langchain4j[icon:question-circle[title=More information about the Duration format]]
481+
|`10s`
482+
483+
353484
|===
354485

355486
ifndef::no-duration-note[]

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
import com.fasterxml.jackson.databind.ObjectMapper;
2727

2828
import dev.langchain4j.mcp.client.McpClient;
29+
import dev.langchain4j.mcp.registryclient.McpRegistryClient;
2930
import io.opentelemetry.api.trace.Tracer;
3031
import io.quarkiverse.langchain4j.deployment.DotNames;
3132
import io.quarkiverse.langchain4j.mcp.auth.McpClientAuthProvider;
3233
import io.quarkiverse.langchain4j.mcp.runtime.McpClientHealthCheck;
3334
import io.quarkiverse.langchain4j.mcp.runtime.McpClientName;
3435
import io.quarkiverse.langchain4j.mcp.runtime.McpRecorder;
36+
import io.quarkiverse.langchain4j.mcp.runtime.McpRegistryClientName;
3537
import io.quarkiverse.langchain4j.mcp.runtime.config.LocalLaunchParams;
3638
import io.quarkiverse.langchain4j.mcp.runtime.config.McpBuildTimeConfiguration;
3739
import io.quarkiverse.langchain4j.mcp.runtime.config.McpTransportType;
@@ -56,7 +58,9 @@ public class McpProcessor {
5658
private static final Logger log = Logger.getLogger(McpProcessor.class);
5759

5860
private static final DotName MCP_CLIENT = DotName.createSimple(McpClient.class);
61+
private static final DotName MCP_REGISTRY_CLIENT = DotName.createSimple(McpRegistryClient.class);
5962
private static final DotName MCP_CLIENT_NAME = DotName.createSimple(McpClientName.class);
63+
private static final DotName MCP_REGISTRY_CLIENT_NAME = DotName.createSimple(McpRegistryClientName.class);
6064
private static final DotName TRACER = DotName.createSimple(Tracer.class);
6165

6266
@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -177,6 +181,30 @@ public void registerMcpClients(McpBuildTimeConfiguration mcpBuildTimeConfigurati
177181
}
178182
}
179183

184+
@BuildStep
185+
@Record(RUNTIME_INIT)
186+
public void registerRegistryClients(
187+
McpBuildTimeConfiguration mcpBuildTimeConfiguration,
188+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
189+
McpRecorder recorder) {
190+
mcpBuildTimeConfiguration.registryClients().forEach((clientName, x) -> {
191+
AnnotationInstance qualifier = AnnotationInstance.builder(MCP_REGISTRY_CLIENT_NAME)
192+
.add("value", clientName)
193+
.build();
194+
beanProducer.produce(SyntheticBeanBuildItem
195+
.configure(MCP_REGISTRY_CLIENT)
196+
.addQualifier(qualifier)
197+
.defaultBean()
198+
.setRuntimeInit()
199+
.unremovable()
200+
.scope(ApplicationScoped.class)
201+
.supplier(
202+
recorder.mcpRegistryClientSupplier(clientName))
203+
.done());
204+
});
205+
206+
}
207+
180208
@BuildStep
181209
public void indexMcpClientDependency(BuildProducer<IndexDependencyBuildItem> index) {
182210
// this is needed for the 'reflectionRegistrations' build step to work

0 commit comments

Comments
 (0)