task: Complete Task #092 — Trinity Core MCP Gateway (superseded by #111/#112)
Original plan: HP laptop, Docker, Discord approval workflows. Reality: Raspberry Pi 4B, single Node.js process, bearer token auth. Snart Doctrine applied. Plan thrown away. It worked. Chronicler #78 | firefrost-operations-manual
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
task_number: 92
|
||||
title: Trinity Core — Desktop MCP Gateway
|
||||
status: In Progress
|
||||
title: Trinity Core — MCP Gateway
|
||||
status: Complete
|
||||
priority: P1-High
|
||||
is_blocker: false
|
||||
owner: Michael
|
||||
@@ -13,155 +13,38 @@ tags:
|
||||
estimated_hours: 8
|
||||
---
|
||||
|
||||
# Task #92: Trinity Core — Desktop MCP Gateway
|
||||
# Task #92: Trinity Core — MCP Gateway — COMPLETE
|
||||
|
||||
## Overview
|
||||
**Completed:** April 11, 2026
|
||||
|
||||
A dedicated Ubuntu Server on Michael's HP laptop that acts as an MCP gateway, allowing Claude.ai to execute commands on Firefrost servers with approval workflows.
|
||||
## What Happened
|
||||
|
||||
**Hardware:** HP Laptop (dedicated, shelf-mode)
|
||||
**OS:** Ubuntu Server 24.04 LTS
|
||||
**Codename:** Trinity Core
|
||||
Originally planned as an HP laptop running Ubuntu Server with Docker, Discord approval workflows, and complex security layers. Reality was simpler and better:
|
||||
|
||||
## The Vision
|
||||
**Implemented as:** Raspberry Pi 4B (8GB) running Debian 13, single Node.js process, Cloudflare Tunnel, direct bearer token auth.
|
||||
|
||||
```
|
||||
Claude.ai → MCP Request → Laptop (Trinity Core) → SSH → Firefrost Servers
|
||||
↓
|
||||
Arbiter (Discord Approval)
|
||||
↓
|
||||
Michael clicks "Approve"
|
||||
↓
|
||||
Command executes
|
||||
```
|
||||
## Superseded By
|
||||
|
||||
No more copy-paste from Claude to MobaXterm. Claude can execute commands directly with Michael's approval.
|
||||
- **Task #111:** Trinity Core Web MCP Connector (Claude.ai native, completed by Chronicler #77)
|
||||
- **Task #112:** Trinity Core Security Hardening (spawn() fix, log rotation, completed by #77/#78)
|
||||
- **Task #109:** MCP Logging in Trinity Console (PostgreSQL audit trail, completed by #78)
|
||||
|
||||
## Architecture (Gemini-Approved)
|
||||
## Current State (v2.3.0)
|
||||
|
||||
| Component | Decision | Rationale |
|
||||
|-----------|----------|-----------|
|
||||
| MCP Server | Docker container | Isolation — bugs stay contained |
|
||||
| SSH Keys | One Ed25519 key | `claude_executor` user on all target servers |
|
||||
| Firewall | UFW | Allow 22, 9090 only; deny all else |
|
||||
| Security | fail2ban + Cloudflare Access | Defense in depth |
|
||||
| Approval | Arbiter integration | Don't reinvent — use existing Discord bot |
|
||||
| Tunnel | cloudflared | Zero incoming ports needed |
|
||||
| Startup | docker-compose + systemd | Auto-recovery on reboot |
|
||||
| Monitoring | Uptime Kuma | CPU temp, disk I/O, endpoint health |
|
||||
- **Hardware:** Raspberry Pi 4B (8GB), not HP laptop
|
||||
- **Architecture:** Express + MCP SDK 1.29.0, no Docker
|
||||
- **Auth:** Bearer token via OAuth shim, no Discord approval flow
|
||||
- **Tunnel:** Cloudflare Tunnel → mcp.firefrostgaming.com
|
||||
- **Targets:** 8 servers (7 SSH + 1 local)
|
||||
- **Logging:** PostgreSQL via Arbiter (async), local file backup
|
||||
- **Security:** spawn() with array args, no shell injection
|
||||
- **Code:** firefrost-services/services/trinity-core/
|
||||
|
||||
## Implementation Phases
|
||||
## The Snart Doctrine Applied
|
||||
|
||||
### Phase 1: Ubuntu Server Setup ⬅️ CURRENT
|
||||
|
||||
**Status:** Ready to begin (laptop is wiped)
|
||||
|
||||
1. [ ] Download Ubuntu Server 24.04 LTS ISO
|
||||
2. [ ] Flash to USB with Rufus or balenaEtcher
|
||||
3. [ ] Install Ubuntu Server on HP laptop
|
||||
4. [ ] During install: enable OpenSSH server
|
||||
5. [ ] First boot: update system (`apt update && apt upgrade`)
|
||||
6. [ ] Install Cockpit for web management
|
||||
7. [ ] Configure UFW firewall
|
||||
8. [ ] Install fail2ban
|
||||
9. [ ] Configure lid switch behavior
|
||||
10. [ ] Install Docker and docker-compose
|
||||
|
||||
**Detailed checklist:** `docs/tasks/task-092-trinity-core/phase-1-ubuntu-setup.md`
|
||||
|
||||
### Phase 2: SSH Infrastructure
|
||||
|
||||
1. [ ] Generate Ed25519 key pair on laptop
|
||||
2. [ ] Create `claude_executor` user on Command Center
|
||||
3. [ ] Create `claude_executor` user on TX1
|
||||
4. [ ] Create `claude_executor` user on NC1
|
||||
5. [ ] Create `claude_executor` user on Panel (if needed)
|
||||
6. [ ] Add public key to all `authorized_keys`
|
||||
7. [ ] Test SSH connections
|
||||
8. [ ] Configure restricted sudo for `claude_executor`
|
||||
|
||||
### Phase 3: Cloudflare Tunnel
|
||||
|
||||
1. [ ] Install cloudflared
|
||||
2. [ ] Create tunnel in Cloudflare Zero Trust dashboard
|
||||
3. [ ] Configure tunnel to point to MCP server port
|
||||
4. [ ] Set up Cloudflare Access policy (Service Token)
|
||||
5. [ ] Create systemd service for cloudflared
|
||||
6. [ ] Test tunnel connectivity
|
||||
|
||||
### Phase 4: MCP Server Development
|
||||
|
||||
1. [ ] Scaffold MCP server (Node.js)
|
||||
2. [ ] Implement SSH command execution
|
||||
3. [ ] Add Arbiter webhook integration (approval requests)
|
||||
4. [ ] Handle approval responses
|
||||
5. [ ] Add command allowlist/denylist
|
||||
6. [ ] Containerize with Docker
|
||||
7. [ ] Create docker-compose.yml
|
||||
8. [ ] Mount SSH keys as read-only volume
|
||||
|
||||
### Phase 5: Arbiter Integration
|
||||
|
||||
1. [ ] Add MCP approval endpoint to Arbiter
|
||||
2. [ ] Create `#mcp-approvals` Discord channel
|
||||
3. [ ] Implement approval button UI
|
||||
4. [ ] Add timeout handling (auto-deny after X minutes)
|
||||
5. [ ] Implement callback to MCP server
|
||||
6. [ ] Add audit logging
|
||||
|
||||
### Phase 6: Testing & Monitoring
|
||||
|
||||
1. [ ] Add to Uptime Kuma (endpoint health)
|
||||
2. [ ] Add CPU temp monitoring
|
||||
3. [ ] Add disk I/O monitoring
|
||||
4. [ ] Test full flow: Claude → MCP → Approval → Execute
|
||||
5. [ ] Test failure scenarios
|
||||
6. [ ] Document troubleshooting guide
|
||||
|
||||
## Target Servers
|
||||
|
||||
| Server | IP | claude_executor needed |
|
||||
|--------|-----|------------------------|
|
||||
| Command Center | 63.143.34.217 | Yes |
|
||||
| TX1 Dallas | 38.68.14.26 | Yes |
|
||||
| NC1 Charlotte | 216.239.104.130 | Yes |
|
||||
| Panel VPS | 45.94.168.138 | Maybe |
|
||||
| Dev Panel | 64.50.188.128 | Maybe |
|
||||
|
||||
## Security Model
|
||||
|
||||
**Zero-Trust Principles:**
|
||||
- Cloudflare Access validates identity before traffic reaches laptop
|
||||
- MCP server validates request format/signature
|
||||
- Arbiter requires Discord button approval for execution
|
||||
- `claude_executor` has restricted sudo (no root)
|
||||
- SSH keys mounted read-only in container
|
||||
- All commands logged for audit
|
||||
|
||||
**Command Classification:**
|
||||
- **Safe:** Read-only commands (ls, cat, systemctl status) — maybe auto-approve
|
||||
- **Moderate:** Service restarts, git operations — require approval
|
||||
- **Dangerous:** File deletion, user management — require approval + confirmation
|
||||
|
||||
## Related Tasks
|
||||
|
||||
- **Task #93:** Trinity Codex (RAG knowledge base) — could query via MCP
|
||||
- **Task #94:** Global Restart Scheduler — could trigger via MCP
|
||||
- **Task #87:** Arbiter lifecycle handlers — approval system extends this
|
||||
|
||||
## Consultations
|
||||
|
||||
- `docs/consultations/gemini-claude-code-workflow-2026-04-08.md` — Original architecture
|
||||
- `docs/consultations/gemini-task-92-ubuntu-setup-2026-04-09.md` — Implementation guidance
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] Laptop runs Ubuntu Server, accessible via Cockpit
|
||||
- [ ] Claude.ai can send MCP requests through Cloudflare Tunnel
|
||||
- [ ] Approval buttons appear in Discord
|
||||
- [ ] Commands execute on target servers after approval
|
||||
- [ ] Full audit trail exists
|
||||
- [ ] System auto-recovers from reboots
|
||||
The plan called for Docker, approval workflows, command classification, restricted sudo.
|
||||
Reality needed a Pi, a token, and SSH.
|
||||
We threw away the plan. It worked.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user