# kottos Engineering agents for Daedalus — powered by [Pallas](https://git.helu.ca/r/pallas). Kottos is a pure agent project: Python agent definitions + YAML configuration. The runtime (serving, registry, health checks, multimodal support) lives in Pallas. ## Architecture ``` Daedalus Backend — FastAPI │ MCP over StreamableHTTP ▼ Pallas MCP Bridge (pallas.server:main) │ reads agents.yaml for topology │ reads fastagent.config.yaml for LLM + model capabilities │ ├── Registry → /.well-known/mcp/server.json (agent discovery) ├── Harper → kernos_harper, gitea, argos, neo4j_cypher, grafana, │ rommie, angelia, time, research, tech_research ├── Scotty → kernos_scotty, argos, tech_research, neo4j_cypher, grafana, time ├── Research → argos, neo4j_cypher └── Tech Research → context7, github, argos ``` ## Project Structure ``` . ├── agents.yaml # Deployment topology — agents, ports, host, namespace ├── fastagent.config.yaml # LLM provider, MCP servers, model capabilities (committed) ├── fastagent.secrets.yaml # API keys and tokens (gitignored — never commit) ├── fastagent.secrets.yaml.example ├── agents/ # Agent definitions (FastAgent @fast.agent decorators) │ ├── harper.py │ ├── scotty.py │ ├── research.py │ └── tech_research.py ├── docs/ │ └── pallas_integration.md ├── pyproject.toml └── LICENSE ``` ## Agents | Agent | Port | MCP URL | Purpose | |-------|------|---------|---------| | Harper | 24101 | `http://puck.incus:24101/mcp` | Scrappy engineer — rapid prototyping, hacking, and creative problem-solving | | Scotty | 24102 | `http://puck.incus:24102/mcp` | Systems administration — infrastructure diagnostics and security hardening | | Research | 24150 | `http://puck.incus:24150/mcp` | Web search + knowledge graph chain | | Tech Research | 24151 | `http://puck.incus:24151/mcp` | Technical investigation — library docs, code examples, API comparisons | | Registry | 24100 | `http://puck.incus:24100/.well-known/mcp/server.json` | Agent discovery | ## Configuration ### `agents.yaml` — Deployment Topology Single source of truth for agent names, ports, dependencies, host, and namespace. Read by Pallas at startup. ```yaml name: kottos version: "1.0.0" host: puck.incus namespace: ca.helu.kottos registry_port: 24100 agents: harper: module: agents.harper port: 24101 title: Harper description: "Scrappy engineer — rapid prototyping, hacking, and creative problem-solving" depends_on: [research, tech_research] # ... ``` To deploy a different agent group, swap `agents.yaml` — no code changes needed. Override the config path with `PALLAS_AGENTS_CONFIG` env var. ### `fastagent.config.yaml` — LLM + Model Capabilities Committed to the repo. Contains LLM provider settings and explicit model capability declarations. In Ansible-managed deployments this file is replaced by the `fastagent.config.yaml.j2` template which renders environment-specific values for model, MCP URLs, etc. ```yaml default_model: openai.Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf model_capabilities: vision: false context_window: 192000 max_output_tokens: 16384 ``` The `model_capabilities` section declares capabilities explicitly rather than inferring from the model name. Exposed in the registry for Daedalus to use when routing requests. ### `fastagent.secrets.yaml` — API Keys and Tokens Gitignored — never commit. Place in the repo root alongside `fastagent.config.yaml`. In Ansible-managed deployments this file is replaced by the `fastagent.secrets.yaml.j2` template which renders secrets from OCI Vault. ```yaml openai: api_key: "your-key-here" mcp: servers: angelia: headers: Authorization: "Bearer your-token" github: env: GITHUB_PERSONAL_ACCESS_TOKEN: "your-token" # ... ``` ## Quickstart ```bash # 1. Install dependencies (Python 3.13 required) source ~/env/kottos/bin/activate pip install -e . # 2. Configure secrets cp fastagent.secrets.yaml.example fastagent.secrets.yaml # Edit: set api_key and service tokens # 3. Start all agents kottos # 4. Verify curl http://localhost:24101/mcp # 5. Start a single agent kottos --agent harper ``` ## Daedalus Integration Daedalus connects to agents via the MCP Python SDK's `streamable_http_client`. Registry endpoint: `http://puck.incus:24100/.well-known/mcp/server.json` The registry includes model capabilities on each agent entry: ```json { "capabilities": { "model": "Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf", "vision": false, "context_window": 192000, "max_output_tokens": 16384 } } ``` ## Downstream MCP Servers | Server | Host | URL | |--------|------|-----| | argos | miranda.incus | `http://miranda.incus:25534/mcp` | | neo4j_cypher | circe.helu.ca | `http://circe.helu.ca:22034/mcp` | | caliban | caliban.incus | `http://caliban.incus:22062/mcp` | | rommie | caliban.incus | `http://caliban.incus:22061/mcp` | | gitea | miranda.incus | `http://miranda.incus:25535/mcp` | | grafana | miranda.incus | `http://miranda.incus:25533/mcp` | | korax | korax.helu.ca | `http://korax.helu.ca:20261/mcp` | | angelia | ouranos.helu.ca | `https://ouranos.helu.ca/mcp/` | | github | local (Docker stdio) | `ghcr.io/github/github-mcp-server` | | context7 | local (stdio) | `npx -y @upstash/context7-mcp` | | time | local (stdio) | `mcp-server-time` | ## Notes - **Python 3.13** required (`fast-agent-mcp` pins `>=3.13`) - **Runtime:** [Pallas](https://git.helu.ca/r/pallas) — `pallas-mcp @ git+ssh://git@git.helu.ca:22022/r/pallas.git` - **Transport:** StreamableHTTP (`/mcp`) throughout — not SSE - **LLM:** OpenAI-compatible API at `http://nyx.helu.ca:22079/v1` (personal Qwen model) - **Logging:** Console output — stdout → syslog → Alloy → Loki in production - **Port scheme:** registry at 24100, agents 24101–24149, sub-agents 24150–24199