Migration from Docker to Standalone Python Server (#73)

* Migration from docker to standalone server
Migration handling
Fixed tests
Use simpler in-memory storage
Support for concurrent logging to disk
Simplified direct connections to localhost

* Migration from docker / redis to standalone script
Updated tests
Updated run script
Fixed requirements
Use dotenv
Ask if user would like to install MCP in Claude Desktop once
Updated docs

* More cleanup and references to docker removed

* Cleanup

* Comments

* Fixed tests

* Fix GitHub Actions workflow for standalone Python architecture

- Install requirements-dev.txt for pytest and testing dependencies
- Remove Docker setup from simulation tests (now standalone)
- Simplify linting job to use requirements-dev.txt
- Update simulation tests to run directly without Docker

Fixes unit test failures in CI due to missing pytest dependency.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove simulation tests from GitHub Actions

- Removed simulation-tests job that makes real API calls
- Keep only unit tests (mocked, no API costs) and linting
- Simulation tests should be run manually with real API keys
- Reduces CI costs and complexity

GitHub Actions now only runs:
- Unit tests (569 tests, all mocked)
- Code quality checks (ruff, black)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fixed tests

* Fixed tests

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Beehive Innovations
2025-06-18 23:41:22 +04:00
committed by GitHub
parent 9d72545ecd
commit 4151c3c3a5
121 changed files with 2842 additions and 3168 deletions

View File

@@ -11,8 +11,8 @@ body:
id: version
attributes:
label: Project Version
description: "Which version are you using? (e.g., Docker image tag like `latest` or `v1.2.3`, or a git commit SHA)"
placeholder: "e.g., ghcr.io/beehiveinnovations/zen-mcp-server:latest"
description: "Which version are you using? (To see version: ./run-server.sh -v)"
placeholder: "e.g., 5.1.0"
validations:
required: true
@@ -29,7 +29,7 @@ body:
id: logs
attributes:
label: Relevant Log Output
description: "Please copy and paste any relevant log output. You can obtain these from the MCP folder by running `docker compose logs`."
description: "Please copy and paste any relevant log output. Logs are stored under the `logs` folder in the zen folder. You an also use `./run-server.sh -f` to see logs"
render: shell
- type: dropdown

View File

@@ -33,7 +33,7 @@ body:
attributes:
label: What is wrong with the documentation?
description: "Please describe the problem. Be specific about what is unclear, incorrect, or missing."
placeholder: "The Docker setup command in the README is missing the `--pull=always` flag, which means users might use an outdated image version."
placeholder: "README is missing some details"
validations:
required: true
@@ -42,16 +42,8 @@ body:
attributes:
label: Suggested Improvement
description: "How can we make it better? If you can, please provide the exact text or changes you'd like to see."
placeholder: |
Change:
```
docker run ghcr.io/beehiveinnovations/zen-mcp-server:latest
```
To:
```
docker run --pull=always ghcr.io/beehiveinnovations/zen-mcp-server:latest
```
placeholder: "Please improve...."
- type: dropdown
id: audience

View File

@@ -33,7 +33,7 @@ body:
label: Feature Category
description: What type of enhancement is this?
options:
- New Gemini tool (chat, codereview, debug, etc.)
- New tool (chat, codereview, debug, etc.)
- Workflow improvement
- Integration enhancement
- Performance optimization

View File

@@ -1,12 +1,12 @@
name: 🛠️ New Gemini Tool Proposal
description: Propose a new Gemini MCP tool (e.g., `summarize`, `testgen`, `refactor`)
description: Propose a new Zen MCP tool (e.g., `summarize`, `fixer`, `refactor`)
labels: ["enhancement", "new-tool"]
body:
- type: input
id: tool-name
attributes:
label: Proposed Tool Name
description: "What would the tool be called? (e.g., `summarize`, `testgen`, `refactor`)"
description: "What would the tool be called? (e.g., `summarize`, `docgen`, `refactor`)"
placeholder: "e.g., `docgen`"
validations:
required: true
@@ -15,7 +15,7 @@ body:
id: purpose
attributes:
label: What is the primary purpose of this tool?
description: "Explain the tool's core function and the value it provides to developers using Claude + Gemini."
description: "Explain the tool's core function and the value it provides to developers using Claude + Zen."
placeholder: "This tool will automatically generate comprehensive documentation from code, extracting class and function signatures, docstrings, and creating usage examples."
validations:
required: true
@@ -27,9 +27,9 @@ body:
description: "Show how a user would invoke this tool through Claude and what the expected output would look like."
placeholder: |
**User prompt to Claude:**
"Use gemini to generate documentation for my entire src/ directory"
"Use zen to generate documentation for my entire src/ directory"
**Expected Gemini tool behavior:**
**Expected behavior:**
- Analyze all Python files in src/
- Extract classes, functions, and their docstrings
- Generate structured markdown documentation
@@ -61,7 +61,7 @@ body:
id: system-prompt
attributes:
label: Proposed System Prompt (Optional)
description: "If you have ideas for how Gemini should be prompted for this tool, share them here."
description: "If you have ideas for how zen should be prompted for this tool, share them here."
placeholder: |
You are an expert technical documentation generator. Your task is to create comprehensive, user-friendly documentation from source code...

View File

@@ -1,197 +0,0 @@
name: Build and Publish Docker Image to GHCR
on:
push:
tags: [ 'v*' ]
repository_dispatch:
types: [docker-build]
env:
REGISTRY: ghcr.io
IMAGE_NAME: beehiveinnovations/zen-mcp-server
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
attestations: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
type=sha,prefix=main-,enable=${{ github.event_name == 'repository_dispatch' }}
type=raw,value=pr-${{ github.event.client_payload.pr_number }},enable=${{ github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number != '' }}
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
- name: Generate usage instructions
run: |
echo "## 🐳 Docker Image Published Successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image Registry:** GitHub Container Registry (GHCR)" >> $GITHUB_STEP_SUMMARY
echo "**Built Tags:** ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Extract the first tag for the main pull command
MAIN_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "### 📥 Pull the Image" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull $MAIN_TAG" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ⚙️ Claude Desktop Configuration" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`json" >> $GITHUB_STEP_SUMMARY
echo "{" >> $GITHUB_STEP_SUMMARY
echo " \"mcpServers\": {" >> $GITHUB_STEP_SUMMARY
echo " \"gemini\": {" >> $GITHUB_STEP_SUMMARY
echo " \"command\": \"docker\"," >> $GITHUB_STEP_SUMMARY
echo " \"args\": [" >> $GITHUB_STEP_SUMMARY
echo " \"run\", \"--rm\", \"-i\"," >> $GITHUB_STEP_SUMMARY
echo " \"-e\", \"GEMINI_API_KEY\"," >> $GITHUB_STEP_SUMMARY
echo " \"$MAIN_TAG\"" >> $GITHUB_STEP_SUMMARY
echo " ]," >> $GITHUB_STEP_SUMMARY
echo " \"env\": {" >> $GITHUB_STEP_SUMMARY
echo " \"GEMINI_API_KEY\": \"your-gemini-api-key-here\"" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo "}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🏷️ All Available Tags" >> $GITHUB_STEP_SUMMARY
echo "Built and pushed the following tags:" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" | sed 's/^/- `/' | sed 's/$/`/' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "repository_dispatch" ]]; then
echo "**Note:** This is a development build triggered by PR #${{ github.event.client_payload.pr_number }}" >> $GITHUB_STEP_SUMMARY
echo "Use this image for testing the changes from that PR." >> $GITHUB_STEP_SUMMARY
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "**Note:** This is a release build from tag ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "This image represents a stable release version." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 View in GitHub Container Registry" >> $GITHUB_STEP_SUMMARY
echo "[View all versions and tags →](https://github.com/${{ github.repository }}/pkgs/container/zen-mcp-server)" >> $GITHUB_STEP_SUMMARY
- name: Update README with latest image info
if: false # Temporarily disabled as agreed with repo author
# if: github.ref_type == 'tag' || (github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number != '')
run: |
# Checkout main branch to avoid detached HEAD when pushing
git fetch origin main:main
git checkout main
# Extract the primary image tag for updating README
if [[ "${{ github.ref_type }}" == "tag" ]]; then
# For tag releases, use the version tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}"
UPDATE_TYPE="release"
elif [[ "${{ github.event_name }}" == "repository_dispatch" && "${{ github.event.client_payload.pr_number }}" != "" ]]; then
# For repository_dispatch (PR builds), use the PR tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.client_payload.pr_number }}"
UPDATE_TYPE="development"
else
# For manual repository_dispatch without PR number, use latest tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
UPDATE_TYPE="manual"
fi
echo "Updating README.md with latest Docker image: $LATEST_TAG"
# Update README.md with the latest image tag
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" README.md
# Also update docs/user-guides/installation.md
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" docs/user-guides/installation.md
# Also update docs/user-guides/configuration.md
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" docs/user-guides/configuration.md
# Check if there are any changes
if git diff --quiet README.md docs/user-guides/installation.md docs/user-guides/configuration.md; then
echo "No changes needed in documentation"
else
echo "Documentation updated with new image tag"
# Configure git for automated commit
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Add and commit changes
git add README.md docs/user-guides/installation.md docs/user-guides/configuration.md
if [[ "$UPDATE_TYPE" == "release" ]]; then
git commit -m "docs: Update Docker image references to ${{ github.ref_name }}
Automated update after Docker image publish for release ${{ github.ref_name }}.
All documentation now references the latest stable image.
🤖 Automated by GitHub Actions"
elif [[ "$UPDATE_TYPE" == "development" ]]; then
git commit -m "docs: Update Docker image references for PR #${{ github.event.client_payload.pr_number }}
Automated update after Docker image publish for development build.
Documentation updated to reference the latest development image.
🤖 Automated by GitHub Actions"
else
git commit -m "docs: Update Docker image references to latest
Automated update after manual Docker image build.
Documentation updated to reference the latest image.
🤖 Automated by GitHub Actions"
fi
# Push changes back to the repository
git push --set-upstream origin main
echo "### 📝 Documentation Updated" >> $GITHUB_STEP_SUMMARY
echo "README.md and user guides have been automatically updated with the new Docker image tag: \`$LATEST_TAG\`" >> $GITHUB_STEP_SUMMARY
fi

View File

@@ -1,32 +0,0 @@
name: Docker Build Test
on:
pull_request:
branches: [ main ]
jobs:
docker-build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Test Docker build
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: test:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build test summary
run: |
echo "### ✅ Docker Build Test Passed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Docker image builds successfully and is ready for production." >> $GITHUB_STEP_SUMMARY

View File

@@ -25,6 +25,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run unit tests
run: |
@@ -49,7 +50,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff black
pip install -r requirements-dev.txt
- name: Run black formatter check
run: black --check .
@@ -57,61 +58,3 @@ jobs:
- name: Run ruff linter
run: ruff check .
simulation-tests:
runs-on: ubuntu-latest
# Only run simulation tests on main branch pushes (requires manual API key setup)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Check API key availability
id: check-key
run: |
has_key=false
if [ -n "${{ secrets.GEMINI_API_KEY }}" ] || [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
has_key=true
echo "✅ API key(s) found - running simulation tests"
else
echo "⚠️ No API keys configured - skipping simulation tests"
fi
echo "api_key_available=$has_key" >> $GITHUB_OUTPUT
- name: Set up Docker
if: steps.check-key.outputs.api_key_available == 'true'
uses: docker/setup-buildx-action@v3
- name: Build Docker image
if: steps.check-key.outputs.api_key_available == 'true'
run: |
docker compose build
- name: Run simulation tests
if: steps.check-key.outputs.api_key_available == 'true'
run: |
# Start services
docker compose up -d
# Wait for services to be ready
sleep 10
# Run communication simulator tests
python communication_simulator_test.py --skip-docker
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: Skip simulation tests
if: steps.check-key.outputs.api_key_available == 'false'
run: |
echo "🔒 Simulation tests skipped (no API keys configured)"
echo "To enable simulation tests, add GEMINI_API_KEY and/or OPENAI_API_KEY as repository secrets"