# 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 in `mcp-servers/` and are launched locally by the worker. ## Quick start 1. Install [Docker Desktop](https://www.docker.com/) and [Ollama](https://ollama.com). 2. Pull a tool-calling local model: ```bash ollama pull qwen2.5:7b-instruct ``` 3. Configure environment: ```bash 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_TOKEN ``` Generate keys: ```bash openssl rand -hex 32 # SECRET_KEY python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" # CREDENTIAL_ENCRYPTION_KEY ``` 4. Launch: ```bash docker compose up -d --build ``` 5. Open the UI at and sign in with `FIRST_ADMIN_EMAIL` / `FIRST_ADMIN_PASSWORD`. Services: UI `:3000`, API `:8000`, LiteLLM `:4000`, Postgres `:5432`. ## Using it 1. **Inventory** — add Locations (with public IPs) and Devices (type, address, MCP server, credentials). Device secrets are encrypted at rest (Fernet). 2. **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. 3. **Approvals** — any proposed configuration change is gated; an `admin`/`support` user approves or rejects it in the task view. 4. **Outputs** — each task writes a memory under project `agentic-os-task` and an Obsidian note under `agentic-os-tasks/` (committed and pushed to Gitea). 5. **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 ```bash 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, set `MCP_START_` (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).