131 lines
3.9 KiB
Markdown
131 lines
3.9 KiB
Markdown
# FreeCAD Robust MCP Server — Ansible Deployment
|
|
|
|
Deploys the [FreeCAD Robust MCP Server](https://pypi.org/project/freecad-robust-mcp/)
|
|
to Caliban as a systemd service with HTTP transport, ready for MCP Switchboard
|
|
consumption.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ caliban.incus │
|
|
│ │
|
|
│ ┌──────────────────────┐ │
|
|
│ │ freecad-mcp.service │ │
|
|
│ │ (streamable-http) │◄─── :22032 ──────────┤◄── MCP Switchboard
|
|
│ │ venv + PyPI package │ │ (oberon.incus)
|
|
│ └──────────────────────┘ │
|
|
│ │ │
|
|
│ │ xmlrpc :9875 │
|
|
│ ▼ │
|
|
│ ┌──────────────────────┐ │
|
|
│ │ FreeCAD (future) │ │
|
|
│ │ XML-RPC server │ │
|
|
│ └──────────────────────┘ │
|
|
└─────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
- Caliban host in Ansible inventory (already exists in Ouranos)
|
|
- Python 3.11+ on Caliban (already present)
|
|
|
|
## Deployment
|
|
|
|
### 1. Copy playbook files to Ouranos
|
|
|
|
Copy the contents of this directory into your Ouranos repo:
|
|
|
|
```
|
|
ansible/freecad_mcp/
|
|
├── deploy.yml
|
|
├── .env.j2
|
|
└── freecad-mcp.service.j2
|
|
```
|
|
|
|
### 2. Add inventory group
|
|
|
|
Add to `ansible/inventory/hosts`:
|
|
|
|
```yaml
|
|
freecad_mcp:
|
|
hosts:
|
|
caliban.incus:
|
|
```
|
|
|
|
### 3. Add host variables
|
|
|
|
Add to `ansible/inventory/host_vars/caliban.incus.yml`:
|
|
|
|
```yaml
|
|
# FreeCAD Robust MCP Server
|
|
freecad_mcp_user: harper
|
|
freecad_mcp_group: harper
|
|
freecad_mcp_directory: /srv/freecad-mcp
|
|
freecad_mcp_port: 22032
|
|
freecad_mcp_version: "0.5.0"
|
|
```
|
|
|
|
Update `services` list:
|
|
|
|
```yaml
|
|
services:
|
|
- alloy
|
|
- caliban
|
|
- docker
|
|
- freecad_mcp
|
|
- kernos
|
|
```
|
|
|
|
### 4. Run the playbook
|
|
|
|
```bash
|
|
ansible-playbook freecad_mcp/deploy.yml
|
|
```
|
|
|
|
## Upgrading
|
|
|
|
To upgrade to a new PyPI version, update `freecad_mcp_version` in host_vars
|
|
and re-run the playbook. The pip install task will detect the version change
|
|
and the handler will restart the service.
|
|
|
|
## Validation
|
|
|
|
The playbook automatically validates the deployment by:
|
|
|
|
1. Waiting for the HTTP port to become available
|
|
2. Sending an MCP `initialize` JSON-RPC request to `/mcp`
|
|
3. Verifying a 200 response
|
|
|
|
You can also manually test:
|
|
|
|
```bash
|
|
curl -X POST http://caliban.incus:22032/mcp \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'
|
|
```
|
|
|
|
## Service Management
|
|
|
|
```bash
|
|
# On Caliban
|
|
sudo systemctl status freecad-mcp
|
|
sudo systemctl restart freecad-mcp
|
|
sudo journalctl -u freecad-mcp -f
|
|
```
|
|
|
|
## Security
|
|
|
|
The systemd service runs with hardened settings:
|
|
|
|
| Setting | Value | Rationale |
|
|
|---------|-------|-----------|
|
|
| `NoNewPrivileges` | `true` | No privilege escalation |
|
|
| `ProtectSystem` | `strict` | Filesystem is read-only except allowed paths |
|
|
| `ProtectHome` | `read-only` | Home directories protected |
|
|
| `PrivateTmp` | `true` | Isolated /tmp namespace |
|
|
| `ReadWritePaths` | `/srv/freecad-mcp` | Only app directory is writable |
|
|
|
|
This is significantly more hardened than the Kernos service (which needs
|
|
broad filesystem access for shell commands).
|