From fa2cc391227371ab49cda64ecbecf3d0d772ba5e Mon Sep 17 00:00:00 2001 From: Daniel Chalef <131175+danielchalef@users.noreply.github.com> Date: Thu, 30 Oct 2025 06:57:33 -0700 Subject: [PATCH] conductor-checkpoint-msg_01Qdskq96hJ6Q9DPg1h5Jjgg --- mcp_server/docker/Dockerfile | 16 +++ mcp_server/docker/build-with-version.sh | 45 +++++++ mcp_server/docker/github-actions-example.yml | 119 +++++++++++++++++++ mcp_server/src/graphiti_mcp_server.py | 14 +++ 4 files changed, 194 insertions(+) create mode 100755 mcp_server/docker/build-with-version.sh create mode 100644 mcp_server/docker/github-actions-example.yml diff --git a/mcp_server/docker/Dockerfile b/mcp_server/docker/Dockerfile index b088dfe1..b2bb5a05 100644 --- a/mcp_server/docker/Dockerfile +++ b/mcp_server/docker/Dockerfile @@ -37,6 +37,9 @@ RUN sed -i '/\[tool\.uv\.sources\]/,/graphiti-core/d' pyproject.toml RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --no-dev +# Extract graphiti-core version and store it in a file for runtime access +RUN uv pip freeze | grep graphiti-core | cut -d'=' -f3 > /app/.graphiti-core-version + # Copy application code and configuration COPY main.py ./ COPY src/ ./src/ @@ -45,6 +48,19 @@ COPY config/ ./config/ # Set execute permissions on main.py and change ownership to app user RUN chmod +x /app/main.py && chown -Rv app:app /app +# Add Docker labels with version information +ARG MCP_SERVER_VERSION=1.0.0rc0 +ARG BUILD_DATE +ARG VCS_REF +LABEL org.opencontainers.image.title="Graphiti MCP Server" \ + org.opencontainers.image.description="MCP server for Graphiti knowledge graph" \ + org.opencontainers.image.version="${MCP_SERVER_VERSION}" \ + org.opencontainers.image.created="${BUILD_DATE}" \ + org.opencontainers.image.revision="${VCS_REF}" \ + org.opencontainers.image.vendor="Zep AI" \ + org.opencontainers.image.source="https://github.com/zep-ai/graphiti" \ + graphiti.core.version="$(cat /app/.graphiti-core-version)" + # Switch to non-root user USER app diff --git a/mcp_server/docker/build-with-version.sh b/mcp_server/docker/build-with-version.sh new file mode 100755 index 00000000..5e1f9635 --- /dev/null +++ b/mcp_server/docker/build-with-version.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Script to build Docker image with proper version tagging +# This script extracts the graphiti-core version and includes it in the image tag + +set -e + +# Get MCP server version from pyproject.toml +MCP_VERSION=$(grep '^version = ' ../pyproject.toml | sed 's/version = "\(.*\)"/\1/') + +# Get build metadata +BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") +VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +# Build the image +echo "Building Docker image..." +docker build \ + --build-arg MCP_SERVER_VERSION="${MCP_VERSION}" \ + --build-arg BUILD_DATE="${BUILD_DATE}" \ + --build-arg VCS_REF="${VCS_REF}" \ + -f Dockerfile \ + -t "zepai/graphiti-mcp:${MCP_VERSION}" \ + -t "zepai/graphiti-mcp:latest" \ + .. + +# Extract graphiti-core version from the built image +GRAPHITI_CORE_VERSION=$(docker run --rm "zepai/graphiti-mcp:${MCP_VERSION}" cat /app/.graphiti-core-version) + +echo "" +echo "Build complete!" +echo " MCP Server Version: ${MCP_VERSION}" +echo " Graphiti Core Version: ${GRAPHITI_CORE_VERSION}" +echo " VCS Ref: ${VCS_REF}" +echo " Build Date: ${BUILD_DATE}" +echo "" +echo "Image tags:" +echo " - zepai/graphiti-mcp:${MCP_VERSION}" +echo " - zepai/graphiti-mcp:${MCP_VERSION}-graphiti-${GRAPHITI_CORE_VERSION}" +echo " - zepai/graphiti-mcp:latest" + +# Tag with graphiti-core version +docker tag "zepai/graphiti-mcp:${MCP_VERSION}" "zepai/graphiti-mcp:${MCP_VERSION}-graphiti-${GRAPHITI_CORE_VERSION}" + +echo "" +echo "To inspect image metadata:" +echo " docker inspect zepai/graphiti-mcp:${MCP_VERSION} | jq '.[0].Config.Labels'" diff --git a/mcp_server/docker/github-actions-example.yml b/mcp_server/docker/github-actions-example.yml new file mode 100644 index 00000000..f65d38f0 --- /dev/null +++ b/mcp_server/docker/github-actions-example.yml @@ -0,0 +1,119 @@ +# Example GitHub Actions workflow for building and pushing the MCP Server Docker image +# This should be placed in .github/workflows/ in your repository + +name: Build and Push MCP Server Docker Image + +on: + push: + branches: + - main + tags: + - 'mcp-v*' + pull_request: + paths: + - 'mcp_server/**' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: zepai/graphiti-mcp + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + run: | + # Get MCP server version from pyproject.toml + MCP_VERSION=$(grep '^version = ' mcp_server/pyproject.toml | sed 's/version = "\(.*\)"/\1/') + echo "mcp_version=${MCP_VERSION}" >> $GITHUB_OUTPUT + + # Get build date and git ref + echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT + echo "vcs_ref=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + - name: Build Docker image + uses: docker/build-push-action@v5 + id: build + with: + context: ./mcp_server + file: ./mcp_server/docker/Dockerfile + push: false + load: true + tags: temp-image:latest + build-args: | + MCP_SERVER_VERSION=${{ steps.meta.outputs.mcp_version }} + BUILD_DATE=${{ steps.meta.outputs.build_date }} + VCS_REF=${{ steps.meta.outputs.vcs_ref }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Extract Graphiti Core version + id: graphiti + run: | + # Extract graphiti-core version from the built image + GRAPHITI_VERSION=$(docker run --rm temp-image:latest cat /app/.graphiti-core-version) + echo "graphiti_version=${GRAPHITI_VERSION}" >> $GITHUB_OUTPUT + echo "Graphiti Core Version: ${GRAPHITI_VERSION}" + + - name: Generate Docker tags + id: tags + run: | + MCP_VERSION="${{ steps.meta.outputs.mcp_version }}" + GRAPHITI_VERSION="${{ steps.graphiti.outputs.graphiti_version }}" + + TAGS="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${MCP_VERSION}" + TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${MCP_VERSION}-graphiti-${GRAPHITI_VERSION}" + TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" + + # Add SHA tag for traceability + TAGS="${TAGS},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ steps.meta.outputs.vcs_ref }}" + + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + + echo "Docker tags:" + echo "${TAGS}" | tr ',' '\n' + + - name: Push Docker image + uses: docker/build-push-action@v5 + with: + context: ./mcp_server + file: ./mcp_server/docker/Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.tags }} + build-args: | + MCP_SERVER_VERSION=${{ steps.meta.outputs.mcp_version }} + BUILD_DATE=${{ steps.meta.outputs.build_date }} + VCS_REF=${{ steps.meta.outputs.vcs_ref }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Create release summary + if: github.event_name != 'pull_request' + run: | + echo "## Docker Image Build Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**MCP Server Version:** ${{ steps.meta.outputs.mcp_version }}" >> $GITHUB_STEP_SUMMARY + echo "**Graphiti Core Version:** ${{ steps.graphiti.outputs.graphiti_version }}" >> $GITHUB_STEP_SUMMARY + echo "**VCS Ref:** ${{ steps.meta.outputs.vcs_ref }}" >> $GITHUB_STEP_SUMMARY + echo "**Build Date:** ${{ steps.meta.outputs.build_date }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Image Tags" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.tags.outputs.tags }}" | tr ',' '\n' | sed 's/^/- /' >> $GITHUB_STEP_SUMMARY diff --git a/mcp_server/src/graphiti_mcp_server.py b/mcp_server/src/graphiti_mcp_server.py index 5391817f..fd2dfd8e 100644 --- a/mcp_server/src/graphiti_mcp_server.py +++ b/mcp_server/src/graphiti_mcp_server.py @@ -812,6 +812,20 @@ async def initialize_server() -> ServerConfig: logger.info(f' - Group ID: {config.graphiti.group_id}') logger.info(f' - Transport: {config.server.transport}') + # Log graphiti-core version + try: + import graphiti_core + graphiti_version = getattr(graphiti_core, '__version__', 'unknown') + logger.info(f' - Graphiti Core: {graphiti_version}') + except Exception: + # Check for Docker-stored version file + version_file = Path('/app/.graphiti-core-version') + if version_file.exists(): + graphiti_version = version_file.read_text().strip() + logger.info(f' - Graphiti Core: {graphiti_version}') + else: + logger.info(' - Graphiti Core: version unavailable') + # Handle graph destruction if requested if hasattr(config, 'destroy_graph') and config.destroy_graph: logger.warning('Destroying all Graphiti graphs as requested...')