This is an automated email from the ASF dual-hosted git repository.

fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new df6ee42c664e CAMEL-16861: Add MCP client support to 
camel-langchain4j-agent
df6ee42c664e is described below

commit df6ee42c664e28db2b913d4f5de2ce799c3907c3
Author: Croway <[email protected]>
AuthorDate: Tue Feb 24 19:01:57 2026 +0100

    CAMEL-16861: Add MCP client support to camel-langchain4j-agent
---
 .../catalog/components/langchain4j-agent.json      |  12 +-
 .../langchain4j/agent/api/AbstractAgent.java       |  15 +-
 .../agent/api/CompositeToolProvider.java           |  57 ++++
 .../component/langchain4j/agent/api/Headers.java   |   8 +
 .../agent/api/CompositeToolProviderTest.java       | 148 +++++++++
 .../camel-ai/camel-langchain4j-agent/pom.xml       |  11 +
 .../agent/LangChain4jAgentComponentConfigurer.java |  23 ++
 .../LangChain4jAgentConfigurationConfigurer.java   |  23 ++
 .../agent/LangChain4jAgentEndpointConfigurer.java  |  23 ++
 .../agent/LangChain4jAgentEndpointUriFactory.java  |   8 +-
 .../langchain4j/agent/langchain4j-agent.json       |  12 +-
 .../src/main/docs/langchain4j-agent-component.adoc |  91 +++++-
 .../agent/LangChain4jAgentConfiguration.java       |  53 ++++
 .../agent/LangChain4jAgentProducer.java            | 212 ++++++++++++-
 .../agent/LangChain4jMcpServerDefinition.java      | 238 +++++++++++++++
 .../LangChain4jAgentMcpAndCamelToolsIT.java        | 330 +++++++++++++++++++++
 .../src/test/resources/log4j2.properties           |  30 ++
 .../Langchain4jAgentComponentBuilderFactory.java   |  40 +++
 .../LangChain4jAgentEndpointBuilderFactory.java    | 106 +++++++
 test-infra/camel-test-infra-mcp-everything/pom.xml |  53 ++++
 .../everything/common/McpEverythingProperties.java |  28 ++
 .../services/McpEverythingInfraService.java        |  36 +++
 .../McpEverythingLocalContainerInfraService.java   | 121 ++++++++
 .../everything/services/McpEverythingService.java  |  26 ++
 .../services/McpEverythingServiceFactory.java      |  39 +++
 .../mcp/everything/services/container.properties   |  18 ++
 test-infra/pom.xml                                 |   1 +
 27 files changed, 1735 insertions(+), 27 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
