From 386fd9fbcc1539abff0649d76b9e2dc38fefa9bb Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Fri, 30 Jan 2026 17:02:10 -0800 Subject: [PATCH 1/3] chore: ignore .serena cache directories --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0c6fe32b1..b595d6d09 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ test/serena-mcp-tests/results-gateway/ test/serena-mcp-tests/**/__pycache__/ test/serena-mcp-tests/**/*.pyc scripts/rebase-github-difc.sh + +# Serena cache directories +.serena/ From 6f4befa21b8504df5396b07f5f358843acc40393 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Fri, 30 Jan 2026 17:11:38 -0800 Subject: [PATCH 2/3] Added serena to images to pre-download --- .github/workflows/smoke-copilot.lock.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 0fb5c53b3..fdb84f776 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -202,7 +202,7 @@ jobs: const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh alpine:latest ghcr.io/github/github-mcp-server:v0.28.1 ghcr.io/githubnext/gh-aw-mcpg:latest mcr.microsoft.com/playwright/mcp node:lts-alpine + run: bash /opt/gh-aw/actions/download_docker_images.sh alpine:latest ghcr.io/github/github-mcp-server:v0.28.1 ghcr.io/githubnext/gh-aw-mcpg:latest mcr.microsoft.com/playwright/mcp node:lts-alpine ghcr.io/githubnext/serena-mcp-server:latest - name: Install gh-aw extension env: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} From 6e0bdcd47a1dedff2a4d71aada65a75210c60db2 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Fri, 30 Jan 2026 17:32:46 -0800 Subject: [PATCH 3/3] feat(serena): slim Docker image with multi-stage build Reduce image size from 2.59GB to 694MB (73% reduction): - Use multi-stage build to compile gopls in alpine, copy binary only - Remove Java JDK (not needed for codex context) - Remove build-essential, golang-go runtime (only need gopls binary) - Remove python-lsp-server, pylsp-mypy (Serena bundles pyright) - Remove curl, wget (not needed at runtime) Also update test script to use slim image by default and allow override via SERENA_IMAGE environment variable. --- containers/serena-mcp-server/Dockerfile | 69 +++++++------------ .../serena-mcp-server/test-startup-time.sh | 2 +- 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/containers/serena-mcp-server/Dockerfile b/containers/serena-mcp-server/Dockerfile index 96b67c023..b7a08064f 100644 --- a/containers/serena-mcp-server/Dockerfile +++ b/containers/serena-mcp-server/Dockerfile @@ -1,11 +1,17 @@ -# Serena MCP Server Container Image -# Provides AI-powered code intelligence with support for Python, Java, JavaScript/TypeScript, and Go +# Serena MCP Server Container Image (Slim) +# Optimized for Python, Go, and TypeScript support with minimal image size +# Stage 1: Build gopls +FROM golang:1.24-alpine AS gopls-builder +# Pin to gopls v0.17.1 which is compatible with Go 1.24 +RUN go install golang.org/x/tools/gopls@v0.17.1 + +# Stage 2: Final image FROM python:3.11-slim # OCI labels for GitHub Container Registry LABEL org.opencontainers.image.title="Serena MCP Server" -LABEL org.opencontainers.image.description="A containerized MCP server with semantic code analysis for Python, Java, JavaScript/TypeScript, and Go" +LABEL org.opencontainers.image.description="A containerized MCP server with semantic code analysis for Python, Go, and TypeScript" LABEL org.opencontainers.image.source="https://github.com/githubnext/gh-aw-mcpg/tree/main/containers/serena-mcp-server" LABEL org.opencontainers.image.documentation="https://github.com/githubnext/gh-aw-mcpg/blob/main/containers/serena-mcp-server/README.md" LABEL org.opencontainers.image.url="https://github.com/githubnext/gh-aw-mcpg/pkgs/container/serena-mcp-server" @@ -14,53 +20,29 @@ LABEL org.opencontainers.image.vendor="GitHub" # Set working directory WORKDIR /app -# Install system dependencies required for language servers and build tools +# Install minimal system dependencies +# - git: required for some Serena operations +# - nodejs/npm: for TypeScript language server +# - ca-certificates: for HTTPS RUN apt-get update && apt-get install -y --no-install-recommends \ - # Build essentials - build-essential \ git \ - curl \ - wget \ - # Java Development Kit (for Java language support and compilation) - default-jdk \ - # Node.js (for JavaScript/TypeScript language support) nodejs \ npm \ - # Go runtime (for Go language support) - golang-go \ - # Additional utilities ca-certificates \ && rm -rf /var/lib/apt/lists/* \ - && update-ca-certificates + && apt-get clean -# Set environment variables for language runtimes -ENV JAVA_HOME=/usr/lib/jvm/default-java -ENV PATH="${JAVA_HOME}/bin:${PATH}" -ENV GOPATH=/go -ENV PATH="${GOPATH}/bin:${PATH}" +# Copy pre-built gopls from builder stage +COPY --from=gopls-builder /go/bin/gopls /usr/local/bin/gopls -# Install Serena MCP server from GitHub using pip -# Serena is a Python package, so we can install it directly -# Try GitHub first, then fall back to PyPI package name if available +# Install Serena MCP server from GitHub RUN pip install --no-cache-dir git+https://github.com/oraios/serena.git || \ (echo "GitHub installation failed, trying PyPI..." && \ pip install --no-cache-dir serena-agent) -# Install common language servers that Serena may need -# These are installed globally to be available to Serena -RUN npm install -g \ - typescript \ - typescript-language-server \ - && rm -rf /root/.npm - -# Install Python language server (pyright is included in Serena dependencies) -# Additional Python tools -RUN pip install --no-cache-dir \ - python-lsp-server \ - pylsp-mypy - -# Install gopls (Go language server) -RUN go install golang.org/x/tools/gopls@latest +# Install TypeScript language server (minimal) +RUN npm install -g typescript typescript-language-server && \ + rm -rf /root/.npm /tmp/* # Create directories for Serena configuration and caching RUN mkdir -p /workspace /tmp/serena-cache /root/.serena @@ -70,30 +52,25 @@ ENV SERENA_WORKSPACE=/workspace ENV SERENA_CACHE_DIR=/tmp/serena-cache # Create a dummy project to pre-warm Serena's LSP cache -# This initializes the language servers and caches so they're ready at runtime -# Focus on Python, Go, and TypeScript which are the primary languages for codex context +# Focus on Python, Go, and TypeScript for codex context RUN mkdir -p /tmp/dummy-project && \ echo 'def hello(): pass' > /tmp/dummy-project/main.py && \ echo 'package main\nfunc main() {}' > /tmp/dummy-project/main.go && \ echo 'export function hello() {}' > /tmp/dummy-project/index.ts -# Pre-index the dummy project to warm up the LSP caches -# Use --language to specify languages non-interactively and --index to index after creation -# This ensures pyright, gopls, and typescript-language-server are initialized +# Pre-index to warm up LSP caches RUN serena project create /tmp/dummy-project --name dummy \ --language python --language go --language typescript \ --index --log-level INFO --timeout 120 || \ echo "Pre-indexing completed (some warnings may be expected)" -# Clean up the dummy project but keep the caches +# Clean up RUN rm -rf /tmp/dummy-project # Expose the workspace directory as a volume mount point VOLUME ["/workspace"] # Set default entrypoint to run Serena MCP server -# This will start the MCP server on stdio transport ENTRYPOINT ["serena-mcp-server"] -# Default arguments (can be overridden) CMD [] diff --git a/containers/serena-mcp-server/test-startup-time.sh b/containers/serena-mcp-server/test-startup-time.sh index 8d42b43fc..e3e57a5f8 100755 --- a/containers/serena-mcp-server/test-startup-time.sh +++ b/containers/serena-mcp-server/test-startup-time.sh @@ -38,7 +38,7 @@ export MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') export WORKSPACE="${WORKSPACE_ARG:-${PWD}}" GATEWAY_IMAGE="ghcr.io/githubnext/gh-aw-mcpg:v0.0.84" -SERENA_IMAGE="serena-mcp-server:test" +SERENA_IMAGE="${SERENA_IMAGE:-serena-mcp-server:slim}" echo "=== Serena Startup Time Test ===" echo "Gateway image: ${GATEWAY_IMAGE}"