tiny-harness
An opinionated, production-grade agent harness for customer-facing agentic workflows:
A2A 1.0 in and out, MCP tools, Agent Skills and Agent Plugins, one Temporal workflow per
task, hooks around every operation, and a TUI and a web renderer. It is being built in
the stacked pull requests of issue #3;
the spec chain lives under docs/specs/issue-3/.
What is in the box
- An A2A 1.0 server (JSON-RPC and REST, streaming, push notifications) and an A2A client for remote agents; five extensions (task, channel, status, commands, A2UI 0.9.1).
- Conversations that stay open: a reply parks the task in
INPUT_REQUIREDuntil a participant sends the next message, completes it or cancels it; slash commands (/model,/effort,/sub-task,/status, or your own) run on the harness without a model call. - A core loop of hooks around every operation: ingest, assemble, compact, call the model, run tools, decide completion. Intrinsic tools cover plans, sub-tasks, help requests, participants, skills and UI.
- Temporal owns the whole request lifecycle: one workflow per task, every model and tool call an activity, workflow-managed retries, a durable event log, continue-as-new.
- Plugins (Agent Plugins manifests) bring MCP servers, skills, hooks and prompt extensions; models are OpenAI (Responses API, or any OpenAI-compatible server such as Ollama over Responses or Chat Completions) and Anthropic adapters.
- Two renderers: a Textual TUI and a React web renderer on the official A2UI renderer, each an A2A client through the official SDK of its language; the web renderer is also hosted at madarauchiha-314.github.io/tiny-harness/ui and talks to any harness whose URL you give it.
- Observability: JSON logs and OpenTelemetry spans (GenAI conventions), redacted.
Run the demo
export TEMPORAL_API_KEY="$(secret-tool lookup service temporal project tiny-harness)"
export OPENAI_API_KEY="$(secret-tool lookup service openai project tiny-harness)"
bun install --cwd renderers/web && bun run --cwd renderers/web build
uv run python -m examples.demo # A2A server + worker, web renderer at /ui
uv run tiny-harness tui --url http://127.0.0.1:8080 # as your OS user; --participant <id> to choose
No Temporal account? Run it with an embedded Temporal: the harness starts a local Temporal dev server for its own process (loopback only, persisted beside the store) and stops it on exit, so only the OpenAI key is needed:
unset TEMPORAL_API_KEY # refused in embedded mode
export OPENAI_API_KEY="$(secret-tool lookup service openai project tiny-harness)"
uv run python -m examples.demo examples/demo/config.embedded.toml
uv run tiny-harness --config examples/demo/config.embedded.toml tui # or: TUI hosting it all
Embedded mode is [temporal] mode = "embedded" in any configuration; it is for
development and single-host use, not production.
No OpenAI account either? Point the OpenAI adapter at any OpenAI-compatible server
with [openai] base_url — Ollama, OpenRouter, vLLM, LM Studio — and choose its wire API
with api = "responses" (the default) or "chat_completions". With a local
Ollama and embedded Temporal, the demo runs with no key and no
network:
OLLAMA_CONTEXT_LENGTH=16384 ollama serve & # the server first: `pull` talks to it
ollama pull qwen3:8b
unset OPENAI_API_KEY TEMPORAL_API_KEY # a local endpoint needs no key
uv run python -m examples.demo examples/demo/config.ollama.toml
See getting started for what happens next and deployment for running it for real: the server must sit behind an authenticating perimeter.
Install and run
pip install tiny_harness
export OPENAI_API_KEY=... # or set [openai] base_url to a local server
tiny-harness # opens the TUI
With no subcommand, tiny-harness is tiny-harness tui. With no --config, it reads
~/.tiny-harness/config.toml and creates it on the first run: a commented file that
selects embedded Temporal and keeps the store, the Temporal database and the log under
~/.tiny-harness/. The directory is created 0700 and the file 0600; a symlink or a
path owned by another user is refused. --config FILE wins and never touches the home
directory. tiny-harness --help names the file in effect.
A reply does not end the task. It waits in INPUT_REQUIRED · awaiting-next-message
until you send the next message, Complete it (ctrl+d in the TUI, the button in the
web renderer) or Cancel it (ctrl+c, or the button). Type / for the commands:
| Command | What it does |
|---|---|
/model [<name>] |
Show, or choose, the task's model from [openai] models |
/effort [low|medium|high] |
Show, or set, the task's reasoning effort |
/sub-task <description> |
Open a sub-task in the same context; f4 returns to the parent |
/status |
The task's state, model, effort, plan progress and sub-tasks |
A /word that is not a registered command goes to the model as an ordinary message.
Develop
uv sync # creates .venv/ with every dev tool
uv run pre-commit install # lint, type-check, unit tests + commit-message hooks
See local development for the full guide, and the documentation site for the tech stack, architecture and decisions.
Metadata
Release files for tiny-harness 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tiny_harness-0.6.0.tar.gz | 188.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tiny_harness-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 443.4 kB
Release files / tiny_harness-0.6.0.tar.gz
| Download URL | tiny_harness-0.6.0.tar.gz |
|---|---|
| Size | 188.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b38c92a87fff46d2b75383cdd4508f40293a7985621dc4a0e9048311f23f1c16
|
|
BLAKE2b-256 checksum How to use checksums |
3fd1265b14f42d2d692818ac1899f3ea25dd613c5dfee3507e15876fc612b3a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / tiny_harness-0.6.0-py3-none-any.whl
| Download URL | tiny_harness-0.6.0-py3-none-any.whl |
|---|---|
| Size | 254.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8cd9f2961b6df0987fde2bf83ef34d0f14bbf4a3bb98a94d087b7822cd258a77
|
|
BLAKE2b-256 checksum How to use checksums |
5832f42b64d711de939778b9129662c5cedb1a5e3636f27f050e5fc8a063eaec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log