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

Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git


The following commit(s) were added to refs/heads/main by this push:
     new 7610a717ffd CAMEL-24507: camel-mcp-server-starter - correct the 
authentication claim in the docs
7610a717ffd is described below

commit 7610a717ffd5d579ffafdb04b8cb74e1ff8d23d9
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Aug 28 09:57:42 2026 +0200

    CAMEL-24507: camel-mcp-server-starter - correct the authentication claim in 
the docs
    
    The starter's javadoc and intro documentation listed authentication among 
the
    serving concerns owned by the Spring AI MCP server and configured via
    spring.ai.mcp.server.*. That namespace has no authentication property, so a
    reader following the sentence would look for a knob that does not exist and 
may
    conclude the endpoint is covered when it is not.
    
    The claim is removed from McpServerConfigurationProperties, 
SpringAiMcpServerEngine
    and intro.adoc, and intro.adoc gains a "Securing the MCP endpoint" section 
with a
    Spring Security filter chain example.
    
    The default posture is unchanged and remains sound: tags default to null 
and the
    untagged pool is never served, so nothing is exposed until an operator opts 
in.
    When they do, one INFO line at startup now says so and points at securing 
the
    endpoint - not WARN, which would fire on every legitimate deployment.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../src/main/doc/intro.adoc                        | 34 ++++++++++++++++++++--
 .../server/CamelMcpServerAutoConfiguration.java    | 12 ++++++++
 .../server/McpServerConfigurationProperties.java   |  8 +++--
 .../mcp/server/SpringAiMcpServerEngine.java        |  3 +-
 .../modules/ROOT/pages/starters/mcp-server.adoc    | 34 ++++++++++++++++++++--
 5 files changed, 84 insertions(+), 7 deletions(-)

diff --git 
a/components-starter/camel-mcp-server-starter/src/main/doc/intro.adoc 
b/components-starter/camel-mcp-server-starter/src/main/doc/intro.adoc
index 4af6d66884c..1c94a3143f4 100644
--- a/components-starter/camel-mcp-server-starter/src/main/doc/intro.adoc
+++ b/components-starter/camel-mcp-server-starter/src/main/doc/intro.adoc
@@ -9,6 +9,36 @@ Tool semantics — tag-based opt-in (the untagged default pool 
is never
 exposed), flat-namespace collision refusal, per-call timeout and error
 sanitization — are owned by the runtime-agnostic `camel-mcp-server-api`
 bridge and are identical on every Camel runtime. Serving concerns (endpoint
-path, protocol, server identity, authentication) are owned by the Spring AI
-MCP server and configured via `spring.ai.mcp.server.*`; use
+path, protocol, server identity) are owned by the Spring AI MCP server and
+configured via `spring.ai.mcp.server.*`; use
 `spring.ai.mcp.server.protocol=STREAMABLE` for the streamable HTTP transport.
+
+== Securing the MCP endpoint
+
+`spring.ai.mcp.server.*` provides **no authentication**. The MCP endpoint is
+served on the application's own HTTP port, and anything that can reach it can
+list and call every exposed tool. Protecting it is the application's
+responsibility.
+
+Nothing is exposed until `camel.mcp-server.tags` is set — the untagged default
+pool is never served — so the surface is opt-in. Once tags are configured,
+secure the endpoint path, for example with a Spring Security filter chain:
+
+[source,java]
+----
+@Bean
+SecurityFilterChain mcpSecurity(HttpSecurity http) throws Exception {
+    return http.securityMatcher("/mcp/**")
+            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
+            .oauth2ResourceServer(oauth2 -> 
oauth2.jwt(Customizer.withDefaults()))
+            .build();
+}
+----
+
+Adjust the matcher to whatever `spring.ai.mcp.server` is configured to serve 
on.
+A network policy that keeps the port off untrusted networks is an alternative
+where the deployment allows it.
+
+See the camel-mcp-server component documentation for the trust boundary this
+sits in: external MCP clients are untrusted senders under the Camel security
+model.
diff --git 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/CamelMcpServerAutoConfiguration.java
 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/CamelMcpServerAutoConfiguration.java
index 4c9c1bac7f2..f2f3b3c00f9 100644
--- 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/CamelMcpServerAutoConfiguration.java
+++ 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/CamelMcpServerAutoConfiguration.java
@@ -22,6 +22,8 @@ import org.apache.camel.component.mcp.server.McpServerBridge;
 import org.apache.camel.component.mcp.server.McpServerConfiguration;
 import org.apache.camel.component.mcp.server.McpServerEngine;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -40,6 +42,8 @@ import org.springframework.context.annotation.Bean;
 @EnableConfigurationProperties(McpServerConfigurationProperties.class)
 public class CamelMcpServerAutoConfiguration {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(CamelMcpServerAutoConfiguration.class);
+
     @Bean(initMethod = "", destroyMethod = "")
     // Camel handles the lifecycle of this bean
     @ConditionalOnMissingBean(McpServerEngine.class)
@@ -58,6 +62,14 @@ public class CamelMcpServerAutoConfiguration {
         configuration.setToolTimeout(properties.getToolTimeout());
         McpServerBridge bridge = new McpServerBridge(configuration);
         camelContext.addService(bridge);
+        if (properties.getTags() != null && !properties.getTags().isBlank()) {
+            // exposing tools is opt-in, but once opted in the endpoint is 
reachable by anything that can reach
+            // the application HTTP port - spring.ai.mcp.server.* has no 
authentication of its own
+            LOG.info("Exposing ai-tool routes tagged [{}] as MCP tools. The 
MCP endpoint is served on the"
+                     + " application HTTP port and is not authenticated by the 
Spring AI MCP server; secure it in"
+                     + " the application, for example with a Spring Security 
filter chain on its path.",
+                    properties.getTags());
+        }
         return bridge;
     }
 }
