Echo

A self-hosted chat and agent workspace I built: bring your own model provider key, and Echo runs a tool-using agent loop against it, streaming answers as it works and pausing protected tools for your approval.

Echo
Screenshot of Echo
Personal project

The idea

I wanted a chat and agent workspace I could run myself, on whichever model I chose. Echo is that: you bring your own provider key (OpenAI, Anthropic, opencode-go or a local LM Studio), and Echo runs a tool-using agent loop against it. Answers stream in as the agent works, and tool calls marked as protected wait for your approval before they run.

How it is built

Echo is three services in one repo. The web app is Next.js; the browser never calls the backend directly, because every request goes through route handlers that keep the JWT in an httpOnly cookie. The backend is Go with Fiber and owns auth, sessions, per-user settings with provider keys encrypted at rest, versioned system prompts and a small memory API. The agent service is Bun with Hono and runs one mission per chat turn, calling back into the backend for memory and prompts with a short-lived service JWT.

Architecture: browser to web to backend to agent, with Postgres, Redis and LLM providers
Browser, web, backend and agent, with Postgres, Redis and the model providers.

The harness

An agent decides its own next step, so it can also decide to do something expensive forever. Every mission runs inside a harness that watches the loop: it stops repeated tool calls, enforces cost and step budgets, compacts the context when it grows, and holds protected tools until the user approves them. Built-in tools are web search, a todo list and delegation to a sub-agent, and MCP tools can be plugged in.

Where it is now

Postgres is the only hard dependency; Redis is used for locks and caching and can be turned off. I wrote up how the agent service scales, including the approval flow across replicas, in a separate blog post. The source is on GitHub.