This release is a pre-release and may not be stable for production use.
mh-tui
Terminal UI client for minimal-harness.
A local-running, single-user counterpart to
mh-orchestration-service
(cloud-distributed, multi-tenant). Both consume the same minimal-harness
SDK and share the same Agent / Tool / Memory / Event abstractions.
Position in the mh ecosystem
| Package | Role | Repo |
|---|---|---|
| minimal-harness | Core SDK (types, protocols, agent runtime, LLM abstraction, memory/session). This package depends on it. | J0ey1iu/minimal-harness |
| mh-service-kit | FastAPI service SDK with SSE engine. Provides the SSEAgentDriver used when a TUI agent delegates to a remote service via RemoteAgentBinding. |
J0ey1iu/mh-service-kit |
| mh-orchestration-service | Multi-tenant FastAPI gateway (sessions, eval, M2M auth). The cloud counterpart of this TUI. | J0ey1iu/mh-orchestration-service |
| agent-tool-service | Example service in the umbrella repo. The TUI can target its agents via RemoteAgentBinding. |
J0ey1iu/mh-incubator |
| mh-incubator | Umbrella workspace that wires every package together for end-to-end demos. | J0ey1iu/mh-incubator |
Built-in tools (
bash,local_file_operation) ship in this package asmh_tui.built_in. They are application glue for the TUI, not part of the SDK.
What This Is
mh-tui is the official Textual-based TUI front-end for the minimal-harness
agent SDK. It provides:
- Streaming chat with markdown rendering, reasoning display, and live tool call/result cards.
- Multi-agent support — switch between agents at runtime, handoff tasks to other agents, discover available agents.
- Persistent sessions — every conversation is auto-saved to local JSONL
files; resume from the
/sessionspicker. - Tool picker — toggle built-in tools (
bash,local_file_operation) and external user-defined tools via/tools. - Mid-run interrupt — press
Escto gracefully stop LLM streaming and tool execution. - Slash commands —
/config,/tools,/new,/sessions,/share,/compact,/dump,/quit, etc. @file picker — type@to fuzzy-match files in the current working directory and insert a path into the input.- Configurable themes — 21 textual themes including
tokyo-night,catppuccin-*,rose-pine-*,solarized-*, etc.
Installation
pip install mh-tui
This pulls in minimal-harness as a dependency.
Run
mhc # launch the TUI
mhc --help # (planned) CLI flags
MH_CONFIG_DIR=/path/to/dir mhc # override config directory
On first launch the TUI will create ~/.minimal_harness/ containing:
config.json— base_url, api_key, model, default_agent, themeagents.json— registered preset agentsmodels.json— model history (for the model picker)system-prompts/*.md— system prompt filessessions/*.json— conversation historylog/tui.log,log/error.log— daily-rotated logs
Note: The directory is intentionally named
~/.minimal_harness/(not~/.mh_tui/) for backward compatibility with pre-0.7.0 installations. Your existing data carries over without migration.
Keybindings
| Key | Action |
|---|---|
Enter |
Send message |
Ctrl+Enter |
Newline in input |
Esc |
Interrupt the running agent |
Ctrl+O |
Open config screen |
Ctrl+T |
Open tool picker |
Ctrl+Y |
Copy last assistant response |
Ctrl+D |
Dump runtime state (debug) |
Ctrl+C |
Quit (with confirmation) |
↑ / ↓ |
Navigate input history |
/ |
Open slash command menu |
@ |
Open file/directory picker |
Project Structure
src/mh_tui/
├── app.py # TUIApp + main()
├── context.py # AppContext (config + registry + session store)
├── session_controller.py
├── session_factory.py
├── session_replayer.py
├── runtime_session.py # ConversationSession (TUI's per-run binding)
├── runtime_tools.py # handoff + discover_agents (application glue)
├── logging_setup.py # TUI-mode file logging
├── config/ # ~/.minimal_harness/ JSON files
├── actions/ # Slash-command action handlers
├── widgets/ # Textual widgets
└── app.tcss # Textual CSS
Architecture
mh-tui is a Layer 3 application that consumes the Layer 1/2 abstractions
exposed by minimal-harness. It never instantiates Layer 1 types directly
(SimpleAgent, Tool); instead it composes Layer 2 services
(AgentRuntime, AgentRegistry, ToolRegistry, session store).
Layer 3: mh-tui (this repo)
TUIApp → SessionController → Display / Modals
↓ uses
Layer 2: minimal_harness.{agent,tool,llm,session}.runtime
AgentRuntime · Registry<> · SessionStore
↓ uses
Layer 1: minimal_harness.types / protocols
Agent · Tool · Memory · LLMProvider · Events
Extending
mh-tui discovers tools from ToolRegistry. To register a custom tool
before launching the TUI:
import asyncio
from mh_tui import TUIApp
from minimal_harness.tool.registry import ToolRegistry
from minimal_harness.types import LocalToolBinding, ToolMetadata
async def setup(registry: ToolRegistry) -> None:
await registry.register(
ToolMetadata(
name="my_tool",
display_name="My Tool",
description="Does something useful",
parameters={"type": "object", "properties": {}, "required": []},
binding=LocalToolBinding(fn=my_tool_fn),
)
)
registry = ToolRegistry()
asyncio.run(setup(registry))
TUIApp(registry=registry).run()
See examples/dev-with-mh/example_use_tui.py for a complete runnable demo.
Migration from minimal-harness ≤ 0.6.x
The TUI was previously shipped as minimal_harness.client.built_in. If you
have existing code that does:
from minimal_harness.client.built_in import TUIApp
Change it to:
from mh_tui import TUIApp
mhc remains the CLI command name — it now resolves to mh_tui.app:main.
License
Same as minimal-harness. See mh-incubator for the umbrella license.
Metadata
Release files for mh-tui 0.1.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mh_tui-0.1.0a1.tar.gz | 73.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mh_tui-0.1.0a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 171.0 kB
Release files / mh_tui-0.1.0a1.tar.gz
| Download URL | mh_tui-0.1.0a1.tar.gz |
|---|---|
| Size | 73.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b49ecd5123e276455dc35ff29a35e0c1e4d6a780d45a38235ce9420ac80b9b88
|
|
BLAKE2b-256 checksum How to use checksums |
023f789f437e7a662b4e26456744fe3045607e373d875b0c24f80d694a224d89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mh_tui-0.1.0a1-py3-none-any.whl
| Download URL | mh_tui-0.1.0a1-py3-none-any.whl |
|---|---|
| Size | 97.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
94712f1ff5fd348dbd14ce1617e125cd20fdaa77d6d92d97c55ce26a669235e2
|
|
BLAKE2b-256 checksum How to use checksums |
4f35c0464e28e5e7a7a6533c673bbb9cbeada847da1fbac652cb247b4dd51131
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|