diff --git a/src/main/java/org/caosdb/server/grpc/ServerSideScriptingServiceImpl.java b/src/main/java/org/caosdb/server/grpc/ServerSideScriptingServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea68d8f7fbbdbcc630d6987ae2531dd5366e405b
--- /dev/null
+++ b/src/main/java/org/caosdb/server/grpc/ServerSideScriptingServiceImpl.java
@@ -0,0 +1,123 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2025 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2025 Joscha Schmiedt <joscha@schmiedt.dev>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.caosdb.server.grpc;
+
+import com.google.protobuf.Timestamp;
+import io.grpc.Status;
+import io.grpc.StatusException;
+import io.grpc.stub.StreamObserver;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.apache.shiro.subject.Subject;
+import org.caosdb.api.scripting.v1alpha1.ExecuteServerSideScriptRequest;
+import org.caosdb.api.scripting.v1alpha1.ExecuteServerSideScriptResponse;
+import org.caosdb.api.scripting.v1alpha1.ServerSideScriptExecutionId;
+import org.caosdb.api.scripting.v1alpha1.ServerSideScriptExecutionResult;
+import org.caosdb.api.scripting.v1alpha1.ServerSideScriptingServiceGrpc.ServerSideScriptingServiceImplBase;
+import org.caosdb.server.accessControl.AuthenticationUtils;
+import org.caosdb.server.utils.ServerMessages;
+
+/**
+ * Main entry point for the server-side scripting service of the server's GRPC API.
+ *
+ * @author Joscha Schmiedt <joscha@schmiedt.dev>
+ */
+public class ServerSideScriptingServiceImpl extends ServerSideScriptingServiceImplBase {
+
+  @Override
+  public void executeServerSideScript(
+      ExecuteServerSideScriptRequest request,
+      io.grpc.stub.StreamObserver<org.caosdb.api.scripting.v1alpha1.ExecuteServerSideScriptResponse>
+          responseObserver) {
+    // ServerSideScriptingCaller caller = new ServerSideScriptingCaller()
+    // caller.executeServerSideScript(request, responseObserver);
+    try {
+      AuthInterceptor.bindSubject();
+      ExecuteServerSideScriptResponse response = executeScript(request);
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+
+    } catch (final Exception e) {
+      ServerSideScriptingServiceImpl.handleException(responseObserver, e);
+    }
+  }
+
+  private ExecuteServerSideScriptResponse executeScript(ExecuteServerSideScriptRequest request) {
+
+    String scriptExecutionId = "";
+    String scriptFilename = "";
+    ServerSideScriptExecutionResult result =
+        ServerSideScriptExecutionResult.SERVER_SIDE_SCRIPT_EXECUTION_RESULT_GENERAL_FAILURE;
+    int returnCode = 1;
+    String stdout = "";
+    String stderr = "";
+    Timestamp startTime = Timestamp.newBuilder().setSeconds(0).setNanos(0).build();
+    Timestamp endTime = Timestamp.newBuilder().setSeconds(0).setNanos(0).build();
+    int duration_ms = 0;
+
+    final ExecuteServerSideScriptResponse response =
+        ExecuteServerSideScriptResponse.newBuilder()
+            .setScriptExecutionId(
+                ServerSideScriptExecutionId.newBuilder()
+                    .setScriptExecutionId(scriptExecutionId)
+                    .build())
+            .setScriptFilename(scriptFilename)
+            .setResult(result)
+            .setReturnCode(returnCode)
+            .setStdout(stdout)
+            .setStderr(stderr)
+            .setStartTime(startTime)
+            .setEndTime(endTime)
+            .setDurationMs(duration_ms)
+            .build();
+    return response;
+  }
+
+  public static void handleException(StreamObserver<?> responseObserver, Exception e) {
+    String description = e.getMessage();
+    if (description == null || description.isBlank()) {
+      description = "Unknown Error. Please Report!";
+    }
+    if (e instanceof UnauthorizedException) {
+      Subject subject = SecurityUtils.getSubject();
+      if (AuthenticationUtils.isAnonymous(subject)) {
+        responseObserver.onError(new StatusException(AuthInterceptor.PLEASE_LOG_IN));
+        return;
+      } else {
+        responseObserver.onError(
+            new StatusException(
+                Status.PERMISSION_DENIED.withCause(e).withDescription(description)));
+        return;
+      }
+    } else if (e == ServerMessages.ROLE_DOES_NOT_EXIST
+        || e == ServerMessages.ACCOUNT_DOES_NOT_EXIST) {
+      responseObserver.onError(
+          new StatusException(Status.NOT_FOUND.withDescription(description).withCause(e)));
+      return;
+    }
+    // TODO: SERVER_SIDE_DOES_NOT_EXIST, SERVER_SIDE_SCRIPT_NOT_EXECUTABLE,
+    // SERVER_SIDE_SCRIPT_ERROR, SERVER_SIDE_SCRIPT_SETUP_ERROR,
+    // SERVER_SIDE_SCRIPT_TIMEOUT, SERVER_SIDE_SCRIPT_MISSING_CALL
+    e.printStackTrace();
+    responseObserver.onError(
+        new StatusException(Status.UNKNOWN.withDescription(description).withCause(e)));
+  }
+}