index 28dd67fe2a67..593d99e60555 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
@@ -29,19 +29,25 @@
     "configuration": { "index": 2, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
configuration" },
     "lazyStartProducer": { "index": 3, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "tags": { "index": 4, "kind": "property", "displayName": "Tags", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Tags for discovering and 
calling Camel route tools" },
-    "autowiredEnabled": { "index": 5, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 5, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "mcpClients": { "index": 6, "kind": "property", "displayName": "Mcp 
Clients", "group": "advanced", "label": "advanced", "required": false, "type": 
"array", "javaType": "java.util.List<dev.langchain4j.mcp.client.McpClient>", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Pre-built MCP (Model 
Context Protocol) client insta [...]
+    "mcpServer": { "index": 7, "kind": "property", "displayName": "Mcp 
Server", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", 
"prefix": "mcpServer.", "multiValue": true, "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "MCP server  [...]
   },
   "headers": {
     "CamelLangChain4jAgentSystemMessage": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The system prompt.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#SYSTEM_MESSAGE" },
     "CamelLangChain4jAgentMemoryId": { "index": 1, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Memory ID.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEMORY_ID" },
     "CamelLangChain4jAgentUserMessage": { "index": 2, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The user message to accompany file 
content when using WrappedFile as input.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#USER_MESSAGE" },
-    "CamelLangChain4jAgentMediaType": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The media type (MIME type) of the file 
content. Overrides auto-detection from file extension.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEDIA_TYPE" }
+    "CamelLangChain4jAgentMediaType": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The media type (MIME type) of the file 
content. Overrides auto-detection from file extension.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEDIA_TYPE" },
+    "CamelLangChain4jAgentExcludeTags": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated list of Camel tool tags 
to exclude from this agent invocation.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#EXCLUDE_TAGS" },
+    "CamelLangChain4jAgentExcludeMcpServers": { "index": 5, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated list of MCP server 
names (keys) to exclude from this agent invocation.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#EXCLUDE_MCP_SERVERS" }
   },
   "properties": {
     "agentId": { "index": 0, "kind": "path", "displayName": "Agent Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Agent id" },
     "agent": { "index": 1, "kind": "parameter", "displayName": "Agent", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.langchain4j.agent.api.Agent", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent to use for the 
component" },
     "agentFactory": { "index": 2, "kind": "parameter", "displayName": "Agent 
Factory", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": 
"org.apache.camel.component.langchain4j.agent.api.AgentFactory", "deprecated": 
false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent factory to u 
[...]
     "tags": { "index": 3, "kind": "parameter", "displayName": "Tags", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Tags for discovering and 
calling Camel route tools" },
-    "lazyStartProducer": { "index": 4, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "lazyStartProducer": { "index": 4, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "mcpClients": { "index": 5, "kind": "parameter", "displayName": "Mcp 
Clients", "group": "advanced", "label": "advanced", "required": false, "type": 
"array", "javaType": "java.util.List<dev.langchain4j.mcp.client.McpClient>", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Pre-built MCP (Model 
Context Protocol) client inst [...]
+    "mcpServer": { "index": 6, "kind": "parameter", "displayName": "Mcp 
Server", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", 
"prefix": "mcpServer.", "multiValue": true, "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "MCP server [...]
   }
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/AbstractAgent.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/AbstractAgent.java
index f7a19d62973b..4334011cab94 100644
--- 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/AbstractAgent.java
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/AbstractAgent.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.langchain4j.agent.api;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import dev.langchain4j.mcp.McpToolProvider;
@@ -77,9 +78,12 @@ public abstract class AbstractAgent<S> implements Agent {
      */
     @SuppressWarnings("unchecked")
     protected void configureBuilder(AiServices<S> builder, ToolProvider 
toolProvider) {
+        // Collect all tool providers to compose them into a single provider
+        List<ToolProvider> toolProviders = new ArrayList<>();
+
         // Apache Camel Tool Provider
         if (toolProvider != null) {
-            builder.toolProvider(toolProvider);
+            toolProviders.add(toolProvider);
         }
 
         // MCP Clients - create MCP ToolProvider if MCP clients are configured
@@ -92,7 +96,14 @@ public abstract class AbstractAgent<S> implements Agent {
                 mcpBuilder.filter(configuration.getMcpToolProviderFilter());
             }
 
-            builder.toolProvider(mcpBuilder.build());
+            toolProviders.add(mcpBuilder.build());
+        }
+
+        // Set the composed tool provider (single or composite)
+        if (toolProviders.size() == 1) {
+            builder.toolProvider(toolProviders.get(0));
+        } else if (toolProviders.size() > 1) {
+            builder.toolProvider(new CompositeToolProvider(toolProviders));
         }
 
         // Additional custom LangChain4j Tool Instances (objects with @Tool 
methods)
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProvider.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProvider.java
new file mode 100644
index 000000000000..da50c9c4c3a6
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.langchain4j.agent.api;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import dev.langchain4j.service.tool.ToolProvider;
+import dev.langchain4j.service.tool.ToolProviderRequest;
+import dev.langchain4j.service.tool.ToolProviderResult;
+
+/**
+ * A composite {@link ToolProvider} that aggregates tools from multiple 
underlying {@link ToolProvider} instances.
+ *
+ * <p>
+ * This class enables the coexistence of different tool sources (e.g., Camel 
route tools and MCP tools) within a single
+ * AI agent. When {@link #provideTools(ToolProviderRequest)} is called, it 
delegates to each underlying provider and
+ * merges all returned tools into a single {@link ToolProviderResult}.
+ * </p>
+ *
+ * @since 4.19.0
+ */
+public class CompositeToolProvider implements ToolProvider {
+
+    private final List<ToolProvider> providers;
+
+    public CompositeToolProvider(List<ToolProvider> providers) {
+        this.providers = new ArrayList<>(providers);
+    }
+
+    @Override
+    public ToolProviderResult provideTools(ToolProviderRequest request) {
+        ToolProviderResult.Builder resultBuilder = 
ToolProviderResult.builder();
+
+        for (ToolProvider provider : providers) {
+            ToolProviderResult result = provider.provideTools(request);
+            result.tools().forEach(resultBuilder::add);
+            
resultBuilder.immediateReturnToolNames(result.immediateReturnToolNames());
+        }
+
+        return resultBuilder.build();
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
index c6a56b3a26df..a68606da9674 100644
--- 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
@@ -35,4 +35,12 @@ public class Headers {
     @Metadata(description = "The media type (MIME type) of the file content. 
Overrides auto-detection from file extension.",
               javaType = "String")
     public static final String MEDIA_TYPE = "CamelLangChain4jAgentMediaType";
+
+    @Metadata(description = "Comma-separated list of Camel tool tags to 
exclude from this agent invocation.",
+              javaType = "String")
+    public static final String EXCLUDE_TAGS = 
"CamelLangChain4jAgentExcludeTags";
+
+    @Metadata(description = "Comma-separated list of MCP server names (keys) 
to exclude from this agent invocation.",
+              javaType = "String")
+    public static final String EXCLUDE_MCP_SERVERS = 
"CamelLangChain4jAgentExcludeMcpServers";
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/test/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProviderTest.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/test/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProviderTest.java
new file mode 100644
index 000000000000..907247077c3f
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/test/java/org/apache/camel/component/langchain4j/agent/api/CompositeToolProviderTest.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.langchain4j.agent.api;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import dev.langchain4j.agent.tool.ToolSpecification;
+import dev.langchain4j.data.message.UserMessage;
+import dev.langchain4j.service.tool.ToolExecutor;
+import dev.langchain4j.service.tool.ToolProvider;
+import dev.langchain4j.service.tool.ToolProviderRequest;
+import dev.langchain4j.service.tool.ToolProviderResult;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class CompositeToolProviderTest {
+
+    private static final ToolExecutor NOOP_EXECUTOR = (request, memoryId) -> 
"ok";
+    private static final ToolProviderRequest DUMMY_REQUEST = new 
ToolProviderRequest("test", UserMessage.from("test"));
+
+    @Test
+    public void testSingleProvider() {
+        ToolSpecification spec = 
ToolSpecification.builder().name("tool1").description("A tool").build();
+
+        ToolProvider provider = request -> ToolProviderResult.builder()
+                .add(spec, NOOP_EXECUTOR)
+                .build();
+
+        CompositeToolProvider composite = new 
CompositeToolProvider(List.of(provider));
+        ToolProviderResult result = composite.provideTools(DUMMY_REQUEST);
+
+        assertNotNull(result);
+        assertEquals(1, result.tools().size());
+        assertTrue(result.tools().containsKey(spec));
+    }
+
+    @Test
+    public void testMultipleProviders() {
+        ToolSpecification spec1 = 
ToolSpecification.builder().name("tool1").description("Tool 1").build();
+        ToolSpecification spec2 = 
ToolSpecification.builder().name("tool2").description("Tool 2").build();
+
+        ToolProvider provider1 = request -> ToolProviderResult.builder()
+                .add(spec1, NOOP_EXECUTOR)
+                .build();
+
+        ToolProvider provider2 = request -> ToolProviderResult.builder()
+                .add(spec2, NOOP_EXECUTOR)
+                .build();
+
+        CompositeToolProvider composite = new 
CompositeToolProvider(List.of(provider1, provider2));
+        ToolProviderResult result = composite.provideTools(DUMMY_REQUEST);
+
+        assertNotNull(result);
+        assertEquals(2, result.tools().size());
+        assertTrue(result.tools().containsKey(spec1));
+        assertTrue(result.tools().containsKey(spec2));
+    }
+
+    @Test
+    public void testEmptyProviderList() {
+        CompositeToolProvider composite = new 
CompositeToolProvider(Collections.emptyList());
+        ToolProviderResult result = composite.provideTools(DUMMY_REQUEST);
+
+        assertNotNull(result);
+        assertTrue(result.tools().isEmpty());
+    }
+
+    @Test
+    public void testDuplicateToolNamesThrows() {
+        ToolSpecification spec1 = 
ToolSpecification.builder().name("sameName").description("Tool 1").build();
+        ToolSpecification spec2 = 
ToolSpecification.builder().name("sameName").description("Tool 2").build();
+
+        ToolProvider provider1 = request -> ToolProviderResult.builder()
+                .add(spec1, NOOP_EXECUTOR)
+                .build();
+
+        ToolProvider provider2 = request -> ToolProviderResult.builder()
+                .add(spec2, NOOP_EXECUTOR)
+                .build();
+
+        CompositeToolProvider composite = new 
CompositeToolProvider(List.of(provider1, provider2));
+
+        // LangChain4j ToolProviderResult.Builder throws on duplicate names
+        assertThrows(Exception.class, () -> 
composite.provideTools(DUMMY_REQUEST));
+    }
+
+    @Test
+    public void testImmediateReturnToolNamesMerged() {
+        ToolSpecification spec1 = 
ToolSpecification.builder().name("tool1").description("Tool 1").build();
+        ToolSpecification spec2 = 
ToolSpecification.builder().name("tool2").description("Tool 2").build();
+
+        ToolProvider provider1 = request -> ToolProviderResult.builder()
+                .add(spec1, NOOP_EXECUTOR)
+                .immediateReturnToolNames(Set.of("tool1"))
+                .build();
+
+        ToolProvider provider2 = request -> ToolProviderResult.builder()
+                .add(spec2, NOOP_EXECUTOR)
+                .immediateReturnToolNames(Set.of("tool2"))
+                .build();
+
+        CompositeToolProvider composite = new 
CompositeToolProvider(List.of(provider1, provider2));
+        ToolProviderResult result = composite.provideTools(DUMMY_REQUEST);
+
+        assertNotNull(result);
+        assertEquals(2, result.tools().size());
+        assertTrue(result.immediateReturnToolNames().contains("tool1"));
+        assertTrue(result.immediateReturnToolNames().contains("tool2"));
+    }
+
+    @Test
+    public void testProviderWithNoTools() {
+        ToolSpecification spec1 = 
ToolSpecification.builder().name("tool1").description("Tool 1").build();
+
+        ToolProvider provider1 = request -> ToolProviderResult.builder()
+                .add(spec1, NOOP_EXECUTOR)
+                .build();
+
+        ToolProvider emptyProvider = request -> 
ToolProviderResult.builder().build();
+
+        CompositeToolProvider composite = new 
CompositeToolProvider(List.of(provider1, emptyProvider));
+        ToolProviderResult result = composite.provideTools(DUMMY_REQUEST);
+
+        assertNotNull(result);
+        assertEquals(1, result.tools().size());
+        assertTrue(result.tools().containsKey(spec1));
+    }
+}
diff --git a/components/camel-ai/camel-langchain4j-agent/pom.xml 
b/components/camel-ai/camel-langchain4j-agent/pom.xml
index 35ca9854931f..947f894048b9 100644
--- a/components/camel-ai/camel-langchain4j-agent/pom.xml
+++ b/components/camel-ai/camel-langchain4j-agent/pom.xml
@@ -55,6 +55,11 @@
       <artifactId>langchain4j</artifactId>
       <version>${langchain4j-version}</version>
     </dependency>
+    <dependency>
+      <groupId>dev.langchain4j</groupId>
+      <artifactId>langchain4j-mcp</artifactId>
+      <version>${langchain4j-beta-version}</version>
+    </dependency>
     <dependency>
       <groupId>org.apache.camel</groupId>
       <artifactId>camel-langchain4j-tools</artifactId>
@@ -109,6 +114,12 @@
           <version>${project.version}</version>
           <scope>test</scope>
       </dependency>
+      <dependency>
+          <groupId>org.apache.camel</groupId>
+          <artifactId>camel-test-infra-mcp-everything</artifactId>
+          <version>${project.version}</version>
+          <scope>test</scope>
+      </dependency>
   </dependencies>
 
 </project>
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentComponentConfigurer.java
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentComponentConfigurer.java
index 319f695178b3..35edb4062ab1 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentComponentConfigurer.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentComponentConfigurer.java
@@ -38,6 +38,10 @@ public class LangChain4jAgentComponentConfigurer extends 
PropertyConfigurerSuppo
         case "configuration": target.setConfiguration(property(camelContext, 
org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration.class,
 value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "mcpclients":
+        case "mcpClients": 
getOrCreateConfiguration(target).setMcpClients(property(camelContext, 
java.util.List.class, value)); return true;
+        case "mcpserver":
+        case "mcpServer": 
getOrCreateConfiguration(target).setMcpServer(property(camelContext, 
java.util.Map.class, value)); return true;
         case "tags": 
getOrCreateConfiguration(target).setTags(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
@@ -59,6 +63,10 @@ public class LangChain4jAgentComponentConfigurer extends 
PropertyConfigurerSuppo
         case "configuration": return 
org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
+        case "mcpclients":
+        case "mcpClients": return java.util.List.class;
+        case "mcpserver":
+        case "mcpServer": return java.util.Map.class;
         case "tags": return java.lang.String.class;
         default: return null;
         }
@@ -76,9 +84,24 @@ public class LangChain4jAgentComponentConfigurer extends 
PropertyConfigurerSuppo
         case "configuration": return target.getConfiguration();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "mcpclients":
+        case "mcpClients": return 
getOrCreateConfiguration(target).getMcpClients();
+        case "mcpserver":
+        case "mcpServer": return 
getOrCreateConfiguration(target).getMcpServer();
         case "tags": return getOrCreateConfiguration(target).getTags();
         default: return null;
         }
     }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "mcpclients":
+        case "mcpClients": return dev.langchain4j.mcp.client.McpClient.class;
+        case "mcpserver":
+        case "mcpServer": return java.lang.Object.class;
+        default: return null;
+        }
+    }
 }
 
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfigurationConfigurer.java
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfigurationConfigurer.java
index 4e61552d23a1..69a1f67aaede 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfigurationConfigurer.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfigurationConfigurer.java
@@ -26,6 +26,10 @@ public class LangChain4jAgentConfigurationConfigurer extends 
org.apache.camel.su
         case "agent": target.setAgent(property(camelContext, 
org.apache.camel.component.langchain4j.agent.api.Agent.class, value)); return 
true;
         case "agentfactory":
         case "agentFactory": target.setAgentFactory(property(camelContext, 
org.apache.camel.component.langchain4j.agent.api.AgentFactory.class, value)); 
return true;
+        case "mcpclients":
+        case "mcpClients": target.setMcpClients(property(camelContext, 
java.util.List.class, value)); return true;
+        case "mcpserver":
+        case "mcpServer": target.setMcpServer(property(camelContext, 
java.util.Map.class, value)); return true;
         case "tags": target.setTags(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
@@ -37,6 +41,10 @@ public class LangChain4jAgentConfigurationConfigurer extends 
org.apache.camel.su
         case "agent": return 
org.apache.camel.component.langchain4j.agent.api.Agent.class;
         case "agentfactory":
         case "agentFactory": return 
org.apache.camel.component.langchain4j.agent.api.AgentFactory.class;
+        case "mcpclients":
+        case "mcpClients": return java.util.List.class;
+        case "mcpserver":
+        case "mcpServer": return java.util.Map.class;
         case "tags": return java.lang.String.class;
         default: return null;
         }
@@ -49,9 +57,24 @@ public class LangChain4jAgentConfigurationConfigurer extends 
org.apache.camel.su
         case "agent": return target.getAgent();
         case "agentfactory":
         case "agentFactory": return target.getAgentFactory();
+        case "mcpclients":
+        case "mcpClients": return target.getMcpClients();
+        case "mcpserver":
+        case "mcpServer": return target.getMcpServer();
         case "tags": return target.getTags();
         default: return null;
         }
     }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "mcpclients":
+        case "mcpClients": return dev.langchain4j.mcp.client.McpClient.class;
+        case "mcpserver":
+        case "mcpServer": return java.lang.Object.class;
+        default: return null;
+        }
+    }
 }
 
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointConfigurer.java
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointConfigurer.java
index a5643be29293..ff73e3cd6af3 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointConfigurer.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointConfigurer.java
@@ -28,6 +28,10 @@ public class LangChain4jAgentEndpointConfigurer extends 
PropertyConfigurerSuppor
         case "agentFactory": 
target.getConfiguration().setAgentFactory(property(camelContext, 
org.apache.camel.component.langchain4j.agent.api.AgentFactory.class, value)); 
return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "mcpclients":
+        case "mcpClients": 
target.getConfiguration().setMcpClients(property(camelContext, 
java.util.List.class, value)); return true;
+        case "mcpserver":
+        case "mcpServer": 
target.getConfiguration().setMcpServer(property(camelContext, 
java.util.Map.class, value)); return true;
         case "tags": target.getConfiguration().setTags(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
@@ -46,6 +50,10 @@ public class LangChain4jAgentEndpointConfigurer extends 
PropertyConfigurerSuppor
         case "agentFactory": return 
org.apache.camel.component.langchain4j.agent.api.AgentFactory.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
+        case "mcpclients":
+        case "mcpClients": return java.util.List.class;
+        case "mcpserver":
+        case "mcpServer": return java.util.Map.class;
         case "tags": return java.lang.String.class;
         default: return null;
         }
@@ -60,9 +68,24 @@ public class LangChain4jAgentEndpointConfigurer extends 
PropertyConfigurerSuppor
         case "agentFactory": return 
target.getConfiguration().getAgentFactory();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "mcpclients":
+        case "mcpClients": return target.getConfiguration().getMcpClients();
+        case "mcpserver":
+        case "mcpServer": return target.getConfiguration().getMcpServer();
         case "tags": return target.getConfiguration().getTags();
         default: return null;
         }
     }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "mcpclients":
+        case "mcpClients": return dev.langchain4j.mcp.client.McpClient.class;
+        case "mcpserver":
+        case "mcpServer": return java.lang.Object.class;
+        default: return null;
+        }
+    }
 }
 
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointUriFactory.java
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointUriFactory.java
index b32835caf0fa..952244774942 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointUriFactory.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpointUriFactory.java
@@ -23,15 +23,19 @@ public class LangChain4jAgentEndpointUriFactory extends 
org.apache.camel.support
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(5);
+        Set<String> props = new HashSet<>(7);
         props.add("agent");
         props.add("agentFactory");
         props.add("agentId");
         props.add("lazyStartProducer");
+        props.add("mcpClients");
+        props.add("mcpServer");
         props.add("tags");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
         SECRET_PROPERTY_NAMES = Collections.emptySet();
-        MULTI_VALUE_PREFIXES = Collections.emptyMap();
+        Map<String, String> prefixes = new HashMap<>(1);
+        prefixes.put("mcpServer", "mcpServer.");
+        MULTI_VALUE_PREFIXES = Collections.unmodifiableMap(prefixes);
     }
 
     @Override
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
index 28dd67fe2a67..593d99e60555 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
@@ -29,19 +29,25 @@
     "configuration": { "index": 2, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
configuration" },
     "lazyStartProducer": { "index": 3, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "tags": { "index": 4, "kind": "property", "displayName": "Tags", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Tags for discovering and 
calling Camel route tools" },
-    "autowiredEnabled": { "index": 5, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 5, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "mcpClients": { "index": 6, "kind": "property", "displayName": "Mcp 
Clients", "group": "advanced", "label": "advanced", "required": false, "type": 
"array", "javaType": "java.util.List<dev.langchain4j.mcp.client.McpClient>", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Pre-built MCP (Model 
Context Protocol) client insta [...]
+    "mcpServer": { "index": 7, "kind": "property", "displayName": "Mcp 
Server", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", 
"prefix": "mcpServer.", "multiValue": true, "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "MCP server  [...]
   },
   "headers": {
     "CamelLangChain4jAgentSystemMessage": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The system prompt.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#SYSTEM_MESSAGE" },
     "CamelLangChain4jAgentMemoryId": { "index": 1, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Memory ID.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEMORY_ID" },
     "CamelLangChain4jAgentUserMessage": { "index": 2, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The user message to accompany file 
content when using WrappedFile as input.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#USER_MESSAGE" },
-    "CamelLangChain4jAgentMediaType": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The media type (MIME type) of the file 
content. Overrides auto-detection from file extension.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEDIA_TYPE" }
+    "CamelLangChain4jAgentMediaType": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The media type (MIME type) of the file 
content. Overrides auto-detection from file extension.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MEDIA_TYPE" },
+    "CamelLangChain4jAgentExcludeTags": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated list of Camel tool tags 
to exclude from this agent invocation.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#EXCLUDE_TAGS" },
+    "CamelLangChain4jAgentExcludeMcpServers": { "index": 5, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated list of MCP server 
names (keys) to exclude from this agent invocation.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#EXCLUDE_MCP_SERVERS" }
   },
   "properties": {
     "agentId": { "index": 0, "kind": "path", "displayName": "Agent Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Agent id" },
     "agent": { "index": 1, "kind": "parameter", "displayName": "Agent", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.langchain4j.agent.api.Agent", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent to use for the 
component" },
     "agentFactory": { "index": 2, "kind": "parameter", "displayName": "Agent 
Factory", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": 
"org.apache.camel.component.langchain4j.agent.api.AgentFactory", "deprecated": 
false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent factory to u 
[...]
     "tags": { "index": 3, "kind": "parameter", "displayName": "Tags", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Tags for discovering and 
calling Camel route tools" },
-    "lazyStartProducer": { "index": 4, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "lazyStartProducer": { "index": 4, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "mcpClients": { "index": 5, "kind": "parameter", "displayName": "Mcp 
Clients", "group": "advanced", "label": "advanced", "required": false, "type": 
"array", "javaType": "java.util.List<dev.langchain4j.mcp.client.McpClient>", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "Pre-built MCP (Model 
Context Protocol) client inst [...]
+    "mcpServer": { "index": 6, "kind": "parameter", "displayName": "Mcp 
Server", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", 
"prefix": "mcpServer.", "multiValue": true, "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "MCP server [...]
   }
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/docs/langchain4j-agent-component.adoc
 
b/components/camel-ai/camel-langchain4j-agent/src/main/docs/langchain4j-agent-component.adoc
index 551433aee59e..aa1416c042f8 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/main/docs/langchain4j-agent-component.adoc
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/docs/langchain4j-agent-component.adoc
@@ -463,10 +463,99 @@ from("direct:chat")
 
 [source,java]
 ----
-String response = template.requestBody("direct:chat", 
+String response = template.requestBody("direct:chat",
     "Can you list the files in the current directory and read the content of 
file.txt?", String.class);
 ----
 
+==== Endpoint-Level MCP Configuration
+
+MCP servers can also be configured directly on the endpoint, without setting 
them on the `AgentConfiguration`. This is useful for declarative route 
definitions and allows MCP tools to coexist with Camel route tools (via `tags`).
+
+===== Bean References
+
+Register pre-built `McpClient` beans and reference them via the `mcpClients` 
endpoint parameter:
+
+[source,java]
+----
+// Register MCP clients as beans
+McpClient timeClient = new DefaultMcpClient.Builder()
+    .key("time")
+    .transport(new StdioMcpTransport.Builder()
+        .command(Arrays.asList("docker", "run", "-i", "--rm", "mcp/time"))
+        .build())
+    .build();
+context.getRegistry().bind("timeMcpClient", timeClient);
+
+// Reference in endpoint URI
+from("direct:chat")
+    
.to("langchain4j-agent:assistant?agent=#myAgent&tags=users&mcpClients=#timeMcpClient")
+    .to("mock:response");
+----
+
+===== Inline URI Configuration
+
+MCP servers can be defined inline on the endpoint URI using the 
`mcpServer.<name>.<property>` pattern. The component creates and manages the 
MCP client lifecycle automatically.
+
+Supported properties:
+
+[cols="1,1,3"]
+|===
+| Property | Default | Description
+
+| `transportType` | `stdio` | Transport type: `stdio`, `http` (Streamable 
HTTP), or `sse` (legacy SSE)
+| `command` | | Comma-separated command for stdio transport (e.g., 
`docker,run,-i,--rm,mcp/time`)
+| `url` | | Server URL for `http` or `sse` transport
+| `environment.<key>` | | Environment variables for stdio transport
+| `timeout` | `60` | Timeout in seconds
+| `logRequests` | `false` | Log requests sent to the MCP server
+| `logResponses` | `false` | Log responses from the MCP server
+|===
+
+Example with two MCP servers configured inline:
+
+[source,java]
+----
+from("direct:chat")
+    .to("langchain4j-agent:assistant?agent=#myAgent&tags=users"
+        + "&mcpServer.everything.transportType=http"
+        + "&mcpServer.everything.url=http://localhost:3001/mcp";
+        + "&mcpServer.time.transportType=stdio"
+        + "&mcpServer.time.command=docker,run,-i,--rm,mcp/time")
+    .to("mock:response");
+----
+
+Both `mcpClients` (bean references) and `mcpServer` (inline) can be used 
together on the same endpoint. All tool sources -- Camel route tools, 
endpoint-level MCP tools, and agent-level MCP tools -- are automatically 
composed into a single tool provider.
+
+==== Dynamic Tool Exclusion via Headers
+
+Tools can be dynamically excluded on a per-message basis using Camel headers. 
This allows routes to control which tools are available based on business 
logic, user roles, or message content.
+
+[cols="1,3"]
+|===
+| Header | Description
+
+| `CamelLangChain4jAgentExcludeTags` | Comma-separated list of Camel tool tags 
to exclude
+| `CamelLangChain4jAgentExcludeMcpServers` | Comma-separated list of MCP 
server names (keys) to exclude
+|===
+
+Example -- exclude specific tools based on a condition:
+
+[source,java]
+----
+from("direct:chat")
+    .choice()
+        .when(header("userRole").isEqualTo("readonly"))
+            // Exclude write-capable tools for read-only users
+            .setHeader("CamelLangChain4jAgentExcludeTags", 
constant("admin-tools"))
+            .setHeader("CamelLangChain4jAgentExcludeMcpServers", 
constant("filesystem"))
+    .end()
+    .to("langchain4j-agent:assistant?agent=#myAgent&tags=users,admin-tools"
+        + "&mcpClients=#fsMcpClient,#timeMcpClient")
+    .to("mock:response");
+----
+
+MCP servers are matched by their key, which is set via 
`DefaultMcpClient.Builder.key(name)` or automatically from the server name in 
inline `mcpServer.<name>` configuration. MCP clients without a key are never 
excluded.
+
 === RAG Integration
 
 RAG (Retrieval-Augmented Generation) is supported by configuring a 
`RetrievalAugmentor` in the `AgentConfiguration`. Create an agent with RAG 
capabilities:
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfiguration.java
 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfiguration.java
index fa886ec04508..8ef15e74a167 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfiguration.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentConfiguration.java
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.component.langchain4j.agent;
 
+import java.util.List;
+import java.util.Map;
+
+import dev.langchain4j.mcp.client.McpClient;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.langchain4j.agent.api.Agent;
 import org.apache.camel.component.langchain4j.agent.api.AgentFactory;
@@ -39,6 +43,19 @@ public class LangChain4jAgentConfiguration implements 
Cloneable {
     @UriParam(description = "Tags for discovering and calling Camel route 
tools")
     private String tags;
 
+    @UriParam(description = "Pre-built MCP (Model Context Protocol) client 
instances for external tool integration."
+                            + " Reference beans from the registry, e.g., 
#myMcpClient1,#myMcpClient2",
+              label = "advanced")
+    private List<McpClient> mcpClients;
+
+    @UriParam(description = "MCP server definitions in the form of 
mcpServer.<name>.<property>=<value>."
+                            + " Supported properties: transportType (stdio or 
http, default: stdio),"
+                            + " command (comma-separated, for stdio), url (for 
http),"
+                            + " environment.<key>=<value> (for stdio), timeout 
(in seconds, default: 60),"
+                            + " logRequests, logResponses.",
+              prefix = "mcpServer.", multiValue = true, label = "advanced")
+    private Map<String, Object> mcpServer;
+
     public LangChain4jAgentConfiguration() {
     }
 
@@ -88,4 +105,40 @@ public class LangChain4jAgentConfiguration implements 
Cloneable {
     public void setAgentFactory(AgentFactory agentFactory) {
         this.agentFactory = agentFactory;
     }
+
+    /**
+     * Pre-built MCP client instances for external tool integration
+     *
+     * @return the list of MCP clients
+     */
+    public List<McpClient> getMcpClients() {
+        return mcpClients;
+    }
+
+    public void setMcpClients(List<McpClient> mcpClients) {
+        this.mcpClients = mcpClients;
+    }
+
+    /**
+     * MCP server definitions for inline URI configuration.
+     *
+     * <p>
+     * The map keys are in the form {@code <serverName>.<property>} and are 
collected from URI parameters with the
+     * {@code mcpServer.} prefix. For example:
+     * </p>
+     *
+     * <pre>
+     * 
mcpServer.weather.transportType=http&amp;mcpServer.weather.url=http://localhost:8080
+     * 
mcpServer.fs.transportType=stdio&amp;mcpServer.fs.command=npx,-y,@modelcontextprotocol/server-filesystem
+     * </pre>
+     *
+     * @return the map of MCP server properties
+     */
+    public Map<String, Object> getMcpServer() {
+        return mcpServer;
+    }
+
+    public void setMcpServer(Map<String, Object> mcpServer) {
+        this.mcpServer = mcpServer;
+    }
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
index 41fc57ea0001..f74743644275 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
@@ -16,12 +16,15 @@
  */
 package org.apache.camel.component.langchain4j.agent;
 
+import java.time.Duration;
 import java.util.*;
 import java.util.stream.Collectors;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import dev.langchain4j.agent.tool.ToolSpecification;
+import dev.langchain4j.mcp.McpToolProvider;
+import dev.langchain4j.mcp.client.McpClient;
 import dev.langchain4j.service.tool.ToolExecutor;
 import dev.langchain4j.service.tool.ToolProvider;
 import dev.langchain4j.service.tool.ToolProviderRequest;
@@ -30,6 +33,8 @@ import org.apache.camel.Exchange;
 import org.apache.camel.component.langchain4j.agent.api.Agent;
 import org.apache.camel.component.langchain4j.agent.api.AgentFactory;
 import org.apache.camel.component.langchain4j.agent.api.AiAgentBody;
+import org.apache.camel.component.langchain4j.agent.api.CompositeToolProvider;
+import org.apache.camel.component.langchain4j.agent.api.Headers;
 import 
org.apache.camel.component.langchain4j.tools.spec.CamelToolExecutorCache;
 import 
org.apache.camel.component.langchain4j.tools.spec.CamelToolSpecification;
 import org.apache.camel.support.DefaultProducer;
@@ -44,6 +49,7 @@ public class LangChain4jAgentProducer extends DefaultProducer 
{
     private final ObjectMapper objectMapper = new ObjectMapper();
     private AgentFactory agentFactory;
     private Agent agent;
+    private List<McpClient> materializedMcpClients;
 
     public LangChain4jAgentProducer(LangChain4jAgentEndpoint endpoint) {
         super(endpoint);
@@ -75,34 +81,102 @@ public class LangChain4jAgentProducer extends 
DefaultProducer {
 
         AiAgentBody<?> aiAgentBody = agent.processBody(messagePayload, 
exchange);
 
-        ToolProvider toolProvider = createCamelToolProvider(tags, exchange);
+        ToolProvider toolProvider = createComposedToolProvider(tags, exchange);
         String response = agent.chat(aiAgentBody, toolProvider);
         exchange.getMessage().setBody(response);
     }
 
     /**
-     * We create our own Tool Provider
+     * Creates a composed tool provider that aggregates tools from all 
configured sources: Camel route tools (via tags)
+     * and MCP tools (via endpoint-level mcpClients and mcpServers 
configuration).
      *
-     * @param tags
-     * @param exchange
+     * <p>
+     * Supports dynamic filtering via exchange headers:
+     * <ul>
+     * <li>{@link Headers#EXCLUDE_TAGS} — exclude Camel tools by tag (handled 
in
+     * {@link #createCamelToolProvider(String, Exchange)})</li>
+     * <li>{@link Headers#EXCLUDE_MCP_SERVERS} — exclude MCP servers by 
key/name</li>
+     * </ul>
      */
-    private ToolProvider createCamelToolProvider(String tags, Exchange 
exchange) {
-        ToolProvider toolProvider = null;
-        if (tags != null && !tags.trim().isEmpty()) {
-            // Discover tools from Camel LangChain4j Tools routes
-            Map<String, CamelToolSpecification> availableTools = 
discoverToolsByName(tags);
+    private ToolProvider createComposedToolProvider(String tags, Exchange 
exchange) {
+        List<ToolProvider> providers = new ArrayList<>();
 
-            if (!availableTools.isEmpty()) {
-                LOG.debug("Creating AI Service with {} tools for tags: {}", 
availableTools.size(), tags);
+        // 1. Camel route tools from tags (handles EXCLUDE_TAGS header 
internally)
+        ToolProvider camelToolProvider = createCamelToolProvider(tags, 
exchange);
+        if (camelToolProvider != null) {
+            providers.add(camelToolProvider);
+        }
 
-                // Create dynamic tool provider that returns Camel routes as 
tools
-                toolProvider = createCamelToolProvider(availableTools, 
exchange);
+        // 2. MCP tools from endpoint configuration (pre-built clients + 
materialized from server definitions)
+        List<McpClient> allMcpClients = new ArrayList<>();
 
-            } else {
-                LOG.debug("No tools found for tags: {}, using simple AI 
Service", tags);
+        List<McpClient> endpointMcpClients = 
endpoint.getConfiguration().getMcpClients();
+        if (endpointMcpClients != null) {
+            allMcpClients.addAll(endpointMcpClients);
+        }
+        if (materializedMcpClients != null) {
+            allMcpClients.addAll(materializedMcpClients);
+        }
+
+        // Apply MCP server exclusion from header
+        String excludeMcpServers = 
exchange.getIn().getHeader(Headers.EXCLUDE_MCP_SERVERS, String.class);
+        if (excludeMcpServers != null && !excludeMcpServers.trim().isEmpty()) {
+            Set<String> excludeSet = new 
HashSet<>(Arrays.asList(ToolsTagsHelper.splitTags(excludeMcpServers)));
+            allMcpClients = allMcpClients.stream()
+                    .filter(client -> client.key() == null || 
!excludeSet.contains(client.key()))
+                    .collect(Collectors.toList());
+            LOG.debug("After MCP server exclusion (excluded: {}): {} clients 
remaining",
+                    excludeMcpServers, allMcpClients.size());
+        }
+
+        if (!allMcpClients.isEmpty()) {
+            LOG.debug("Adding {} MCP clients to tool provider", 
allMcpClients.size());
+            
providers.add(McpToolProvider.builder().mcpClients(allMcpClients).build());
+        }
+
+        if (providers.isEmpty()) {
+            return null;
+        } else if (providers.size() == 1) {
+            return providers.get(0);
+        } else {
+            return new CompositeToolProvider(providers);
+        }
+    }
+
+    /**
+     * Creates a tool provider for Camel route tools discovered by tags. If 
the {@link Headers#EXCLUDE_TAGS} header is
+     * set on the exchange, the specified tags (comma-separated) are excluded 
from discovery.
+     */
+    private ToolProvider createCamelToolProvider(String tags, Exchange 
exchange) {
+        if (tags == null || tags.trim().isEmpty()) {
+            return null;
+        }
+
+        // Apply tag exclusion from header
+        String excludeTags = exchange.getIn().getHeader(Headers.EXCLUDE_TAGS, 
String.class);
+        if (excludeTags != null && !excludeTags.trim().isEmpty()) {
+            Set<String> excludeSet = new 
HashSet<>(Arrays.asList(ToolsTagsHelper.splitTags(excludeTags)));
+            String[] allTags = ToolsTagsHelper.splitTags(tags);
+            tags = Arrays.stream(allTags)
+                    .filter(t -> !excludeSet.contains(t))
+                    .collect(Collectors.joining(","));
+            LOG.debug("After tag exclusion (excluded: {}): remaining tags: 
{}", excludeTags, tags);
+            if (tags.isEmpty()) {
+                LOG.debug("All Camel tool tags excluded by header");
+                return null;
             }
         }
-        return toolProvider;
+
+        // Discover tools from Camel LangChain4j Tools routes
+        Map<String, CamelToolSpecification> availableTools = 
discoverToolsByName(tags);
+
+        if (!availableTools.isEmpty()) {
+            LOG.debug("Creating AI Service with {} tools for tags: {}", 
availableTools.size(), tags);
+            return createCamelToolProvider(availableTools, exchange);
+        } else {
+            LOG.debug("No tools found for tags: {}, using simple AI Service", 
tags);
+            return null;
+        }
     }
 
     /**
@@ -191,5 +265,111 @@ public class LangChain4jAgentProducer extends 
DefaultProducer {
         if (agentFactory != null) {
             agentFactory.setCamelContext(this.endpoint.getCamelContext());
         }
+
+        // Materialize MCP clients from inline mcpServer.<name>.<property> 
configuration
+        Map<String, Object> mcpServerMap = 
endpoint.getConfiguration().getMcpServer();
+        if (mcpServerMap != null && !mcpServerMap.isEmpty()) {
+            List<LangChain4jMcpServerDefinition> serverDefs = 
parseMcpServerDefinitions(mcpServerMap);
+            if (!serverDefs.isEmpty()) {
+                materializedMcpClients = new ArrayList<>();
+                for (LangChain4jMcpServerDefinition def : serverDefs) {
+                    LOG.debug("Building MCP client '{}' (transport: {})", 
def.getServerName(), def.getTransportType());
+                    materializedMcpClients.add(def.buildClient());
+                }
+                LOG.debug("Materialized {} MCP clients from server 
definitions", materializedMcpClients.size());
+            }
+        }
+    }
+
+    /**
+     * Parses the flat mcpServer map (from URI parameters like 
mcpServer.weather.url=...) into grouped
+     * {@link LangChain4jMcpServerDefinition} instances.
+     *
+     * <p>
+     * The map keys are in the form {@code <serverName>.<property>}. For 
example:
+     * </p>
+     * <ul>
+     * <li>{@code weather.transportType=http}</li>
+     * <li>{@code weather.url=http://localhost:8080}</li>
+     * <li>{@code 
filesystem.command=npx,-y,@modelcontextprotocol/server-filesystem}</li>
+     * </ul>
+     */
+    private List<LangChain4jMcpServerDefinition> 
parseMcpServerDefinitions(Map<String, Object> mcpServerMap) {
+        // Group entries by server name (the first dot-separated segment)
+        Map<String, Map<String, String>> serverGroups = new LinkedHashMap<>();
+        for (Map.Entry<String, Object> entry : mcpServerMap.entrySet()) {
+            String key = entry.getKey();
+            int dotIndex = key.indexOf('.');
+            if (dotIndex > 0 && dotIndex < key.length() - 1) {
+                String serverName = key.substring(0, dotIndex);
+                String property = key.substring(dotIndex + 1);
+                serverGroups.computeIfAbsent(serverName, k -> new 
LinkedHashMap<>())
+                        .put(property, String.valueOf(entry.getValue()));
+            } else {
+                LOG.warn("Ignoring invalid mcpServer property key: '{}'. 
Expected format: <serverName>.<property>", key);
+            }
+        }
+
+        List<LangChain4jMcpServerDefinition> definitions = new ArrayList<>();
+        for (Map.Entry<String, Map<String, String>> group : 
serverGroups.entrySet()) {
+            String serverName = group.getKey();
+            Map<String, String> props = group.getValue();
+
+            LangChain4jMcpServerDefinition def = new 
LangChain4jMcpServerDefinition();
+            def.setServerName(serverName);
+
+            if (props.containsKey("transportType")) {
+                def.setTransportType(props.get("transportType"));
+            }
+            if (props.containsKey("url")) {
+                def.setUrl(props.get("url"));
+            }
+            if (props.containsKey("command")) {
+                def.setCommand(Arrays.asList(props.get("command").split(",")));
+            }
+            if (props.containsKey("timeout")) {
+                
def.setTimeout(Duration.ofSeconds(Long.parseLong(props.get("timeout"))));
+            }
+            if (props.containsKey("logRequests")) {
+                
def.setLogRequests(Boolean.parseBoolean(props.get("logRequests")));
+            }
+            if (props.containsKey("logResponses")) {
+                
def.setLogResponses(Boolean.parseBoolean(props.get("logResponses")));
+            }
+
+            // Collect environment variables (environment.<key>=<value>)
+            Map<String, String> environment = new LinkedHashMap<>();
+            for (Map.Entry<String, String> prop : props.entrySet()) {
+                if (prop.getKey().startsWith("environment.")) {
+                    String envKey = 
prop.getKey().substring("environment.".length());
+                    environment.put(envKey, prop.getValue());
+                }
+            }
+            if (!environment.isEmpty()) {
+                def.setEnvironment(environment);
+            }
+
+            definitions.add(def);
+            LOG.debug("Parsed MCP server definition '{}' (transport: {})", 
serverName, def.getTransportType());
+        }
+
+        return definitions;
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // Close only MCP clients that were materialized from server 
definitions.
+        // Pre-built McpClient beans (from mcpClients parameter) are managed 
by the registry/container.
+        if (materializedMcpClients != null) {
+            for (McpClient client : materializedMcpClients) {
+                try {
+                    client.close();
+                } catch (Exception e) {
+                    LOG.warn("Error closing MCP client: {}", e.getMessage(), 
e);
+                }
+            }
+            materializedMcpClients = null;
+        }
+        super.doStop();
     }
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jMcpServerDefinition.java
 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jMcpServerDefinition.java
new file mode 100644
index 000000000000..d196ae1d2da4
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jMcpServerDefinition.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.langchain4j.agent;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+
+import dev.langchain4j.mcp.client.DefaultMcpClient;
+import dev.langchain4j.mcp.client.McpClient;
+import dev.langchain4j.mcp.client.transport.McpTransport;
+import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
+import dev.langchain4j.mcp.client.transport.http.StreamableHttpMcpTransport;
+import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
+
+/**
+ * A simplified configuration POJO for declaratively defining MCP (Model 
Context Protocol) servers.
+ *
+ * <p>
+ * This class provides a convenient way to configure MCP server connections 
without manually building
+ * {@link DefaultMcpClient} and transport instances. It supports both 
stdio-based and HTTP-based transports.
+ * </p>
+ *
+ * <p>
+ * Example usage as a Spring bean:
+ * </p>
+ *
+ * <pre>{@code
+ * // Stdio transport (e.g., local MCP server via npx)
+ * LangChain4jMcpServerDefinition serverDef = new 
LangChain4jMcpServerDefinition();
+ * serverDef.setTransportType("stdio");
+ * serverDef.setCommand(List.of("npx", "-y", 
"@modelcontextprotocol/server-everything"));
+ *
+ * // HTTP transport (e.g., remote MCP server)
+ * LangChain4jMcpServerDefinition serverDef = new 
LangChain4jMcpServerDefinition();
+ * serverDef.setTransportType("http");
+ * serverDef.setUrl("http://localhost:3001/mcp";);
+ * }</pre>
+ *
+ * @since 4.19.0
+ */
+public class LangChain4jMcpServerDefinition {
+
+    private String serverName;
+    private String transportType = "stdio";
+    private List<String> command;
+    private Map<String, String> environment;
+    private String url;
+    private Duration timeout = Duration.ofSeconds(60);
+    private boolean logRequests;
+    private boolean logResponses;
+
+    /**
+     * Gets the server name (used for identification and as the MCP client 
key).
+     */
+    public String getServerName() {
+        return serverName;
+    }
+
+    /**
+     * Sets the server name (used for identification and as the MCP client 
key).
+     */
+    public void setServerName(String serverName) {
+        this.serverName = serverName;
+    }
+
+    /**
+     * Gets the transport type. Supported values: "stdio", "http".
+     */
+    public String getTransportType() {
+        return transportType;
+    }
+
+    /**
+     * Sets the transport type. Supported values: "stdio" (default), "http".
+     */
+    public void setTransportType(String transportType) {
+        this.transportType = transportType;
+    }
+
+    /**
+     * Gets the command for stdio transport.
+     */
+    public List<String> getCommand() {
+        return command;
+    }
+
+    /**
+     * Sets the command for stdio transport. For example: ["npx", "-y", 
"@modelcontextprotocol/server-everything"].
+     */
+    public void setCommand(List<String> command) {
+        this.command = command;
+    }
+
+    /**
+     * Gets the environment variables for stdio transport.
+     */
+    public Map<String, String> getEnvironment() {
+        return environment;
+    }
+
+    /**
+     * Sets the environment variables for stdio transport.
+     */
+    public void setEnvironment(Map<String, String> environment) {
+        this.environment = environment;
+    }
+
+    /**
+     * Gets the URL for HTTP transport.
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * Sets the URL for HTTP transport. For example: 
"http://localhost:3001/mcp";.
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * Gets the timeout for tool execution and connection.
+     */
+    public Duration getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * Sets the timeout for tool execution and connection. Default: 60 seconds.
+     */
+    public void setTimeout(Duration timeout) {
+        this.timeout = timeout;
+    }
+
+    /**
+     * Gets whether request logging is enabled.
+     */
+    public boolean isLogRequests() {
+        return logRequests;
+    }
+
+    /**
+     * Sets whether to log requests sent to the MCP server.
+     */
+    public void setLogRequests(boolean logRequests) {
+        this.logRequests = logRequests;
+    }
+
+    /**
+     * Gets whether response logging is enabled.
+     */
+    public boolean isLogResponses() {
+        return logResponses;
+    }
+
+    /**
+     * Sets whether to log responses received from the MCP server.
+     */
+    public void setLogResponses(boolean logResponses) {
+        this.logResponses = logResponses;
+    }
+
+    /**
+     * Builds an {@link McpClient} from this definition.
+     *
+     * @return                          a configured and ready-to-use McpClient
+     * @throws IllegalArgumentException if required configuration is missing
+     */
+    public McpClient buildClient() {
+        McpTransport transport = buildTransport();
+
+        DefaultMcpClient.Builder clientBuilder = new DefaultMcpClient.Builder()
+                .transport(transport)
+                .toolExecutionTimeout(timeout);
+
+        if (serverName != null) {
+            clientBuilder.key(serverName);
+        }
+
+        return clientBuilder.build();
+    }
+
+    @SuppressWarnings("deprecation")
+    private McpTransport buildTransport() {
+        if ("http".equalsIgnoreCase(transportType)) {
+            if (url == null || url.trim().isEmpty()) {
+                throw new IllegalArgumentException("URL is required for HTTP 
MCP transport");
+            }
+            return new StreamableHttpMcpTransport.Builder()
+                    .url(url)
+                    .logRequests(logRequests)
+                    .logResponses(logResponses)
+                    .timeout(timeout)
+                    .build();
+        } else if ("sse".equalsIgnoreCase(transportType)) {
+            if (url == null || url.trim().isEmpty()) {
+                throw new IllegalArgumentException("URL is required for SSE 
MCP transport");
+            }
+            return new HttpMcpTransport.Builder()
+                    .sseUrl(url)
+                    .logRequests(logRequests)
+                    .logResponses(logResponses)
+                    .timeout(timeout)
+                    .build();
+        } else if ("stdio".equalsIgnoreCase(transportType)) {
+            if (command == null || command.isEmpty()) {
+                throw new IllegalArgumentException("Command is required for 
stdio MCP transport");
+            }
+            StdioMcpTransport.Builder builder = new StdioMcpTransport.Builder()
+                    .command(command)
+                    .logEvents(logRequests || logResponses);
+            if (environment != null) {
+                builder.environment(environment);
+            }
+            return builder.build();
+        } else {
+            throw new IllegalArgumentException(
+                    "Unsupported MCP transport type: " + transportType
+                                               + ". Supported values: stdio, 
http, sse");
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpAndCamelToolsIT.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpAndCamelToolsIT.java
new file mode 100644
index 000000000000..6f06db05c5fa
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpAndCamelToolsIT.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.langchain4j.agent.integration;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import dev.langchain4j.mcp.client.DefaultMcpClient;
+import dev.langchain4j.mcp.client.McpClient;
+import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
+import dev.langchain4j.model.chat.ChatModel;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.langchain4j.agent.api.Agent;
+import org.apache.camel.component.langchain4j.agent.api.AgentConfiguration;
+import org.apache.camel.component.langchain4j.agent.api.AgentWithoutMemory;
+import org.apache.camel.component.langchain4j.agent.api.Headers;
+import org.apache.camel.component.mock.MockEndpoint;
+import 
org.apache.camel.test.infra.mcp.everything.services.McpEverythingService;
+import 
org.apache.camel.test.infra.mcp.everything.services.McpEverythingServiceFactory;
+import org.apache.camel.test.infra.ollama.services.OllamaService;
+import org.apache.camel.test.infra.ollama.services.OllamaServiceFactory;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Integration test for the LangChain4j Agent component verifying that 
internal Camel route tools (via
+ * camel-langchain4j-tools with tags) and external MCP tools can coexist 
together in a single agent.
+ *
+ * <p>
+ * This test demonstrates two MCP configuration approaches working 
simultaneously:
+ * <ul>
+ * <li><strong>Endpoint URI configuration</strong>: the mcp/everything server 
(Streamable HTTP) is configured
+ * declaratively via {@code 
mcpServer.everything.transportType=http&mcpServer.everything.url=...}</li>
+ * <li><strong>Bean reference configuration</strong>: the mcp/time server 
(Docker stdio) is configured as a pre-built
+ * {@link McpClient} bean and referenced via {@code 
mcpClients=#timeMcpClient}</li>
+ * </ul>
+ *
+ * <p>
+ * Additionally, Camel route tools (user database and weather service) are 
configured via the {@code tags} parameter.
+ * All tool sources are composed via {@code CompositeToolProvider}.
+ */
+@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*", 
disabledReason = "Requires too much network resources")
+public class LangChain4jAgentMcpAndCamelToolsIT extends CamelTestSupport {
+
+    private static final String USER_DATABASE = """
+            {"id": "42", "name": "Alice Johnson", "role": "Engineer"}
+            """;
+
+    private static final String WEATHER_INFO = "cloudy, 18C";
+
+    protected ChatModel chatModel;
+    private McpClient timeClient;
+
+    @RegisterExtension
+    static OllamaService OLLAMA = 
OllamaServiceFactory.createSingletonService();
+
+    @RegisterExtension
+    static McpEverythingService MCP_EVERYTHING = 
McpEverythingServiceFactory.createService();
+
+    @Override
+    protected void setupResources() throws Exception {
+        super.setupResources();
+        chatModel = ModelHelper.loadChatModel(OLLAMA);
+
+        // MCP Time Server via Docker stdio transport - configured as 
pre-built McpClient bean
+        timeClient = new DefaultMcpClient.Builder()
+                .key("time")
+                .transport(new StdioMcpTransport.Builder()
+                        .command(Arrays.asList("docker", "run", "-i", "--rm", 
"mcp/time"))
+                        .logEvents(true)
+                        .build())
+                .build();
+    }
+
+    @Override
+    protected void cleanupResources() throws Exception {
+        if (timeClient != null) {
+            timeClient.close();
+        }
+        super.cleanupResources();
+    }
+
+    /**
+     * Tests that the agent can use a Camel route tool (user database lookup) 
while MCP tools are also available.
+     */
+    @Test
+    void testCamelRouteToolWithMcpToolsPresent() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String response = template.requestBody("direct:chat",
+                "What is the name of user with ID 42? Use the user database 
tool.", String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        assertTrue(response.contains("Alice Johnson"),
+                "Response should contain the user name from the Camel route 
tool but was: " + response);
+    }
+
+    /**
+     * Tests that the agent can use an MCP tool (time server via Docker stdio, 
configured as bean reference).
+     */
+    @Test
+    void testMcpStdioToolAsBeanReference() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String response = template.requestBody("direct:chat",
+                "What is the current time? Use your available tools to find 
out.", String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        assertTrue(response.matches("(?si).*\\d{1,2}[:\\.]\\d{2}.*") || 
response.toLowerCase().contains("time"),
+                "Response should contain time information from MCP time tool 
but was: " + response);
+    }
+
+    /**
+     * Tests that the agent can use an MCP tool from the Streamable HTTP 
server configured inline on the endpoint URI.
+     * The echo tool is part of everything.
+     */
+    @Test
+    void testMcpHttpToolConfiguredOnEndpoint() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String response = template.requestBody("direct:chat",
+                "Use the echo tool to echo the message 'Hello from Camel'.", 
String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        assertTrue(response.toLowerCase().contains("hello") || 
response.toLowerCase().contains("camel"),
+                "Response should contain echoed message from MCP Streamable 
HTTP tool but was: " + response);
+    }
+
+    /**
+     * Tests the add tool from the MCP Everything Server (configured via 
endpoint URI, Streamable HTTP transport). The
+     * add tool is part of everything.
+     */
+    @Test
+    void testMcpHttpToolAdd() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String response = template.requestBody("direct:chat",
+                "Use the add tool to add 17 and 25. What is the result?", 
String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        assertTrue(response.contains("42"),
+                "Response should contain the sum 42 from MCP add tool but was: 
" + response);
+    }
+
+    /**
+     * Tests that both Camel route tools and MCP tools work together in a 
single interaction.
+     */
+    @Test
+    void testMixedCamelAndMcpTools() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String response = template.requestBody("direct:chat",
+                "First, tell me the name of user ID 42 using the user database 
tool, "
+                                                              + "then tell me 
the current time using the time tool.",
+                String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        assertTrue(response.contains("Alice Johnson"),
+                "Response should contain user info from Camel route tool but 
was: " + response);
+    }
+
+    // ---- Tool Exclusion Tests ----
+
+    /**
+     * Tests that excluding a Camel tool tag via header prevents those tools 
from being used. First verifies the tool
+     * works, then excludes the "users" tag and verifies the agent can no 
longer query the user database.
+     */
+    @Test
+    void testExcludeCamelToolTag() throws InterruptedException {
+        // First: verify the Camel tool works without exclusion
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String responseWithTool = template.requestBody("direct:chat",
+                "What is the name of user with ID 42? Use the user database 
tool.", String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(responseWithTool);
+        assertTrue(responseWithTool.contains("Alice Johnson"),
+                "Without exclusion, response should contain user name but was: 
" + responseWithTool);
+
+        // Then: exclude the "users" tag and verify the agent cannot use the 
user database tool
+        mockEndpoint.reset();
+        mockEndpoint.expectedMessageCount(1);
+
+        String responseWithoutTool = 
template.requestBodyAndHeader("direct:chat",
+                "What is the name of user with ID 42? Use the user database 
tool.",
+                Headers.EXCLUDE_TAGS, "users",
+                String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(responseWithoutTool);
+        assertFalse(responseWithoutTool.contains("Alice Johnson"),
+                "With 'users' tag excluded, response should NOT contain user 
name but was: " + responseWithoutTool);
+    }
+
+    /**
+     * Tests that excluding an MCP server by name via header prevents those 
tools from being used. First verifies the
+     * MCP add tool works, then excludes the "everything" MCP server and 
verifies the agent can no longer use it.
+     */
+    @Test
+    void testExcludeMcpServer() throws InterruptedException {
+        // First: verify the MCP tool works without exclusion
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        String responseWithTool = template.requestBody("direct:chat",
+                "Use the add tool to add 17 and 25. What is the result?", 
String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(responseWithTool);
+        assertTrue(responseWithTool.contains("42"),
+                "Without exclusion, response should contain 42 but was: " + 
responseWithTool);
+
+        // Then: exclude the "everything" MCP server and verify the add tool 
is no longer available
+        mockEndpoint.reset();
+        mockEndpoint.expectedMessageCount(1);
+
+        String responseWithoutTool = 
template.requestBodyAndHeader("direct:chat",
+                "Use the add tool to add 17 and 25. What is the result?",
+                Headers.EXCLUDE_MCP_SERVERS, "everything",
+                String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(responseWithoutTool);
+        assertFalse(responseWithoutTool.contains("42"),
+                "With 'everything' MCP server excluded, response should NOT 
contain 42 but was: " + responseWithoutTool);
+    }
+
+    /**
+     * Tests that excluding both Camel tool tags and MCP servers 
simultaneously works. The agent should have no tools
+     * available and respond based only on its own knowledge.
+     */
+    @Test
+    void testExcludeBothCamelTagsAndMcpServers() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:response");
+        mockEndpoint.expectedMessageCount(1);
+
+        // Exclude all Camel tool tags and all MCP servers
+        String response = template.requestBodyAndHeaders("direct:chat",
+                "What tools do you have available? List them all.",
+                Map.of(
+                        Headers.EXCLUDE_TAGS, "users,weather",
+                        Headers.EXCLUDE_MCP_SERVERS, "everything,time"),
+                String.class);
+
+        mockEndpoint.assertIsSatisfied();
+        assertNotNull(response);
+        // With all tools excluded, the agent should not be able to use any 
tools
+        String lowerResponse = response.toLowerCase();
+        assertTrue(lowerResponse.contains("no tool") || 
lowerResponse.contains("don't have")
+                || lowerResponse.contains("do not have") || 
lowerResponse.contains("not available")
+                || lowerResponse.contains("cannot") || 
!lowerResponse.contains("add")
+                || !lowerResponse.contains("echo"),
+                "With all tools excluded, agent should indicate no tools are 
available but was: " + response);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        // Create agent with no tools at the agent level
+        AgentConfiguration config = new AgentConfiguration()
+                .withChatModel(chatModel);
+        Agent agent = new AgentWithoutMemory(config);
+
+        // Register agent and the pre-built MCP client bean in the registry
+        this.context.getRegistry().bind("myAgent", agent);
+        this.context.getRegistry().bind("timeMcpClient", timeClient);
+
+        // Get the MCP Everything Server Streamable HTTP URL from the 
test-infra service
+        String everythingUrl = MCP_EVERYTHING.url();
+
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                // Agent route combining 3 tool sources:
+                // 1. Camel route tools via tags (users, weather)
+                // 2. MCP Everything Server via endpoint URI config 
(mcpServer.everything.*)
+                // 3. MCP Time Server via pre-built bean reference 
(mcpClients=#timeMcpClient)
+                from("direct:chat")
+                        
.toF("langchain4j-agent:assistant?agent=#myAgent&tags=users,weather"
+                             + "&mcpServer.everything.transportType=http"
+                             + "&mcpServer.everything.url=%s"
+                             + "&mcpClients=#timeMcpClient",
+                                everythingUrl)
+                        .to("mock:response");
+
+                // Camel route tools (internal tools via 
camel-langchain4j-tools)
+                from("langchain4j-tools:userDb?tags=users"
+                     + "&description=Query user database by user ID"
+                     + "&parameter.userId=string")
+                        .setBody(constant(USER_DATABASE));
+
+                from("langchain4j-tools:weatherService?tags=weather"
+                     + "&description=Get current weather for a location"
+                     + "&parameter.location=string")
+                        .setBody(constant("{\"weather\": \"" + WEATHER_INFO + 
"\", \"location\": \"Current Location\"}"));
+            }
+        };
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/resources/log4j2.properties
 
b/components/camel-ai/camel-langchain4j-agent/src/test/resources/log4j2.properties
new file mode 100644
index 000000000000..500141398566
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/resources/log4j2.properties
@@ -0,0 +1,30 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-langchain4j-agent-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n
+
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Langchain4jAgentComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Langchain4jAgentComponentBuilderFactory.java
index 543885e06108..b4437aac5aaf 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Langchain4jAgentComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Langchain4jAgentComponentBuilderFactory.java
@@ -159,6 +159,44 @@ public interface Langchain4jAgentComponentBuilderFactory {
             doSetProperty("autowiredEnabled", autowiredEnabled);
             return this;
         }
+    
+        /**
+         * Pre-built MCP (Model Context Protocol) client instances for external
+         * tool integration. Reference beans from the registry, e.g.,
+         * #myMcpClient1,#myMcpClient2.
+         * 
+         * The option is a:
+         * 
&lt;code&gt;java.util.List&amp;lt;dev.langchain4j.mcp.client.McpClient&amp;gt;&lt;/code&gt;
 type.
+         * 
+         * Group: advanced
+         * 
+         * @param mcpClients the value to set
+         * @return the dsl builder
+         */
+        default Langchain4jAgentComponentBuilder 
mcpClients(java.util.List<dev.langchain4j.mcp.client.McpClient> mcpClients) {
+            doSetProperty("mcpClients", mcpClients);
+            return this;
+        }
+    
+        /**
+         * MCP server definitions in the form of mcpServer..=. Supported
+         * properties: transportType (stdio or http, default: stdio), command
+         * (comma-separated, for stdio), url (for http), environment.= (for
+         * stdio), timeout (in seconds, default: 60), logRequests, 
logResponses.
+         * This is a multi-value option with prefix: mcpServer.
+         * 
+         * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
+         * java.lang.Object&amp;gt;&lt;/code&gt; type.
+         * 
+         * Group: advanced
+         * 
+         * @param mcpServer the value to set
+         * @return the dsl builder
+         */
+        default Langchain4jAgentComponentBuilder 
mcpServer(java.util.Map<java.lang.String, java.lang.Object> mcpServer) {
+            doSetProperty("mcpServer", mcpServer);
+            return this;
+        }
     }
 
     class Langchain4jAgentComponentBuilderImpl
@@ -186,6 +224,8 @@ public interface Langchain4jAgentComponentBuilderFactory {
             case "lazyStartProducer": ((LangChain4jAgentComponent) 
component).setLazyStartProducer((boolean) value); return true;
             case "tags": getOrCreateConfiguration((LangChain4jAgentComponent) 
component).setTags((java.lang.String) value); return true;
             case "autowiredEnabled": ((LangChain4jAgentComponent) 
component).setAutowiredEnabled((boolean) value); return true;
+            case "mcpClients": 
getOrCreateConfiguration((LangChain4jAgentComponent) 
component).setMcpClients((java.util.List) value); return true;
+            case "mcpServer": 
getOrCreateConfiguration((LangChain4jAgentComponent) 
component).setMcpServer((java.util.Map) value); return true;
             default: return false;
             }
         }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
index 5bf843a02cf4..b49ecec2a956 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
@@ -178,6 +178,85 @@ public interface LangChain4jAgentEndpointBuilderFactory {
             doSetProperty("lazyStartProducer", lazyStartProducer);
             return this;
         }
+        /**
+         * Pre-built MCP (Model Context Protocol) client instances for external
+         * tool integration. Reference beans from the registry, e.g.,
+         * #myMcpClient1,#myMcpClient2.
+         * 
+         * The option is a:
+         * 
<code>java.util.List&lt;dev.langchain4j.mcp.client.McpClient&gt;</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param mcpClients the value to set
+         * @return the dsl builder
+         */
+        default AdvancedLangChain4jAgentEndpointBuilder 
mcpClients(List<dev.langchain4j.mcp.client.McpClient> mcpClients) {
+            doSetProperty("mcpClients", mcpClients);
+            return this;
+        }
+        /**
+         * Pre-built MCP (Model Context Protocol) client instances for external
+         * tool integration. Reference beans from the registry, e.g.,
+         * #myMcpClient1,#myMcpClient2.
+         * 
+         * The option will be converted to a
+         * 
<code>java.util.List&lt;dev.langchain4j.mcp.client.McpClient&gt;</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param mcpClients the value to set
+         * @return the dsl builder
+         */
+        default AdvancedLangChain4jAgentEndpointBuilder mcpClients(String 
mcpClients) {
+            doSetProperty("mcpClients", mcpClients);
+            return this;
+        }
+        /**
+         * MCP server definitions in the form of mcpServer..=. Supported
+         * properties: transportType (stdio or http, default: stdio), command
+         * (comma-separated, for stdio), url (for http), environment.= (for
+         * stdio), timeout (in seconds, default: 60), logRequests, 
logResponses.
+         * This is a multi-value option with prefix: mcpServer.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.Object&gt;</code> type.
+         * The option is multivalued, and you can use the mcpServer(String,
+         * Object) method to add a value (call the method multiple times to set
+         * more values).
+         * 
+         * Group: advanced
+         * 
+         * @param key the option key
+         * @param value the option value
+         * @return the dsl builder
+         */
+        default AdvancedLangChain4jAgentEndpointBuilder mcpServer(String key, 
Object value) {
+            doSetMultiValueProperty("mcpServer", "mcpServer." + key, value);
+            return this;
+        }
+        /**
+         * MCP server definitions in the form of mcpServer..=. Supported
+         * properties: transportType (stdio or http, default: stdio), command
+         * (comma-separated, for stdio), url (for http), environment.= (for
+         * stdio), timeout (in seconds, default: 60), logRequests, 
logResponses.
+         * This is a multi-value option with prefix: mcpServer.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.Object&gt;</code> type.
+         * The option is multivalued, and you can use the mcpServer(String,
+         * Object) method to add a value (call the method multiple times to set
+         * more values).
+         * 
+         * Group: advanced
+         * 
+         * @param values the values
+         * @return the dsl builder
+         */
+        default AdvancedLangChain4jAgentEndpointBuilder mcpServer(Map values) {
+            doSetMultiValueProperties("mcpServer", "mcpServer.", values);
+            return this;
+        }
     }
 
     public interface LangChain4jAgentBuilders {
@@ -296,6 +375,33 @@ public interface LangChain4jAgentEndpointBuilderFactory {
         public String langChain4jAgentMediaType() {
             return "CamelLangChain4jAgentMediaType";
         }
+        /**
+         * Comma-separated list of Camel tool tags to exclude from this agent
+         * invocation.
+         * 
+         * The option is a: {@code String} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code LangChain4jAgentExcludeTags}.
+         */
+        public String langChain4jAgentExcludeTags() {
+            return "CamelLangChain4jAgentExcludeTags";
+        }
+        /**
+         * Comma-separated list of MCP server names (keys) to exclude from this
+         * agent invocation.
+         * 
+         * The option is a: {@code String} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code
+         * LangChain4jAgentExcludeMcpServers}.
+         */
+        public String langChain4jAgentExcludeMcpServers() {
+            return "CamelLangChain4jAgentExcludeMcpServers";
+        }
     }
     static LangChain4jAgentEndpointBuilder endpointBuilder(String 
componentName, String path) {
         class LangChain4jAgentEndpointBuilderImpl extends 
AbstractEndpointBuilder implements LangChain4jAgentEndpointBuilder, 
AdvancedLangChain4jAgentEndpointBuilder {
diff --git a/test-infra/camel-test-infra-mcp-everything/pom.xml 
b/test-infra/camel-test-infra-mcp-everything/pom.xml
new file mode 100644
index 000000000000..a852f9d7955d
--- /dev/null
+++ b/test-infra/camel-test-infra-mcp-everything/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>camel-test-infra-parent</artifactId>
+        <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+        <version>4.19.0-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-test-infra-mcp-everything</artifactId>
+    <name>Camel :: Test Infra :: MCP Everything</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j2-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/common/McpEverythingProperties.java
 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/common/McpEverythingProperties.java
new file mode 100644
index 000000000000..e096bdf2cb1f
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/common/McpEverythingProperties.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.infra.mcp.everything.common;
+
+public final class McpEverythingProperties {
+    public static final String MCP_EVERYTHING_URL = "mcp.everything.url";
+    public static final String MCP_EVERYTHING_HOST = "mcp.everything.host";
+    public static final String MCP_EVERYTHING_PORT = "mcp.everything.port";
+    public static final String MCP_EVERYTHING_CONTAINER = 
"mcp.everything.container";
+    public static final int DEFAULT_PORT = 3001;
+
+    private McpEverythingProperties() {
+    }
+}
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingInfraService.java
 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingInfraService.java
new file mode 100644
index 000000000000..0ac69476249d
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingInfraService.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.infra.mcp.everything.services;
+
+import org.apache.camel.test.infra.common.services.InfrastructureService;
+
+/**
+ * Test infra service for the MCP Everything Server, which provides MCP tools 
via Streamable HTTP transport.
+ */
+public interface McpEverythingInfraService extends InfrastructureService {
+
+    String host();
+
+    int port();
+
+    /**
+     * Returns the Streamable HTTP endpoint URL for connecting an MCP client.
+     */
+    default String url() {
+        return String.format("http://%s:%d/mcp";, host(), port());
+    }
+}
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingLocalContainerInfraService.java
new file mode 100644
index 000000000000..6e409693a977
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingLocalContainerInfraService.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.infra.mcp.everything.services;
+
+import java.time.Duration;
+
+import org.apache.camel.spi.annotations.InfraService;
+import org.apache.camel.test.infra.common.LocalPropertyResolver;
+import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil;
+import org.apache.camel.test.infra.common.services.ContainerService;
+import 
org.apache.camel.test.infra.mcp.everything.common.McpEverythingProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ * Runs the MCP Everything Server as a Docker container in Streamable HTTP 
transport mode, exposing port 3001.
+ */
+@InfraService(service = McpEverythingInfraService.class,
+              description = "MCP Everything Server (Streamable HTTP 
transport)",
+              serviceAlias = { "mcp-everything" })
+public class McpEverythingLocalContainerInfraService
+        implements McpEverythingInfraService, 
ContainerService<GenericContainer<?>> {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(McpEverythingLocalContainerInfraService.class);
+
+    // Using tzolov/mcp-everything-server instead of the official 
mcp/everything image
+    // because the official image does not properly support HTTP/SSE transport 
mode
+    // (it only works reliably with stdio transport).
+    private static final String DEFAULT_CONTAINER = 
"tzolov/mcp-everything-server:v3";
+
+    private final GenericContainer<?> container;
+
+    public McpEverythingLocalContainerInfraService() {
+        
this(LocalPropertyResolver.getProperty(McpEverythingLocalContainerInfraService.class,
+                McpEverythingProperties.MCP_EVERYTHING_CONTAINER));
+    }
+
+    public McpEverythingLocalContainerInfraService(String imageName) {
+        container = initContainer(imageName);
+        String name = ContainerEnvironmentUtil.containerName(this.getClass());
+        if (name != null) {
+            container.withCreateContainerCmdModifier(cmd -> 
cmd.withName(name));
+        }
+    }
+
+    public McpEverythingLocalContainerInfraService(GenericContainer<?> 
container) {
+        this.container = container;
+    }
+
+    protected GenericContainer<?> initContainer(String imageName) {
+        String image = imageName != null ? imageName : DEFAULT_CONTAINER;
+
+        class TestInfraMcpEverythingContainer extends 
GenericContainer<TestInfraMcpEverythingContainer> {
+            public TestInfraMcpEverythingContainer(boolean fixedPort) {
+                super(DockerImageName.parse(image));
+
+                withCommand("node", "dist/index.js", "streamableHttp");
+                waitingFor(Wait.forLogMessage(".*listening on port.*\\n", 1))
+                        .withStartupTimeout(Duration.ofMinutes(2L));
+
+                ContainerEnvironmentUtil.configurePort(this, fixedPort, 
McpEverythingProperties.DEFAULT_PORT);
+            }
+        }
+
+        return new 
TestInfraMcpEverythingContainer(ContainerEnvironmentUtil.isFixedPort(this.getClass()));
+    }
+
+    @Override
+    public void registerProperties() {
+        System.setProperty(McpEverythingProperties.MCP_EVERYTHING_URL, url());
+        System.setProperty(McpEverythingProperties.MCP_EVERYTHING_HOST, 
host());
+        System.setProperty(McpEverythingProperties.MCP_EVERYTHING_PORT, 
String.valueOf(port()));
+    }
+
+    @Override
+    public void initialize() {
+        LOG.info("Trying to start the MCP Everything Server container");
+        container.start();
+
+        registerProperties();
+        LOG.info("MCP Everything Server running at {}", url());
+    }
+
+    @Override
+    public void shutdown() {
+        LOG.info("Stopping the MCP Everything Server container");
+        container.stop();
+    }
+
+    @Override
+    public GenericContainer<?> getContainer() {
+        return container;
+    }
+
+    @Override
+    public String host() {
+        return container.getHost();
+    }
+
+    @Override
+    public int port() {
+        return container.getMappedPort(McpEverythingProperties.DEFAULT_PORT);
+    }
+}
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingService.java
 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingService.java
new file mode 100644
index 000000000000..42ddfdd816c8
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingService.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.infra.mcp.everything.services;
+
+import org.apache.camel.test.infra.common.services.ContainerTestService;
+import org.apache.camel.test.infra.common.services.TestService;
+
+/**
+ * Test infra service for the MCP Everything Server.
+ */
+public interface McpEverythingService extends TestService, 
McpEverythingInfraService, ContainerTestService {
+}
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingServiceFactory.java
 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingServiceFactory.java
new file mode 100644
index 000000000000..597b46d53c20
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/java/org/apache/camel/test/infra/mcp/everything/services/McpEverythingServiceFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.infra.mcp.everything.services;
+
+import org.apache.camel.test.infra.common.services.SimpleTestServiceBuilder;
+
+public final class McpEverythingServiceFactory {
+
+    private McpEverythingServiceFactory() {
+    }
+
+    public static SimpleTestServiceBuilder<McpEverythingService> builder() {
+        return new SimpleTestServiceBuilder<>("mcp-everything");
+    }
+
+    public static McpEverythingService createService() {
+        return builder()
+                .addLocalMapping(McpEverythingLocalContainerService::new)
+                .build();
+    }
+
+    public static class McpEverythingLocalContainerService extends 
McpEverythingLocalContainerInfraService
+            implements McpEverythingService {
+    }
+}
diff --git 
a/test-infra/camel-test-infra-mcp-everything/src/main/resources/org/apache/camel/test/infra/mcp/everything/services/container.properties
 
b/test-infra/camel-test-infra-mcp-everything/src/main/resources/org/apache/camel/test/infra/mcp/everything/services/container.properties
new file mode 100644
index 000000000000..fab448187c43
--- /dev/null
+++ 
b/test-infra/camel-test-infra-mcp-everything/src/main/resources/org/apache/camel/test/infra/mcp/everything/services/container.properties
@@ -0,0 +1,18 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+mcp.everything.container=tzolov/mcp-everything-server:v3
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index a506707a54de..7d0f4ab17fe2 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -98,6 +98,7 @@
         <module>camel-test-infra-ibmmq</module>
         <module>camel-test-infra-docling</module>
         <module>camel-test-infra-iggy</module>
+        <module>camel-test-infra-mcp-everything</module>
         <module>camel-test-infra-all</module>
     </modules>
 

Reply via email to