A thin, extensible AI agent harness that lets an LLM discover and run skill files, use built-in tools, and talk to MCP servers. Designed from the ground up to host gstack skill packs and gbrain memory + MCP server out of the box.
The harness does four things — discovery, prompt assembly, tool exposure, and the
agent loop. Everything else (workflow logic, memory ops, "how to ship a PR") lives
in SKILL.md files outside the harness. The runtime stays ≈17 source files; new
behaviour is added by writing new skills, not by patching liteharness.
# 1. Install
uv venv
uv sync
# 2. Configure
cp .env.example .env # fill in ANTHROPIC_API_KEY
cp config.example.toml liteharness.toml # tweak skill source paths
# 3. Self-check
uv run liteharness doctor
# 4. Use
uv run liteharness skills list
uv run liteharness mcp status
uv run liteharness chat
uv run liteharness run "use the hello skill to self-test"git clone --depth 1 https://github.com/garrytan/gstack.git ~/code/gstackThen add the path to [skills].sources in liteharness.toml. Because the path
contains gstack, every discovered skill is auto-tagged with source = "gstack".
LiteHarness loads the skill body on demand (load_skill) and executes the steps
inside it using the built-in shell / read_file / write_file / edit_file
tools. There is no need for a host-adapter — liteharness reads the skill
directory directly.
Some gstack skills (
/qa,/browse) need Bun + Playwright/Chromium on the host. Install those yourself; the harness itself does not depend on them.
Do not install gbrain via
bun install -g github:.... That skips thepostinstallstep so its migrations never run. Always:git clone https://github.com/garrytan/gbrain.git ~/code/gbrain cd ~/code/gbrain && bun install && bun link gbrain init # creates the local PGLite brain
gbrain is wired in three complementary ways:
- MCP server —
gbrain serveis registered as an MCP server (default inconfig.example.toml). LiteHarness exposes 30+ memory/search tools under the prefixgbrain__*. The system prompt directs the agent to consultgbrain__*first when a question is about people, projects, decisions, or history. - Skill source — point
[skills].sourcesat~/code/gbrain/skillsto pick upbrain-ops,ingest,enrich, etc. plus the gbrainRESOLVER.mdandconventions/*.md. Routing docs are injected verbatim into the system prompt. - CLI fallback —
gbrainon$PATHis callable through theshelltool whenever a skill needs it.
liteharness.toml is parsed by tomllib and validated by pydantic. See
config.example.toml for the full schema. Highlights:
[agent].max_steps— hard cap on tool-use iterations per turn.[llm]— provider + model + sampling parameters.[skills].sources— list of directories scanned recursively forSKILL.md. Paths containinggstackorgbrainare auto-labelled.[tools].dangerous_command_confirm— when true (default), patterns likerm -rf,git push --force,DROP TABLE, etc. trigger a y/N prompt.[[mcp.servers]]— one block per MCP server to start over stdio.
| Command | Purpose |
|---|---|
liteharness chat |
Interactive REPL. |
liteharness run "<prompt>" |
One-shot execution; prints final reply. |
liteharness skills list [--source X] |
Show discovered skills. |
liteharness skills show <name> |
Print a skill's full body. |
liteharness mcp status |
Probe MCP servers; show connection + tool counts. |
liteharness doctor |
Environment self-check. |
liteharness --version |
Print version. |
Global flags: --config PATH, --workdir PATH, --verbose.
When the user types /skill-name args, the agent's first user message is replaced
by the full body of that skill followed by Arguments: args. This is a
fast-path bypass of the model's own routing — handy when you know which skill you
want.
| Want to extend | Where |
|---|---|
| Another LLM provider | Add src/liteharness/llm/<name>.py, implement LLMProvider. |
| A new tool | Subclass Tool under src/liteharness/tools/; register in cli._bootstrap. |
| Another MCP server | Add a [[mcp.servers]] block in liteharness.toml. |
| New skill source | Add the directory path under [skills].sources. |
| Long-conversation compaction | Implement Session.compact(); hook it from the agent loop. |
| MCP over HTTP/SSE | Extend mcp/client.py with another transport branch. |
| Custom danger policy | Replace ToolContext.confirm_callback or edit shell._DANGEROUS_PATTERNS. |
uv run pytest # unit tests (no live LLM/MCP)
uv run ruff check .
uv run mypy srcTests use a FakeLLMProvider that scripts turns deterministically; no API keys
needed.
The test is not open at present.
MIT.