Tsugite (継ぎ手) is an agent framework where you define AI agents as markdown files and run them from the CLI, a web UI, or through scheduled tasks.
I built it because none of the existing agent frameworks did what I wanted. I needed something self-hosted, model-agnostic, and simple enough that an agent is just a text file I can edit and version control.
Originally it was meant to be a framework for micro-agents inspired by ESA, but has grown a lot since that goal.
A simple "hello world" agent looks like:
---
name: morning-brief
model: anthropic:claude-sonnet-4-20250514
tools: [web_search, fetch_text, write_file, final_answer]
---
You are a morning briefing assistant.
Current date: {{ now() }}
User location: {{ env("LOCATION", "unknown") }}
Check the weather, scan top news, and write a short briefing.
Use final_answer() to return the result.YAML frontmatter for config, markdown body for instructions, Jinja for dynamic context. Run it with:
tsu run +morning-brief "what's happening today"- Agents are markdown. A basic agent is just markdown with yaml frontmatter. Advanced agents are still just markdown but can use jinja templating and a special
<!--tsu -->syntax. - Code execution over tool-calling. Inspired by smolagents. Instead of using native tool calling, LLMs write python code. Tools are exposed as python functions.
- Any LLM. Plugin interface to add support for additional LLM providers. Built-in we have openai-compatible apis, ollama, anthropic, and claude code.
- Workspaces. Each workspace is a persistent directory with agents, skills, memory files, and config. The agent runs inside its workspace and can read/write files, spawn sub-agents, manage schedules, and persist state across conversations. Workspaces are entirely optional.
- CLI and/or Daemon with a Web UI Use
tsu runcommands for cli-only, or runtsu daemonfor a daemon that supports scheduled tasks, a web ui, and some other neat things.
tsugite-cli is a light kernel (CLI, built-in tools, providers, history). Optional
subsystems install as extras:
uv tool install tsugite-cli # recommended; kernel only
pipx install tsugite-cli # alternative
pip install tsugite-cli # or plain pip| Extra | Adds |
|---|---|
tsugite-cli[daemon] |
Daemon: HTTP API, web UI, scheduler, jobs, terminals (pty), sandbox, Discord |
tsugite-cli[web] |
web_search + YouTube transcripts |
tsugite-cli[sandbox] |
bwrap sandbox backend (also needs the bwrap binary) |
tsugite-cli[all] |
Everything above plus the optional tmux + provider plugins |
uv tool install "tsugite-cli[daemon]" # full server installThe package is tsugite-cli, the command is tsugite (or tsu for short).
# Initialize a workspace
tsu init my-workspace
cd my-workspace
# Run the built-in default agent
tsu run +default "summarize the files in this directory"
# Run an agent file directly
tsu run my-agent.md "do the thing"
# Start the daemon (web UI, Discord/Telegram bots) -- needs the [daemon] extra
tsu daemontsu run keeps its terminal output plain by default so logs are copy-pasteable and behave
in nested tmux / non-Rich-friendly shells. Pick a richer or quieter mode when you need it:
| Mode | When to use |
|---|---|
| Default (plain) | Everyday interactive runs and piped output (tsu run ... | less). |
--headless |
CI/scripts: result on stdout, no progress chrome. Combine with --verbose for stderr trace. |
--plain |
Force plain explicitly (same as the default; useful when overriding configs/aliases). |
- Multi-step workflows with
<!-- tsu:step -->to chain steps and pass data between them - Scheduling built-in cron for recurring agent tasks (daily summaries, monitoring, etc.)
- Web UI for conversations, with Discord as an alternative interface
- Sub-agents that can spawn other agents for specific subtasks
- Skills directory-based knowledge modules (mostly) following the agentskills.io SKILL.md format
- Hooks that fire shell commands on lifecycle events (post-tool, pre-message, pre/post-compact)
- Sandbox (linux only) via bubblewrap with filesystem and network isolation
Agents support YAML frontmatter for configuration:
---
name: code-reviewer
model: anthropic:claude-sonnet-4-20250514
max_turns: 15
tools: [read_file, list_files, web_search, final_answer]
auto_load_skills: [coding-standards]
---You can restrict which tools an agent has access to, set turn limits, auto-load skills, attach context files, and extend other agents. TODO: See docs/ for the full spec.
Multi-step agents use <!--tsu --> comments as directives:
<!-- tsu:step name="research" model="openai:gpt-4o" -->
Research the topic and save findings to a variable.
<!-- tsu:step name="write" -->
Using the research from the previous step, write a summary.
The variable `research` is available as a Python variable.For a complete example, check the built-in default agent.
On Linux only (for now), agent code runs inside a bubblewrap sandbox when you pass --sandbox:
tsu run +default "task" --sandbox --allow-domain "github.com"
tsu run +default "task" --sandbox --no-networkFilesystem access is limited to the workspace. Network goes through a filtering proxy that only allows domains you specify.
The daemon can also sandbox its agents (off by default, configured in daemon.yaml). See docs/sandbox.md.
All paths follow XDG Base Directory conventions and can be overridden with the standard environment variables.
| Path | Default | Contents |
|---|---|---|
$XDG_CONFIG_HOME/tsugite/ |
~/.config/tsugite/ |
config.json, daemon.yaml |
$XDG_DATA_HOME/tsugite/history/ |
~/.local/share/tsugite/history/ |
Session history (JSONL per session) |
$XDG_DATA_HOME/tsugite/daemon/ |
~/.local/share/tsugite/daemon/ |
Daemon state |
$XDG_DATA_HOME/tsugite/secrets/ |
~/.local/share/tsugite/secrets/ |
Encrypted secrets (secrets.db) |
$XDG_DATA_HOME/tsugite/usage/ |
~/.local/share/tsugite/usage/ |
Usage (cost and token) tracking (usage.db) |
$XDG_DATA_HOME/tsugite/workspaces/ |
~/.local/share/tsugite/workspaces/ |
Workspace directories |
$XDG_CACHE_HOME/tsugite/attachments/ |
~/.cache/tsugite/attachments/ |
Attachment cache |
git clone https://github.com/justyns/tsugite.git
cd tsugite
uv sync --all-extrasThis is a personal project I use daily. It works for my use cases but isn't polished for general consumption yet. Issues and PRs welcome, but set expectations accordingly. Documentation is very sparse because I keep changing things.