Talon – a self-hosted harness for long-lived AI agents
Talon is a multi-platform, self-hosted AI agent framework supporting Telegram, Discord, Microsoft Teams, terminal, and a cross-platform desktop/mobile app. It offers pluggable backends (Claude Agent SDK, Kilo, OpenCode, Codex, OpenAI Agents) and full MCP tool access, with background agents, goal management, skill system, event bus, and hot-reloadable plugins. The architecture is clean, with frontend and backend independent, making it highly extensible.
Notifications You must be signed in to change notification settings
Fork 2
Star 63
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
940 Commits
940 Commits
.github
.github
apps/companion
apps/companion
bin
bin
docker
docker
docs
docs
native
native
packaging
packaging
prompts
prompts
scripts
scripts
src
src
.dockerignore
.dockerignore
.editorconfig
.editorconfig
.gitattributes
.gitattributes
.gitignore
.gitignore
.gitleaks.toml
.gitleaks.toml
.prettierignore
.prettierignore
.release-please-manifest.json
.release-please-manifest.json
CHANGELOG.md
CHANGELOG.md
Dockerfile
Dockerfile
LICENSE
LICENSE
MESH_BUILD_REPORT.md
MESH_BUILD_REPORT.md
README.md
README.md
SECURITY.md
SECURITY.md
docker-compose.yml
docker-compose.yml
nfpm.yaml
nfpm.yaml
package-lock.json
package-lock.json
package.json
package.json
release-please-config.json
release-please-config.json
tsconfig.json
tsconfig.json
vitest.config.ts
vitest.config.ts
Repository files navigation
Multi-platform agentic AI harness. Runs on Telegram, Discord, Microsoft Teams, the Terminal, and a cross-platform Desktop/Mobile companion app (Flutter), with a pluggable backend (Claude Agent SDK, Kilo, OpenCode, Codex, or OpenAI Agents) and full tool access through MCP.
Features
Multi-frontend Telegram (Grammy + GramJS userbot), Discord (discord.js), Microsoft Teams (Bot Framework), Terminal with live tool visibility, and a Desktop/Mobile app (Flutter) over a local/remote bridge
Pluggable backend Claude Agent SDK, Kilo, OpenCode, Codex, OpenAI Agents — selectable per-process via backend config. Streaming, model fallback, context-overflow recovery.
MCP tools Messaging, media, history, search, web fetch, cron jobs, triggers, goals, stickers, file system, admin controls
Plugins Hot-reloadable plugin system with talon plugin install/enable/disable (npm, git, or local sources). Built-in: GitHub, MemPalace, Playwright, Brave Search
Background agents Heartbeat (hourly by default — advances goals, proactively messages when something matters) and Dream (memory consolidation + diary)
Goals Persistent multi-day objectives the agent commits to in chat; every heartbeat run re-reads them, makes progress, and records what it did
Skills SKILL.md workflow bundles the agent authors and reuses, with talon skill install/enable/disable (local folders, git, or owner/repo — the Anthropic skills ecosystem installs directly)
Triggers Self-authored watcher scripts (bash/python/node) that wake the bot when conditions are met
Task table Every unit of agent work — chat turns, heartbeat, dream, isolated cron/trigger jobs — registered live; talon ps / talon kill
Event bus Typed internal pub-sub spine (task + turn lifecycle events); subsystems subscribe instead of importing each other; talon events -f
VFS Unified namespace at ~/.talon/ns over workspace, skills, scripts, logs, plus /proc-style live views of the task table, event bus, and plugin registry — a real filesystem (FUSE-backed live views), so plain ls/cat and every tool just work
Per-chat settings Model, effort level, and pulse toggle per conversation via inline keyboard
Model registry Models discovered from the active backend at startup — new models appear in all pickers automatically
Quick Start
git clone https://github.com/dylanneve1/talon.git && cd talon npm install
Interactive setup (select frontend, configure tokens, pick model)
npx talon setup
Start
npx talon start # configured frontend (daemon mode) npx talon chat # terminal chat mode
Prerequisites:
Node.js 24+
Backend-specific:
claude backend: Claude Code installed and authenticated (claude CLI on PATH).
kilo backend: nothing extra — @kilocode/sdk spawns a local server. Free models are accessible without auth; routed models use Kilo's own credentials.
opencode backend: nothing extra — @opencode-ai/sdk spawns a local server.
codex backend: install the codex CLI (npm i -g @openai/codex) and authenticate with codex login, CODEX_API_KEY, TALON_CODEX_KEY, or codexApiKey. OPENAI_API_KEY is used only as a fallback when no Codex login exists.
Standalone binary
Each release also ships self-contained binaries (no Node.js required) for Linux and macOS (x64 + arm64) and Windows (x64). Prompts and all native modules are embedded in the binary.
Homebrew (macOS / Linux)
brew install dylanneve1/talon/talon
Debian / Ubuntu — download the .deb for your arch from the release, then:
sudo apt install ./talon__amd64.deb # or _arm64.deb
Direct download — grab talon-- from the release, verify, run:
chmod +x talon-linux-x64 && ./talon-linux-x64 --version
macOS, if Gatekeeper blocks an unsigned binary:
xattr -d com.apple.quarantine ./talon-darwin-arm64
Verify a direct download against the release SHA256SUMS: sha256sum -c SHA256SUMS --ignore-missing.
The binary runs the full interactive/agent CLI (setup, start, chat, doctor, …). Hosting Talon's own MCP server (talon as an MCP stdio server for another client) still needs the npm/Node install — it spawns a tsx loader that isn't present in a compiled binary.
Architecture
index.ts Composition root
|
+-- core/ Platform-agnostic engine
| +-- agent-runtime/ Backend capability interfaces, events, stores
| +-- models/ Model layer: catalog, per-chat active model,
| | reasoning-effort vocabulary
| +-- prompt/ System-prompt assembly + prompts/system templates
| +-- background/ Agents that run without a user message:
| | heartbeat, dream, pulse, cron, triggers
| +-- tools/ MCP tool definitions + spawn/env contract
| +-- engine/ Message flow: dispatcher (per-chat serial,
| | cross-chat parallel), HTTP gateway for MCP
| | tool calls, backend lifecycle controller
| +-- plugin.ts Plugin loader, registry, hot-reload
|
+-- backend/
| +-- registry.ts Bootstrap-decoupled backend lookup
| +-- shared/ Cross-backend helpers (stream state, flow violation,
| | delivery contract, metrics, prompt format,
| | model retry, system prompt, usage)
| +-- remote-server/ Shared infrastructure for agent-server backends
| | (MCP registration, sessions, providers, lifecycle)
| +-- claude-sdk/ Claude Agent SDK (in-process MCP, hooks)
| +-- kilo/ Kilo HTTP server backend (streaming via SSE)
| +-- opencode/ OpenCode HTTP server backend
| +-- codex/ Codex CLI backend (@openai/codex-sdk)
| +-- openai-agents/ OpenAI Agents SDK backend (Responses API)
|
+-- frontend/
| +-- shared/ Cross-frontend presentation helpers
| +-- telegram/ Grammy bot + GramJS userbot
| +-- discord/ discord.js v14
| +-- teams/ Bot Framework + Graph API
| +-- terminal/ Readline CLI with tool call visibility
| +-- desktop/ Client bridge (HTTP + SSE) for the companion app
|
+-- storage/ Sessions, history, chat settings,
| cron jobs, media index, daily logs
+-- util/ Config, logging, workspace, paths, time
Dependency rule: core/ imports nothing from frontend/ or backend/. Frontends and backends depend on core types, never on each other. All five backends (Claude SDK, Kilo, OpenCode, Codex, OpenAI Agents) implement the same Backend capability interface from core/agent-runtime/capabilities.ts. Kilo and OpenCode additionally share the remote-server/ infrastructure because they wrap forks of the same upstream HTTP agent server.
Prompts: everything the model reads at session start is assembled by core/prompt/ from the files in prompts/ — see prompts/README.md for the assembly order, file ownership (user-editable vs package-owned templates), and the per-backend delivery contracts.
Backends
Select via the backend field in ~/.talon/config.json. All backends implement the same Backend capability interface — heartbeat, dream, and chat handlers are backend-agnostic.
Backend backend value Transport Notes
Claude SDK "claude" In-process via @anthropic-ai/claude-agent-sdk Requires the claude CLI on PATH. Hook-based turn termination.
Kilo "kilo" Local HTTP server via @kilocode/sdk SSE-streamed turns. Routes to many model providers via Kilo's auth.
OpenCode "opencode" Local HTTP server via @opencode-ai/sdk SSE-streamed turns; same MCP and session shape as Kilo (upstream fork).
Codex "codex" Per-turn subprocess via @openai/codex-sdk Requires the codex CLI from @openai/codex and Codex auth (codex login, CODEX_API_KEY, TALON_CODEX_KEY, or codexApiKey). MCP servers configured via TOML overrides at thread start.
OpenAI Agents "openai-agents" In-process via @openai/agents Responses API (or any OpenAI-compatible endpoint via TALON_AGENTS_URL / openaiBaseUrl). Persistent per-chat MCP bundles.
The Kilo and OpenCode backends share infrastructure (backend/remote-server/) since the upstream HTTP API is the same; each backend supplies its own SDK client, port, and delivery suffix. Codex is its own integration on top of the Codex CLI's JSONL event stream.
Desktop & mobile app
The desktop frontend turns the daemon into a client bridge — a versioned HTTP + Server-Sent-Events JSON API (the Talon Client Bridge Protocol, src/frontend/desktop/protocol.ts) that any GUI client can speak. The reference client is Talon Companion, a single Flutter codebase that runs on Windows, macOS, Linux, and Android.
Local (desktop): the app connects to a Talon on the same machine and launches one if needed (TALON_FRONTEND_OVERRIDE=desktop).
Remote (mobile/LAN): point the app at host:port + token; the bridge requires Authorization: Bearer … (or ?token= on the SSE stream) whenever a token is set.
Encryption: off-loopback binds serve HTTPS by default with a persistent self-signed certificate (~/.talon/keys/); the companion pins its SHA-256 fingerprint on first connect and refuses any change afterwards. The daemon logs the fingerprint at startup and /health advertises it. Opt out (or in, on loopback) with "tls": false / true in the desktop section.
The app provides multi-chat history, live streaming with reasoning + tool-call visibility, per-chat model/effort/pulse/reset, and settings sync — read and change the daemon's own config (default model, display name, timezone, pulse/heartbeat/dream) and restart it. See apps/companion/README.md.
Managing plugins & skills
Both stores are managed from the CLI; changes hot-reload into a running daemon (plugins) or apply on the next session (skills):
Plugins — npm specs, git repos, or local paths
talon plugin install @scope/my-talon-plugin # npm → module plugin talon plugin install some-mcp-server --mcp # npm → standalone MCP server (npx) talon plugin install owner/repo # git → module plugin talon plugin list # built-ins + configured entries talon plugin disable github # also toggles built-ins talon plugin remove my-talon-plugin
Skills — SKILL.md folders from local paths, git URLs, or owner/repo[/subpath]
talon skill install anthropics/skills/document-skills/pdf talon skill install ./my-skill --force talon skill list talon skill disable pdf # hidden from the prompt index, still readable talon skill remove pdf
Module plugins install under ~/.talon/plugins/; standalone MCP servers are registered as npx entries in config.json. Disabling keeps the entry (or a .disabled marker in the skill folder) so enabling restores it unchanged.
Built-in Plugins
GitHub
GitHub API access via the official GitHub MCP server. Gives the agent access to repositories, issues, PRs, code search, and more.
Requirements: Docker installed and running.
{ "github": { "enabled": true, "token": "ghp_..." } }
The token is optional --- defaults to the output of gh auth token if the GitHub CLI is authenticated.
Long-term Memory
Talon supports two long-term memory backends, selected via the unified memory section:
{ "memory": { "enabled": true, "backend": "mempalace" } }
Set "backend" to "mempalace" (local, vector sear
[truncated for AI cost control]