From 2596cc42e069870627ea67479fc9ab5809cdb0ca Mon Sep 17 00:00:00 2001 From: Charles N Wyble Date: Fri, 23 Jan 2026 15:20:48 -0500 Subject: [PATCH] feat: add gimp-mcp to Crush integration Build and validate GIMP MCP Server (GimpMCP v1.10.1). Changes: - dockerfiles/gimp-mcp/Dockerfile: Fixed ENTRYPOINT to use python -m instead of uvx - mcp-gimp-wrapper.sh: Created wrapper script with container cleanup - crush.json: Added gimp-mcp entry with type: stdio and timeout: 180 - STATUS.md: Updated working MCP list and detailed status table - JOURNAL.md: Documented integration with full validation results Validation: - Container builds successfully (418MB, Python + uv) - Dockerfile fix: Changed from uvx (slow, rebuilds packages) to python -m (fast, uses .venv) - MCP protocol handshake verified with initialize request - Protocol version 2024-11-05 confirmed - Server name: GimpMCP, version 1.10.1 - Wrapper script tested and working - Environment variable: PYTHONUNBUFFERED=1 - External dependency: GIMP 3.0 with server Dockerfile Fix: - Before: ENTRYPOINT ["uvx", "gimp-mcp-server"] (slow, rebuilds on every run) - After: ENTRYPOINT ["python", "-m", "gimp_mcp_server"] (fast, uses built .venv) - Entry point: gimp-mcp-server = "gimp_mcp_server:main" (from pyproject.toml) This is fourth MCP added in alphabetical order after filtering out already working MCPs (audiobook, bitwarden, blender, cloudron, context7, docker, drawio, elasticsearch, freecad, ghost). Following ADR-007: Sequential Server Validation - one MCP at a time. --- JOURNAL.md | 114 ++++++++++++++++++++++++++++++++ STATUS.md | 2 + crush.json | 5 ++ dockerfiles/gimp-mcp/Dockerfile | 2 +- mcp-gimp-wrapper.sh | 20 ++++++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100755 mcp-gimp-wrapper.sh diff --git a/JOURNAL.md b/JOURNAL.md index d4f54af..71b43c6 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1187,3 +1187,117 @@ Sequential validation of MCP servers with pattern: + +### [MCP Integration] gimp-mcp Added and Validated + +**Date/Time**: 2026-01-23 02:10:00 PM EST +**Type**: MCP Integration +**Status**: Completed - Awaiting User Validation + +**What Was Done**: +Added gimp-mcp (GIMP MCP Server) to Crush integration as fourth MCP in alphabetical order. + +**Work Completed**: + +1. **Built container**: +```bash +docker compose build gimp-mcp +``` +Result: Successfully built (418MB, Python + uv) + +2. **Fixed Dockerfile**: +- Problem: `ENTRYPOINT ["uvx", "gimp-mcp-server"]` caused uvx to rebuild packages on every run +- Solution: Changed to `ENTRYPOINT ["python", "-m", "gimp_mcp_server"]` +- Result: Uses pre-built .venv from container build, much faster and more reliable + +3. **Created wrapper script**: +- File: `mcp-gimp-wrapper.sh` +- Pattern: Same as working MCP wrappers (container cleanup, explicit naming) +- Environment variables: PYTHONUNBUFFERED=1 + +4. **Tested MCP protocol**: +```bash +echo '{"jsonrpc":"2.0","method":"initialize",...}' | \ + timeout 10 docker run --rm -i kneldevstack-aimiddleware-gimp-mcp +``` +Result: Valid JSON-RPC response returned (GimpMCP v1.10.1, protocol version 2024-11-05) + +5. **Added to crush.json**: +```json +"gimp": { + "type": "stdio", + "command": "/path/to/mcp-gimp-wrapper.sh", + "timeout": 180 +} +``` + +6. **Updated documentation**: +- STATUS.md: Added gimp-mcp to "Working MCP Servers" and "Recently Built" +- JOURNAL.md: This entry + +**Server Details**: +- Name: GimpMCP +- Version: 1.10.1 +- Purpose: GIMP 3.0 integration through Model Context Protocol +- Type: stdio-based MCP +- Size: 418MB +- Build: Python with uv package manager +- Environment Variables Required: + - PYTHONUNBUFFERED=1 (for proper Python output buffering) +- External Service Required: GIMP 3.0 with server running + +**Validation Results**: +- Container builds: ✓ +- Dockerfile fix applied: ✓ +- MCP protocol handshake: ✓ +- Wrapper script execution: ✓ +- JSON-RPC initialize response: ✓ +- Protocol version: 2024-11-05 ✓ +- Server capabilities returned: ✓ + +**Dockerfile Fix Details**: +- Before: `ENTRYPOINT ["uvx", "gimp-mcp-server"]` (slow, rebuilds packages) +- After: `ENTRYPOINT ["python", "-m", "gimp_mcp_server"]` (fast, uses .venv) +- Entry point from pyproject.toml: `gimp-mcp-server = "gimp_mcp_server:main"` + +**Files Created**: +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-gimp-wrapper.sh` (executable) + +**Files Modified**: +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/dockerfiles/gimp-mcp/Dockerfile` (fixed entry point) +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/crush.json` (added gimp entry) +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/STATUS.md` (updated status) + +**Working MCPs to Date** (11 total): +1. audiobook-mcp +2. bitwarden-mcp +3. blender-mcp +4. cloudron-mcp +5. context7-mcp +6. docker-mcp +7. drawio-mcp +8. elasticsearch-mcp +9. freecad-mcp +10. ghost-mcp +11. **gimp-mcp** (NEW - awaiting validation) + +**Remaining MCPs** (alphabetical order, filtering out working): +- imap-mcp +- kicad-mcp (special case: host-only, requires KiCAD running) +- mcp-ansible (ansibe-mcp) +- mcp-redmine (redmine-mcp) +- matomo-mcp +- nextcloud-mcp (special case: HTTP-based) +- discourse-mcp +- docspace-mcp +- penpot-mcp +- postizz-mcp +- proxmox-mcp +- snipeit-mcp +- terraform-mcp +- wordpress-mcp +- kubernetes-mcp (special case: requires kube config) + +**Pattern Applied**: ADR-007 (Sequential Server Validation) - one MCP at a time, validate before proceeding. + +--- diff --git a/STATUS.md b/STATUS.md index 92ec47e..4a8ba56 100644 --- a/STATUS.md +++ b/STATUS.md @@ -17,6 +17,7 @@ Last validated: 2026-01-23 - ✓ elasticsearch-mcp: Working (rmcp v0.2.1, deprecated) - requires ES_URL env var - ✓ freecad-mcp: Working (FreeCADMCP v1.25.0) - requires FreeCAD with addon running - ✓ ghost-mcp: Working (ghost-mcp-ts v1.0.0) - requires Ghost CMS credentials +- ✓ gimp-mcp: Working (GimpMCP v1.10.1) - requires GIMP with server running **MCP Servers with Configuration Issues:** - None @@ -65,6 +66,7 @@ Last validated: 2026-01-23 | elasticsearch-mcp | Built | Container built from Rust source (22MB). Fixed Dockerfile to pass "stdio" subcommand. MCP stdio-based, requires ES_URL env var. NOTE: Server is deprecated. Version 0.2.1. | | freecad-mcp | Built | Container built from Python source (317MB). Uses uv package manager. MCP stdio-based, requires FreeCAD running with addon. Version 1.25.0. | | ghost-mcp | Built | Container built from TypeScript source (284MB). npm build with tsc. MCP stdio-based, requires Ghost CMS URL and API key. Version 1.0.0. | +| gimp-mcp | Built | Container built from Python source (418MB). Uses uv package manager. Fixed Dockerfile to use python -m instead of uvx. MCP stdio-based, requires GIMP with server running. Version 1.10.1. | | bash-language-server | Built | Container built using prebuilt npm package (190MB). LSP configured in crush.json via wrapper script. Version 5.6.0. | | docker-language-server | Built | Container built from Go source (49.2MB). LSP configured in crush.json via wrapper script. Version 0.0.0. | | marksman | Built | Container built from prebuilt binary (144MB). LSP configured in crush.json via wrapper script. Version 2025-12-13. | diff --git a/crush.json b/crush.json index 6e201e0..894385c 100644 --- a/crush.json +++ b/crush.json @@ -61,6 +61,11 @@ "type": "stdio", "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-ghost-wrapper.sh", "timeout": 60 + }, + "gimp": { + "type": "stdio", + "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-gimp-wrapper.sh", + "timeout": 180 } } } diff --git a/dockerfiles/gimp-mcp/Dockerfile b/dockerfiles/gimp-mcp/Dockerfile index 6d30372..e7145d3 100644 --- a/dockerfiles/gimp-mcp/Dockerfile +++ b/dockerfiles/gimp-mcp/Dockerfile @@ -21,4 +21,4 @@ RUN uv sync --frozen --no-dev --no-editable --no-cache ENV PYTHONUNBUFFERED=1 ENV PATH=/app/.venv/bin:$PATH -ENTRYPOINT ["uvx", "gimp-mcp-server"] +ENTRYPOINT ["python", "-m", "gimp_mcp_server"] diff --git a/mcp-gimp-wrapper.sh b/mcp-gimp-wrapper.sh new file mode 100755 index 0000000..f61db86 --- /dev/null +++ b/mcp-gimp-wrapper.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Wrapper script for gimp-mcp +# Ensures clean container with proper name + +CONTAINER_NAME="kneldevstack-aimiddleware-gimp-mcp-crush" +IMAGE_NAME="kneldevstack-aimiddleware-gimp-mcp" + +# Force remove existing container if it exists (in any state) +if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then + docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 + # Wait for container to be fully removed + while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do + sleep 0.05 + done +fi + +# Start MCP server with explicit name +exec docker run -i --rm --name "${CONTAINER_NAME}" \ + -e "PYTHONUNBUFFERED=1" \ + "${IMAGE_NAME}" "$@"