No agent framework
No LangChain, LangGraph, CrewAI, Mastra or agent SDKs. The loop, tool registry, context management, permissions, skills loader and agent switching are plain TypeScript. The only libraries are the model API client, the MCP SDK, zod, React, a WebSocket server and Vitest.
One agent per site or project
Each agent is a profile on disk: model, system prompt, budget, tools, shell mode, subagents, MCP connectors and skills, with its own brief, notes and workspace. Switch agents mid-conversation: the history is shared, the capabilities are not.
Real work in a shell
Commands run in a Linux container with Python, one workspace per agent, with no secret from the server. Per agent and per conversation, they run on their own (auto) or wait for your approval on each (ask).
Secrets stay in the server
Keys and tokens are encrypted at rest and reach only the MCP connectors of the agents in their scope. The model never sees them, and the shell never inherits them, unless you mark a variable for an agent's shell.
Anything that speaks MCP
Built in: Google Search Console, Google Analytics 4, PageSpeed, Serper, DataForSEO, Wikipedia and image generation. Or register any remote MCP server, with a token header or an OAuth login, and pick which tools ask before each call.
Skills, loaded only when needed
A skill is a method in a Markdown file. The prompt lists only each skill's name and description; the full method enters the context when a task needs it.
Memory you can read and edit
A brief and dated notes in plain Markdown. After a conversation, a small model proposes what to remember, and nothing is saved until you approve it.
Autonomy with a leash
Milestones you approve, each change proposed as an experiment with a measured baseline, routines on a schedule. Unattended runs never get an approval: what they needed waits in your inbox. Changes ship as pull requests you merge.
Long conversations that stay cheap
Append-only history. Old tool results are cleared from the model's view (and saved to the workspace), and past a larger size the conversation is summarized. Request prefixes stay byte-identical between steps, so prompt caching holds.