From fcfb6f486acf9d867bbd17e12501364cf6b2bc0c Mon Sep 17 00:00:00 2001 From: Charles N Wyble Date: Fri, 23 Jan 2026 14:52:34 -0500 Subject: [PATCH] feat: add freecad-mcp to Crush integration Build and validate FreeCAD MCP Server (v1.25.0). Changes: - mcp-freecad-wrapper.sh: Created wrapper script with container cleanup - crush.json: Added freecad-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 (317MB, Python + uv) - MCP protocol handshake verified with initialize request - Protocol version 2024-11-05 confirmed - Server name: FreeCADMCP, version 1.25.0 - Wrapper script tested and working - Environment variable: PYTHONUNBUFFERED=1 - External dependency: FreeCAD with MCP addon (warning if not running) Similar to blender-mcp: - Both Python-based with uv package manager - Both require CAD application with addon running - Both show warning on startup when CAD app not connected - Both still initialize properly for MCP protocol handshake This is second MCP added in alphabetical order after filtering out already working MCPs (audiobook, bitwarden, blender, cloudron, context7, docker, drawio, elasticsearch). Following ADR-007: Sequential Server Validation - one MCP at a time, awaiting user validation before proceeding to next MCP. --- JOURNAL.md | 115 +++++++++++++++++++++++++++++++++++++++++ STATUS.md | 2 + crush.json | 5 ++ mcp-freecad-wrapper.sh | 20 +++++++ 4 files changed, 142 insertions(+) create mode 100755 mcp-freecad-wrapper.sh diff --git a/JOURNAL.md b/JOURNAL.md index fb93c48..2898596 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -778,6 +778,121 @@ Result: Valid JSON-RPC response returned (Context7 v2.1.0, protocol version 2024 **Note**: Docker config.json issue remains (requires user action with sudo to fix directory/file problem). +--- + +### [MCP Integration] freecad-mcp Added and Validated + +**Date/Time**: 2026-01-23 01:50:00 PM EST +**Type**: MCP Integration +**Status**: Completed - Awaiting User Validation + +**What Was Done**: +Added freecad-mcp (FreeCAD MCP Server) to Crush integration as second MCP in alphabetical order. + +**Work Completed**: + +1. **Built container**: +```bash +docker compose build freecad-mcp +``` +Result: Successfully built (317MB, Python + uv package manager) + +2. **Created wrapper script**: +- File: `mcp-freecad-wrapper.sh` +- Pattern: Same as working MCP wrappers (container cleanup, explicit naming) +- Environment variables: PYTHONUNBUFFERED=1 + +3. **Tested MCP protocol**: +```bash +echo '{"jsonrpc":"2.0","method":"initialize",...}' | \ + timeout 10 docker run --rm -i kneldevstack-aimiddleware-freecad-mcp +``` +Result: Valid JSON-RPC response returned (FreeCADMCP v1.25.0, protocol version 2024-11-05) + +4. **Added to crush.json**: +```json +"freecad": { + "type": "stdio", + "command": "/path/to/mcp-freecad-wrapper.sh", + "timeout": 180 +} +``` + +5. **Updated documentation**: +- STATUS.md: Added freecad-mcp to "Working MCP Servers" and "Recently Built" +- JOURNAL.md: This entry + +**Server Details**: +- Name: FreeCAD MCP Server +- Version: 1.25.0 +- Purpose: FreeCAD CAD modeling integration through Model Context Protocol +- Type: stdio-based MCP +- Size: 317MB +- Build: Python with uv package manager +- Environment Variables Required: + - PYTHONUNBUFFERED=1 (for proper Python output buffering) +- External Service Required: FreeCAD with MCP addon running + +**Validation Results**: +- Container builds: ✓ +- MCP protocol handshake: ✓ +- Wrapper script execution: ✓ +- JSON-RPC initialize response: ✓ +- Protocol version: 2024-11-05 ✓ +- Server capabilities returned: ✓ +- Warning message (expected): Could not connect to FreeCAD (addon not running) + +**Files Created**: +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-freecad-wrapper.sh` (executable) + +**Files Modified**: +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/crush.json` (added freecad entry) +- `/home/charles/Projects/KNEL/KNEL-AIMiddleware/STATUS.md` (updated status) + +**Next Steps**: +- **User Action**: Validate freecad-mcp in Crush +- **User Authorization**: After validation, proceed to next MCP (ghost-mcp) + +**Working MCPs to Date** (9 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** (NEW - awaiting validation) + +**Remaining MCPs** (alphabetical order, filtering out working): +- ghost-mcp +- gimp-mcp +- 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. + +**Similarities to blender-mcp**: +- Both Python-based with uv package manager +- Both require CAD application with addon running +- Both show warning on startup when CAD app not connected +- Both still initialize properly for MCP protocol handshake + +--- + **Date/Time**: 2026-01-23 01:15:00 PM EST diff --git a/STATUS.md b/STATUS.md index 9328015..7083720 100644 --- a/STATUS.md +++ b/STATUS.md @@ -15,6 +15,7 @@ Last validated: 2026-01-23 - ✓ docker-mcp: Working (docker-mcp v0.1.0) - requires Docker socket mount - ✓ drawio-mcp: Working (drawio-mcp-server v1.4.0) - requires DRAWIO_URL env var - ✓ 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 **MCP Servers with Configuration Issues:** - None @@ -61,6 +62,7 @@ Last validated: 2026-01-23 | docker-mcp | Built | Container built from Python source (188MB). Uses uv package manager. MCP stdio-based, requires Docker socket mount (/var/run/docker.sock). Version 0.1.0. | | drawio-mcp | Built | Container built from TypeScript source (302MB). Uses pnpm package manager. MCP stdio-based, requires DRAWIO_URL env var. Version 1.4.0. | | 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. | | 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 a699fd4..8e3c5cd 100644 --- a/crush.json +++ b/crush.json @@ -51,6 +51,11 @@ "type": "stdio", "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-elasticsearch-wrapper.sh", "timeout": 60 + }, + "freecad": { + "type": "stdio", + "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-freecad-wrapper.sh", + "timeout": 180 } } } diff --git a/mcp-freecad-wrapper.sh b/mcp-freecad-wrapper.sh new file mode 100755 index 0000000..9719c68 --- /dev/null +++ b/mcp-freecad-wrapper.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Wrapper script for freecad-mcp +# Ensures clean container with proper name + +CONTAINER_NAME="kneldevstack-aimiddleware-freecad-mcp-crush" +IMAGE_NAME="kneldevstack-aimiddleware-freecad-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}" "$@"