6185b9b85a81ca5eb080fd3117fb8053c48f50db
Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend + LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini -> DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials, RBAC, audit log, project-memory + Obsidian integrations, and editable troubleshooting decision rules tuned for the GeneseasX vessel stack. Co-authored-by: Cursor <cursoragent@cursor.com>
Agentic OS
A self-hosted, Docker-based agentic troubleshooting platform. It runs on your Apple Silicon Mac, uses a local LLM for initial triage and cloud APIs (OpenRouter / DeepSeek) for deep reasoning, drives your existing MCP servers to inspect devices, tracks API balances, enforces user roles, and writes every task outcome to your project-memory agent and Obsidian vault.
Built to troubleshoot and configure GeneseasX and other gear: plain Debian/Proxmox hosts, FortiGate, FortiSwitch, Asterisk, pfSense, TP-Link, and more.
Architecture
Browser ──> Next.js UI ──> FastAPI backend ──> Postgres / Redis
│
├─ balance pollers (OpenRouter /credits, DeepSeek /user/balance)
│
Worker (LangGraph agent) ─────────┤
triage (local) -> diagnose (MCP tools) -> reason (cloud) -> report
│
LiteLLM gateway ──> Ollama (host) + Gemini + DeepSeek + OpenRouter
MCP Manager ──> spawns MCP servers (pfsense/proxmox/asterisk/ssh/fortigate/...)
Integrations ──> project-memory MCP + Obsidian vault (git)
- Local LLM: Ollama runs on the host (Docker Desktop on macOS cannot use the
Metal GPU). Containers reach it at
host.docker.internal:11434. - MCP servers: existing ones are cloned from Gitea; net-new ones
(
ssh-generic-mcp,fortigate-mcp,fortiswitch-mcp) ship inmcp-servers/and are launched locally by the worker.
Quick start
- Install Docker Desktop and Ollama.
- Pull a tool-calling local model:
ollama pull qwen2.5:7b-instruct - Configure environment:
Generate keys:
cp .env.example .env # then edit .env — at minimum set: # SECRET_KEY, CREDENTIAL_ENCRYPTION_KEY, FIRST_ADMIN_PASSWORD # OPENROUTER_API_KEY and/or DEEPSEEK_API_KEY and/or GEMINI_API_KEY # GITEA_TOKEN, MEMORY_MCP_TOKENopenssl rand -hex 32 # SECRET_KEY python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" # CREDENTIAL_ENCRYPTION_KEY - Launch:
docker compose up -d --build - Open the UI at http://localhost:3000 and sign in with
FIRST_ADMIN_EMAIL/FIRST_ADMIN_PASSWORD.
Services: UI :3000, API :8000, LiteLLM :4000, Postgres :5432.
Using it
- Inventory — add Locations (with public IPs) and Devices (type, address, MCP server, credentials). Device secrets are encrypted at rest (Fernet).
- Tasks — create a troubleshooting task, pick the target device, describe the issue. The agent triages locally, runs read-only diagnostics through the device's MCP, escalates to a cloud model, and produces a structured report.
- Approvals — any proposed configuration change is gated; an
admin/supportuser approves or rejects it in the task view. - Outputs — each task writes a memory under project
agentic-os-taskand an Obsidian note underagentic-os-tasks/(committed and pushed to Gitea). - Dashboard — live API balances, MCP server health, and recent tasks.
Roles
| Role | Capabilities |
|---|---|
admin |
Everything, incl. user management |
support |
Create/run tasks, manage inventory, approve changes |
readonly |
View dashboards, tasks, inventory |
Tests
cd backend && pip install -r requirements.txt && pytest
Repository layout
backend/ FastAPI app, agent engine, MCP manager, services
app/agent/ LangGraph troubleshooting graph + device playbooks
app/mcp_manager/ clones + launches MCP servers, tool registry
app/services/ events, balance, llm router, memory+obsidian integrations
frontend/ Next.js + Tailwind operator console
litellm/ LiteLLM gateway config (local + cloud models)
mcp-servers/ net-new MCP servers (ssh-generic, fortigate, fortiswitch)
docker-compose.yml full stack
Notes & next steps
- Existing MCP repos are launched best-effort via
uv run; if a repo needs a custom start command, setMCP_START_<REPO_NAME>(e.g.MCP_START_PFSENSE_MCP). - Approved configuration changes are recorded but executed in a follow-up flow; wire
them to the relevant MCP write tool when ready (writes are gated by
*_ALLOW_WRITES). - TP-Link MCP is intentionally deferred (after FortiGate/FortiSwitch).
Description
Languages
Python
72.8%
TypeScript
26.4%
CSS
0.3%
Dockerfile
0.2%
Mako
0.1%