This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-mcp-server.git
The following commit(s) were added to refs/heads/master by this push:
new 4085538 fix: require admin access for McpServlet (#10)
4085538 is described below
commit 4085538c1fb074e89c1ff2d031496a89810d5d79
Author: Robert Munteanu <[email protected]>
AuthorDate: Fri Mar 13 14:19:10 2026 +0100
fix: require admin access for McpServlet (#10)
---
README.md | 16 ++++++++++-
pom.xml | 5 ++++
.../apache/sling/mcp/server/impl/McpServlet.java | 33 ++++++++++++++++++++++
3 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b189d5d..ed82a21 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,21 @@ Then build and deploy the [MCP server contributions bundle
from the Sling Whiteb
$ mvn -f whiteboard/mcp-server-contributions/ install sling:install
```
-Then open up your coding assistant tool and add an remote MCP server with
location http://localhost:8080/mcp .
+Then open up your coding assistant tool and add an remote MCP server with
location http://localhost:8080/mcp . Access is only
+permitted for the `admin` user therefore basic authentication headers need to
be specified. In case of the default credentials
+the configuration can look as follows
+
+```json
+"aem-cs-sdk": {
+ "type": "streamable-http",
+ "url": "http://localhost:4502/bin/mcp",
+ "headers": {
+ "Authorization": "Basic YWRtaW46YWRtaW4="
+ }
+}
+```
+
+Please refer to the documentation of your coding assistant tool for details on
how to add a remote MCP server and specify authentication headers.
## Legacy artifact
diff --git a/pom.xml b/pom.xml
index be655a9..c76aa7b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,6 +121,11 @@
<artifactId>jakarta.servlet-api</artifactId>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-jackrabbit-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.http.wrappers</artifactId>
diff --git a/src/main/java/org/apache/sling/mcp/server/impl/McpServlet.java
b/src/main/java/org/apache/sling/mcp/server/impl/McpServlet.java
index d3a68d0..2cdfc72 100644
--- a/src/main/java/org/apache/sling/mcp/server/impl/McpServlet.java
+++ b/src/main/java/org/apache/sling/mcp/server/impl/McpServlet.java
@@ -18,8 +18,11 @@
*/
package org.apache.sling.mcp.server.impl;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
@@ -40,6 +43,8 @@ import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;
import org.apache.felix.http.jakartawrappers.HttpServletRequestWrapper;
import org.apache.felix.http.jakartawrappers.HttpServletResponseWrapper;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.User;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
@@ -218,6 +223,13 @@ public class McpServlet extends SlingAllMethodsServlet {
@Override
protected void doGet(@NotNull SlingHttpServletRequest request, @NotNull
SlingHttpServletResponse response)
throws ServletException, IOException {
+
+ User user = getCurrentUser(request);
+ if (user == null || !user.isAdmin()) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access
denied");
+ return;
+ }
+
try {
doGetMethod.invoke(
transportProvider,
@@ -230,9 +242,30 @@ public class McpServlet extends SlingAllMethodsServlet {
}
}
+ protected User getCurrentUser(SlingHttpServletRequest request) {
+ if (request.getResourceResolver().adaptTo(Session.class) instanceof
JackrabbitSession jcrSession) {
+
+ String userId = jcrSession.getUserID();
+
+ try {
+ return jcrSession.getUserManager().getAuthorizable(userId,
User.class);
+ } catch (RepositoryException e) {
+ logger.warn("Failed to retrieve user for ID {}, access will be
denied", userId, e);
+ }
+ }
+ return null;
+ }
+
@Override
protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull
SlingHttpServletResponse response)
throws ServletException, IOException {
+
+ User user = getCurrentUser(request);
+ if (user == null || !user.isAdmin()) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access
denied");
+ return;
+ }
+
try {
doPostMethod.invoke(
transportProvider,