diff --git 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/McpServerConfigurationProperties.java
 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/McpServerConfigurationProperties.java
index b5023fe62b4..2a35b7e6472 100644
--- 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/McpServerConfigurationProperties.java
+++ 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/McpServerConfigurationProperties.java
@@ -19,8 +19,12 @@ package org.apache.camel.springboot.mcp.server;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
 /**
- * Bridge-owned configuration of the Camel MCP server. Serving concerns 
(endpoint path, protocol, server identity,
- * authentication) are owned by the Spring AI MCP server and configured via 
{@code spring.ai.mcp.server.*}.
+ * Bridge-owned configuration of the Camel MCP server. Serving concerns 
(endpoint path, protocol, server identity)
+ * are owned by the Spring AI MCP server and configured via {@code 
spring.ai.mcp.server.*}.
+ * <p/>
+ * Note that {@code spring.ai.mcp.server.*} provides no authentication: the 
MCP endpoint is served on the
+ * application's own HTTP port and must be protected by the application, for 
example with a Spring Security filter
+ * chain matching the endpoint path.
  */
 @ConfigurationProperties(prefix = "camel.mcp-server")
 public class McpServerConfigurationProperties {
diff --git 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/SpringAiMcpServerEngine.java
 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/SpringAiMcpServerEngine.java
index 1728fd4fd9a..1f8939af346 100644
--- 
a/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/SpringAiMcpServerEngine.java
+++ 
b/components-starter/camel-mcp-server-starter/src/main/java/org/apache/camel/springboot/mcp/server/SpringAiMcpServerEngine.java
@@ -37,7 +37,8 @@ import org.slf4j.LoggerFactory;
  * {@link McpServerEngine} publishing tools into the Spring AI MCP server: 
{@code toolAdded}/{@code toolRemoved} map to
  * the auto-configured {@link McpSyncServer}'s {@code addTool}/{@code 
removeTool}, which emit
  * {@code notifications/tools/list_changed} to connected clients. Serving 
concerns (endpoint path, protocol, server
- * identity, authentication) are owned by the Spring AI MCP server 
configuration ({@code spring.ai.mcp.server.*}).
+ * identity) are owned by the Spring AI MCP server configuration ({@code 
spring.ai.mcp.server.*}), which provides
+ * no authentication - the endpoint must be protected by the application.
  */
 public class SpringAiMcpServerEngine extends ServiceSupport implements 
McpServerEngine {
 
diff --git a/docs/spring-boot/modules/ROOT/pages/starters/mcp-server.adoc 
b/docs/spring-boot/modules/ROOT/pages/starters/mcp-server.adoc
index bd465cb2b0b..73f5c698eb2 100644
--- a/docs/spring-boot/modules/ROOT/pages/starters/mcp-server.adoc
+++ b/docs/spring-boot/modules/ROOT/pages/starters/mcp-server.adoc
@@ -14,10 +14,40 @@ Tool semantics — tag-based opt-in (the untagged default 
pool is never
 exposed), flat-namespace collision refusal, per-call timeout and error
 sanitization — are owned by the runtime-agnostic `camel-mcp-server-api`
 bridge and are identical on every Camel runtime. Serving concerns (endpoint
-path, protocol, server identity, authentication) are owned by the Spring AI
-MCP server and configured via `spring.ai.mcp.server.*`; use
+path, protocol, server identity) are owned by the Spring AI MCP server and
+configured via `spring.ai.mcp.server.*`; use
 `spring.ai.mcp.server.protocol=STREAMABLE` for the streamable HTTP transport.
 
+== Securing the MCP endpoint
+
+`spring.ai.mcp.server.*` provides **no authentication**. The MCP endpoint is
+served on the application's own HTTP port, and anything that can reach it can
+list and call every exposed tool. Protecting it is the application's
+responsibility.
+
+Nothing is exposed until `camel.mcp-server.tags` is set — the untagged default
+pool is never served — so the surface is opt-in. Once tags are configured,
+secure the endpoint path, for example with a Spring Security filter chain:
+
+[source,java]
+----
+@Bean
+SecurityFilterChain mcpSecurity(HttpSecurity http) throws Exception {
+    return http.securityMatcher("/mcp/**")
+            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
+            .oauth2ResourceServer(oauth2 -> 
oauth2.jwt(Customizer.withDefaults()))
+            .build();
+}
+----
+
+Adjust the matcher to whatever `spring.ai.mcp.server` is configured to serve 
on.
+A network policy that keeps the port off untrusted networks is an alternative
+where the deployment allows it.
+
+See the camel-mcp-server component documentation for the trust boundary this
+sits in: external MCP clients are untrusted senders under the Camel security
+model.
+
 == Maven coordinates
 
 [source,xml]

Reply via email to