Product
Router, Messenger, and Mail, plus the plugins you add. The desktop app is not released yet.
What it works with.
Three programs, each with one job: model accounts, chat apps, and mail.
Router
PaidWhere your model accounts live.
Messenger
FreeThe chat apps you already use.
Mail
FreeGmail and Outlook.
Where you can open it.
The web app is live. The phone shell is built and does not reach a server yet. The desktop build is a test bench with no installer to release.
- Ask
- Plan
- Approve and run
Web
AvailableThis site, plus the console behind sign-in. Your account and its sessions are kept for you, so the browser and your other devices see the same account.
Mobile
In progressA phone app with four tabs and a sign-in screen. Sign-in returns to the app through its own link, and the app does not reach a server yet.
Desktop
Not releasedA test bench that talks to the assistant on your own computer. It is not a product client, and no installer is released.
Link a device once
Your account keeps your devices in step. When a connection drops, the device picks up from the last event it saw. The helper on that machine does only what its consent file allows, and it records every decision.
One server instance for now. The connection, the event log, and issued sign-ins are not shared between separate running copies, so running more than one copy is still ahead.
Sign in away from the browser
The apps do not hold a browser cookie, so they carry their own sign-in. A machine without a browser proves itself with a short code, and both app links are accepted.
It asks before it acts.
It works with the tools you turned on, waits for your answer, and says what it is about to do.
- Only the tools you turned on
- A session starts with exactly the tools you allowed. A tool you add yourself has sixty seconds to answer, and you can stop it sooner.
- It stops at your answer
- When a step needs permission, the request reaches you before it runs, and your answer decides whether it goes ahead.
- It says what it is about to do
- Ask for a plan and it answers in the shape you asked for; when the answer does not fit, it corrects it and tries again.
- The tools you already run
- It plugs into the tool servers you already have running, so what you set up elsewhere is available here too.
- Your other computer
- Read and write files and run commands on a machine you are not sitting at.
- Watch it work
- Each step is reported as it happens, so you watch the run instead of waiting for the last line.
- Long sessions keep going
- When a session grows long, it hands old context back so it can keep working without running out of room.
From another device
The device helper runs file, messenger, and command work for a linked device, so you can read and write files and run commands on a machine you are not sitting at.
- Approval
- A permission request reaches you before the call runs, and your answer decides whether it continues.
- Consent
- File, messenger, and command work on a linked device is refused unless that device's consent file allows it.
- Audit log
- Every allow and every deny is appended to an audit log, so you can read back what a device was permitted to do.
For developers.
The SDK, the interfaces each product exposes, and how the pieces connect. Everything here is what the repository does today, including what it does not do yet.
A typed SDK, and five surfaces behind each product.
The TypeScript SDK is generally available against protocol v1. It builds sessions, restricts tools, streams events, and returns validated structured output.
import { HoronAgentClient } from "./vendor/horon-agent-sdk";
// Your application implements this lookup. Honor the signal so a cancel stops the work.
async function lookupTicket(id: string, options: { signal: AbortSignal }) {
const response = await fetch("https://tickets.example.com/api/tickets/" + id, { signal: options.signal });
return (await response.json()) as { id: string; title: string };
}
// A private instance: its own sessions and sockets, stopped by close().
const client = await HoronAgentClient.launch({ workingDir: process.cwd() });
const session = await client.createSession({
workingDir: process.cwd(),
tools: {
enabled: ["read"],
custom: [
{
name: "lookup_ticket",
description: "Look up a ticket in the application's ticket store",
parameters: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
additionalProperties: false,
},
execute: async (input, { signal }) => {
const ticket = await lookupTicket(String(input.id), { signal });
return JSON.stringify(ticket);
},
},
],
},
});
// Ask for JSON against a schema; the SDK validates the answer and retries corrections.
const result = await client.runStructured<{ summary: string; count: number }>(
session.session_id,
"Summarize the open tickets for this repository",
{
schema: {
type: "object",
additionalProperties: false,
required: ["summary", "count"],
properties: {
summary: { type: "string" },
count: { type: "integer", minimum: 0 },
},
},
},
);
console.log(result.data.summary, result.data.count);
await client.close();
agent/sdk/typescript
Build the package from the source checkout at agent/sdk/typescript, then link that checkout into your project as ./vendor/horon-agent-sdk. There is no install command to copy.
- Sessions with a tool policyCreate a session with the tool set you want, or reconfigure it afterwards, using enabled, disabled, and custom lists.
- Custom tools with a deadlineYour execute callback receives validated input and a cancel signal, and 60 seconds is the ceiling before a call is cut.
- Structured outputAsk for JSON against a schema and the SDK validates the answer before you see it.
- Streaming eventsEvents arrive as they happen inside protocol v1, so you can render a run while it is still going.
- Long sessions stay workableCompaction gives context back when a transcript grows past what the window wants to hold.
- Permissions answered in codePermission prompts come to you, and your decision goes back with the request id.
The same five surfaces, twice
Mail and Messenger each put their SDK behind a CLI, an SDK, an MCP server, an HTTP API, and a terminal UI.
| Surface | Messenger | |
|---|---|---|
| CLI | horon-mailhoron-mail is present | horon-messengerhoron-messenger is present |
| SDK | horon-mail-sdkhoron-mail-sdk is present | horon-messenger-sdkhoron-messenger-sdk is present |
| MCP server | horon-mail-mcphoron-mail-mcp is present | horon-messenger-mcphoron-messenger-mcp is present |
| HTTP API | 127.0.0.1:8787127.0.0.1:8787 is present | 127.0.0.1:8787127.0.0.1:8787 is present |
| TUI | horon-mail-tuihoron-mail-tui is present | horon-messenger-tuihoron-messenger-tui is present |
What each product ships.
Capabilities, the surfaces you can call, and the limits that still apply. Plugins are listed here too.
Router
- CLI
- TUI
- HTTP API
- A built-in dashboard and a management API
- Its own OpenAPI document at /openapi.json
- mDNS discovery for other instances on the LAN
- A Redis-compatible RESP usage queue on the API port
Its compatibility audit covers 1,687 items: 835 implemented and verified, 707 partial, 145 unimplemented.
Messenger
- CLI
- SDK
- MCP server
- HTTP API
- TUI
- An MCP server with eleven tools
- An HTTP server on 127.0.0.1:8787 that opens loopback only
KakaoTalk is a skeleton: every operation returns NotImplemented.
Mail
- CLI
- SDK
- MCP server
- HTTP API
- TUI
- An MCP server with thirteen tools
- Credentials in 0600 files inside a 0700 directory, written atomically
No live new-mail push yet: no provider advertises listen or send_media.
Plugins
- A cdylib that exports one symbol over C ABI 1 and wire schema 1
Plugins are installed, enabled and loaded from the command line today; there is no store or marketplace yet.
MCP runs in both directions.
The agent consumes outside MCP servers. Mail and Messenger publish MCP servers of their own, so anything that speaks MCP can use them.
- External MCP serversstdio, HTTP/SSEHoron agent
The agent as an MCP client
It attaches over stdio or remote HTTP/SSE, and the servers are managed from the command line.
- Mail13 toolsMessenger11 toolsMCPAny MCP client
Mail and Messenger as MCP servers
Mail publishes thirteen tools and Messenger publishes eleven.
The plugin contract
In progressA plugin is a cdylib that exports one symbol, horon_agent_plugin_get_api_v1, over C ABI 1 and wire schema 1.
Installing, enabling and loading a plugin work from the command line today. There is no store or marketplace yet.
See the limits and roadmap- Entry symbol
- horon_agent_plugin_get_api_v1
- Boundary
- C ABI 1, wire schema 1
- Features
- tools, model_backend
Where Horon sits.
Three of these columns describe a kind of tool, not a named product. The last column is this repository, and each of its cells cites the file the sentence rests on. A blank reads None on purpose.
| Conversational chatbot | Agent CLI | Local proxy | Horon | |
|---|---|---|---|---|
| Multi-device sync | None | None | None | The event log replays to a device that reconnects |
| MCP both ways | None | Client side only | None | Consumes outside servers, and Mail and Messenger publish their own |
| Local credentials | The service holds the account | Provider keys in the environment | Several accounts and keys on one box | 0600 credential files inside a 0700 directory |
| Plugin contract | None | None | None | A cdylib exporting one symbol over C ABI 1Nothing loads one yet. |
| Model selection | The service picks the model | The provider you configure | Several accounts behind one endpoint | Several provider accounts, three wire formats translated |
