Skip to main content

LocalHarness logo

LocalHarness

GitHub stars License: MIT

Run AI agents on the models you already run locally.

LocalHarness is an open-source, self-hosted agent harness for local LLMs. It connects to a model you serve over an OpenAI-compatible API (vLLM, llama.cpp, Ollama or LM Studio), or starts one for you, and gives it agents, defined in YAML, with tools, MCP servers, a permission gate in front of every tool call, and helper agents that each work in a fresh context with only the tools they are allowed. A small core runs the agent loop; memory, the phone app, Discord, image generation, the self-improvement loop and a headless browser for JavaScript-rendered pages are plugins that you turn on or off with one command. Use it as a coding and research agent on your own machine, with no account and no telemetry.

LocalHarness: init detects your local model, start drops you into a ready agent, and it researches a question live with web search and multi-step tool calls

Why an agent harness for local models

  • Local models. The harness sizes a launch from the model's own files. It reads the served, trained and fitted context windows, prices a llama.cpp launch from the GGUF tensor table, keeps an MoE's experts in RAM when the GPU cannot hold them, and refuses a model that fits nowhere. It will not launch below the window the agent loop needs. A model without native tool calling gets an XML fallback. /effort off|low|high|max caps how much a model may think per request.
  • The model server. localharness start finds a model on your machine or offers one to fetch, writes it a preset (KV cache type, drafting and parsers are chosen at launch), serves it, and remembers your last choice. /model lists every launch this box can make, each with its runtime, weight placement and window, and switches in place. localharness model --autostart on starts the server with the harness, and localharness model --script prints the launch as a shell script. A turn survives a server restart.
  • Private by default. Memory is SQLite in your home directory, config is YAML, and the event stream, logs and bench results stay on your disk. Plugins, tool hooks and the phone app use the same event bus and public plugin API as the bundled plugins. No account, no telemetry (what start contacts); web search runs over DuckDuckGo with no key. MIT licensed.
  • Permissions. One permission gate stands in front of every tool call, helper agents included. An agent that reads untrusted content, a web page or an MCP result, is not given tools that change your machine; the check runs when an agent's tools resolve and fails closed. The endpoint, credential and allowed senders are set in machine-level config, and a cloned repository cannot change them. Threat model: SECURITY.md.

Quick start

Python 3.12 or later and uv. You do not need a running model server: the first localharness start finds a model on your machine or offers one to fetch.

uv tool install 'localharness[embeddings,mobile]'  # memory's CPU model + the phone app's dependencies (`plugins enable mobile` turns it on)
localharness start                   # finds a model (or offers one), sets up, opens a session

localharness plugins list            # every plugin and whether it is on
localharness plugins disable autoresearch
localharness plugins enable image --set comfyui_url=http://127.0.0.1:8188
localharness update                  # the latest release from PyPI

plugins enable and plugins disable write overrides.yaml and leave your config.yaml alone; --workspace changes a bundled plugin for one project only. Inside a session, /plugins enable <name> asks what the plugin needs, checks it, and restarts with your conversation kept. Keyboard shortcuts and multi-line input: docs/terminal-keys.md.

What agents can do

Agents are YAML. The built-in tools are read, write, edit, glob, grep, bash, python, web search and fetch, delegation to helper agents, and MCP servers, so a session works as a coding agent or a research agent. Drive it from the terminal, from Zed (localharness acp), from your phone on your own network (localharness mobile) or from Discord (--channel discord). With a vision model, drop a screenshot on the terminal, paste one into Zed or the phone page, or attach one on Discord.

Supported runtimes

Point it at vLLM, llama.cpp, Ollama or LM Studio; the agents, tools, permission gate and plugins are the same on all four. Every runtime is reached through one OpenAI-compatible client, and init can attach to an endpoint that is already running. Live-validated means run on the DGX Spark reference machine; recorded bench runs exist for vLLM only.

Runtime Harness starts the server Tool calling Token counting Live-validated
vLLM docker or binary native exact reference machine and bench
llama.cpp spawns llama-server XML / Hermes fallback exact reference machine
Ollama spawns ollama serve native exact with the exact-tokenizer extra, else estimated CPU round-trip
LM Studio drives headless lms native exact with the exact-tokenizer extra, else estimated CPU round-trip

A session with no temperature set sends none, so the server's sampling defaults apply; pin one on the server (llama-server's --temp, vLLM's --generation-config). Setup: llama.cpp, Ollama, LM Studio, vLLM (reference architectures); the code is the provider layer.

Plugins

Name What it does Default How to switch
image makes pictures with ComfyUI off localharness plugins enable image --set comfyui_url=<url>
mobile Mobile: the phone page, served with its event API by localharness mobile off; needs localharness[mobile] uv tool install 'localharness[mobile]' (name the other extras you use too: a reinstall keeps only the ones it names), then localharness plugins enable mobile --set public_url=<url>
memory persistent memory: facts recalled into each turn, memory tools, background consolidation on localharness plugins disable memory
dispatch chat: Discord off; needs localharness[dispatch] uv tool install 'localharness[dispatch]' (name the other extras you use too: a reinstall keeps only the ones it names), then localharness plugins enable dispatch --set discord.token=… --set discord.allow=<your user id>
autoresearch experiment loop on localharness plugins disable autoresearch
browser reads JavaScript-rendered pages through a sandboxed headless Chromium off; needs localharness[browser] uv tool install 'localharness[browser]' (name the other extras you use too: a reinstall keeps only the ones it names), then localharness plugins enable browser

Pages: image · mobile · memory · dispatch · autoresearch · browser, and on the site: image · mobile · memory · dispatch · autoresearch · browser.

Installed plugins live on your machine, not inside a project: a Python package with a localharness.plugins entry point beside LocalHarness, or a folder ~/.localharness/plugins/<name>/. None of its code is imported until localharness plugins enable <name>, which only your machine-level config can do. A plugin you turn on is trusted code that runs with your privileges: read SECURITY.md before you enable one.

Write a plugin

Copy the example plugin: one tool, one command, one slash command, one doctor check and two settings, tested in CI. The API is plugins/api.py; its version is "1", and changes since its first release have only added optional fields. Plugins written for the previous plugin API no longer load; the example plugin says how to port one.

Status

Early stage (v0.21.1, pre-1.0). Interfaces and config schema may change without notice. Each release's known limitations are listed in the CHANGELOG.

License

MIT

Metadata

Release files for localharness 0.21.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for localharness 0.21.1
File Size Uploaded Provenance
localharness-0.21.1.tar.gz 1.7 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for localharness 0.21.1
File Interpreter ABI Platform
localharness-0.21.1-py3-none-any.whl Python 3 none any Details

Total release size: 3.5 MB

Release files / localharness-0.21.1.tar.gz

Download URL localharness-0.21.1.tar.gz
Size 1.7 MB
Tags Source
SHA-256 checksum
How to use checksums
dd577551da58d50b1c6806c3999b52be2c68392a9d324ced1a9696bd380b91e9
BLAKE2b-256 checksum
How to use checksums
04364b762ce1d0d1f2ca1f0120f85e7a93a55c56b6615635ed23193cd97e0c3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / localharness-0.21.1-py3-none-any.whl

Download URL localharness-0.21.1-py3-none-any.whl
Size 1.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
cbd092e157589e03a1daa1fcf12f40a2d881c6b3ae4997811fd371e62d1db1b6
BLAKE2b-256 checksum
How to use checksums
f307f260b539fdde2de13050669a4671b92e8ae0239561cb1c8e1b8390d61e8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for localharness 0.21.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.21.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page