Terminal UI client for minimal-harness. The local-running counterpart of mh-orchestration-service.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mh_tui-0.1.0a1.tar.gz.
File metadata
- Download URL: mh_tui-0.1.0a1.tar.gz
- Upload date:
- Size: 73.6 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b49ecd5123e276455dc35ff29a35e0c1e4d6a780d45a38235ce9420ac80b9b88
|
|
| MD5 |
659af7e2588b77f51dbcd0c0bad8d5a5
|
|
| BLAKE2b-256 |
023f789f437e7a662b4e26456744fe3045607e373d875b0c24f80d694a224d89
|
File details
Details for the file mh_tui-0.1.0a1-py3-none-any.whl.
File metadata
- Download URL: mh_tui-0.1.0a1-py3-none-any.whl
- Upload date:
- Size: 97.4 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94712f1ff5fd348dbd14ce1617e125cd20fdaa77d6d92d97c55ce26a669235e2
|
|
| MD5 |
5d9777d94bce0533cd105970ee9e4d8c
|
|
| BLAKE2b-256 |
4f35c0464e28e5e7a7a6533c673bbb9cbeada847da1fbac652cb247b4dd51131
|