OpenHarness delivers core lightweight agent infrastructure: tool-use, skills, memory, and multi-agent coordination. ohmo is a personal AI agent built on OpenHarness — not another chatbot, but an assistant that actually works for you over long sessions. Chat with ohmo in Feishu / Slack / Telegram / Discord, and it forks branches, writes code, runs tests, and opens PRs on its own. ohmo runs on your existing Claude Code or Codex subscription — no extra API key needed. Join the community: contribute Harness for open agent development.
oh — OpenHarness & ohmo
OpenHarness delivers core lightweight agent infrastructure: tool-use, skills, memory, and multi-agent coordination.
ohmo is a personal AI agent built on OpenHarness — not another chatbot, but an assistant that actually works for you over long sessions. Chat with ohmo in Feishu / Slack / Telegram / Discord, and it forks branches, writes code, runs tests, and opens PRs on its own. ohmo runs on your existing Claude Code or Codex subscription — no extra API key needed.
Join the community: contribute Harness for open agent development.
One Command (oh) to Launch OpenHarness and Unlock All Agent Harnesses.
Supports CLI agent integration including OpenClaw, nanobot, Cursor, and more.
🔄 Agent Loop
• Streaming Tool-Call Cycle • API Retry with Exponential Backoff • Parallel Tool Execution • Token Counting & Cost Tracking |
🔧 Harness Toolkit
• 43 Tools (File, Shell, Search, Web, MCP) • On-Demand Skill Loading (.md) • Plugin Ecosystem (Skills + Hooks + Agents) • Compatible with anthropics/skills & plugins |
🧠 Context & Memory
• CLAUDE.md Discovery & Injection • Context Compression (Auto-Compact) • MEMORY.md Persistent Memory • Session Resume & History |
🛡️ Governance
• Multi-Level Permission Modes • Path-Level & Command Rules • PreToolUse / PostToolUse Hooks • Interactive Approval Dialogs |
🤝 Swarm Coordination
• Subagent Spawning & Delegation • Team Registry & Task Management • Background Task Lifecycle • ClawTeam Integration (Roadmap) |
An Agent Harness is the complete infrastructure that wraps around an LLM to make it a functional agent. The model provides intelligence; the harness provides hands, eyes, memory, and safety boundaries.
OpenHarness is an open-source Python implementation designed for researchers, builders, and the community:
oh --dry-run previews resolved runtime settings, auth state, skills, commands, tools, and configured MCP servers without executing the model, tools, or subagents.ready / warning / blocked readiness verdict with concrete next-step suggestions such as fixing auth, fixing MCP config, or running the prompt directly.oh, ohmo, and openharness into ~/.local/bin instead of prepending the virtualenv bin directory to PATH, which avoids clobbering Conda-managed shells.Shift+Enter to insert a newline while keeping plain Enter as submit.ohmo gains channel slash commands and multimodal attachment supportohmo channels support file attachments and multimodal gateway messagesreasoning_content support for thinking modelsOPENAI_BASE_URL env override, profile-scoped credential prioritycall_tool / read_resourceweb_fetch URL validation--debug logging, Windows cmd flash fixohmo personal-agent app:
oh setup now guides provider selection as workflows instead of exposing raw auth/provider internalsohmo ships as a packaged app with ~/.ohmo workspace, gateway, bootstrap prompts, and channel config flowStart here: Quick Start · Provider Compatibility · Showcase · Contributing · Changelog
# One-click install
curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash
# Or via pip
pip install openharness-ai
# One-click install (PowerShell)
iex (Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.ps1')
# Or via pip
pip install openharness-ai
Note: Windows support is now native. In PowerShell, use openh instead of oh because oh can resolve to the built-in Out-Host alias.
oh setup # interactive wizard — pick a provider, authenticate, done
# On Windows PowerShell, use: openh setup
Supports Claude / OpenAI / Copilot / Codex / Moonshot(Kimi) / GLM / MiniMax / NVIDIA NIM and any compatible endpoint.
oh
# On Windows PowerShell, use: openh
Want an AI agent that works for you from Feishu / Slack / Telegram / Discord?
ohmo init # initialize ~/.ohmo workspace
ohmo config # configure channels and provider
ohmo gateway start # start the gateway — ohmo is now live in your chat app
ohmo runs on your existing Claude Code subscription or Codex subscription — no extra API key needed.
# Single prompt → stdout
oh -p "Explain this codebase"
# JSON output for programmatic use
oh -p "List all functions in main.py" --output-format json
# Stream JSON events in real-time
oh -p "Fix the bug" --output-format stream-json
Use --dry-run when you want to inspect what OpenHarness would use before any live execution starts.
# Preview an interactive session setup
oh --dry-run
# Preview one prompt without executing the model or tools
oh --dry-run -p "Review this bug fix and grep for failing tests"
# Preview a slash command path
oh --dry-run -p "/plugin list"
# Get structured output for scripts or channels
oh --dry-run -p "Explain this repository" --output-format json
Dry-run is intentionally static:
Readiness levels:
ready: configuration looks usable; the next suggested action is usually to run the prompt directlywarning: OpenHarness can resolve the session, but something important still looks wrong, such as broken MCP config or missing auth for later model workblocked: the requested path will not run successfully as-is, for example an unknown slash command or a prompt that cannot resolve a runtime clientnext actions in the dry-run output tell you the shortest fix or follow-up step, such as:
oh auth loginoh -p "..." or open the interactive UI with ohOpenHarness treats providers as workflows backed by named profiles. In day-to-day use, prefer:
oh setup
oh provider list
oh provider use <profile>
| Workflow | What it is | Typical backends |
|---|---|---|
| Anthropic-Compatible API | Anthropic-style request format | Claude official, Kimi, GLM, MiniMax, internal Anthropic-compatible gateways |
| Claude Subscription | Claude CLI subscription bridge | Local ~/.claude/.credentials.json |
| OpenAI-Compatible API | OpenAI-style request format | OpenAI official, OpenRouter, DashScope, DeepSeek, SiliconFlow, Groq, Ollama, GitHub Models |
| Codex Subscription | Codex CLI subscription bridge | Local ~/.codex/auth.json |
| GitHub Copilot | Copilot OAuth workflow | GitHub Copilot device-flow login |
Typical examples:
| Backend | Base URL | Example models |
|---|---|---|
| Claude official | https://api.anthropic.com | claude-sonnet-4-6, claude-opus-4-6 |
| Moonshot / Kimi | https://api.moonshot.cn/anthropic | kimi-k2.5 |
| Zhipu / GLM | custom Anthropic-compatible endpoint | glm-4.5 |
| MiniMax | custom Anthropic-compatible endpoint | minimax-m1 |
Any provider implementing the OpenAI /v1/chat/completions style API works:
| Backend | Base URL | Example models |
|---|---|---|
| OpenAI | https://api.openai.com/v1 | gpt-5.4, gpt-4.1 |
| OpenRouter | https://openrouter.ai/api/v1 | provider-specific |
| Alibaba DashScope | https://dashscope.aliyuncs.com/compatible-mode/v1 | qwen3.5-flash, qwen3-max, deepseek-r1 |
| DeepSeek | https://api.deepseek.com | deepseek-chat, deepseek-reasoner |
| GitHub Models | https://models.inference.ai.azure.com | gpt-4o, Meta-Llama-3.1-405B-Instruct |
| SiliconFlow | https://api.siliconflow.cn/v1 | deepseek-ai/DeepSeek-V3 |
| NVIDIA NIM | https://integrate.api.nvidia.com/v1 | openai/gpt-oss-120b, nvidia/llama-3.3-nemotron-super-49b-v1 |
| Google Gemini | https://generativelanguage.googleapis.com/v1beta/openai | gemini-2.5-flash, gemini-2.5-pro |
| Groq | https://api.groq.com/openai/v1 | llama-3.3-70b-versatile |
| Ollama (local) | http://localhost:11434/v1 | any local model |
# List saved workflows
oh provider list
# Switch the active workflow
oh provider use codex
# Add your own compatible endpoint
oh provider add my-endpoint \
--label "My Endpoint" \
--provider openai \
--api-format openai \
--auth-source openai_api_key \
--model my-model \
--base-url https://example.com/v1
For custom compatible endpoints, OpenHarness can bind credentials per profile instead of forcing every Anthropic-compatible or OpenAI-compatible backend to share the same API key.
Run local models through Ollama's OpenAI-compatible endpoint:
# Add an Ollama provider profile
oh provider add ollama \
--label "Ollama" \
--provider Ollama \
--api-format openai \
--auth-source openai_api_key \
--model glm-4.7-flash:q8_0 \
--base-url http://localhost:11434/v1
Saved provider profile: ollama
# Activate and verify
oh provider use ollama
Activated provider profile: ollama
oh provider list
claude-api: Anthropic-Compatible API [ready]
...
moonshot: Moonshot (Kimi) [missing auth]
auth=moonshot_api_key model=kimi-k2.5 base_url=https://api.moonshot.cn/v1
* ollama: Ollama [ready]
auth=openai_api_key model=glm-4.7-flash:q8_0 base_url=http://localhost:11434/v1
--api-format copilot)Use your existing GitHub Copilot subscription as the LLM backend. Authentication uses GitHub's OAuth device flow — no API keys needed.
# One-time login (opens browser for GitHub authorization)
oh auth copilot-login
# Then launch with Copilot as the provider
uv run oh --api-format copilot
# Or via environment variable
export OPENHARNESS_API_FORMAT=copilot
uv run oh
# Check auth status
oh auth status
# Remove stored credentials
oh auth copilot-logout
| Feature | Details |
|---|---|
| Auth method | GitHub OAuth device flow (no API key needed) |
| Token management | Automatic refresh of short-lived session tokens |
| Enterprise | Supports GitHub Enterprise via --github-domain flag |
| Models | Uses Copilot's default model selection |
| API | OpenAI-compatible chat completions under the hood |
OpenHarness implements the core Agent Harness pattern with 10 subsystems:
openharness/
engine/ # 🧠 Agent Loop — query → stream → tool-call → loop
tools/ # 🔧 43 Tools — file I/O, shell, search, web, MCP
skills/ # 📚 Knowledge — on-demand skill loading (.md files)
plugins/ # 🔌 Extensions — commands, hooks, agents, MCP servers
permissions/ # 🛡️ Safety — multi-level modes, path rules, command deny
hooks/ # ⚡ Lifecycle — PreToolUse/PostToolUse event hooks
commands/ # 💬 54 Commands — /help, /commit, /plan, /resume, ...
mcp/ # 🌐 MCP — Model Context Protocol client
memory/ # 🧠 Memory — persistent cross-session knowledge
tasks/ # 📋 Tasks — background task management
coordinator/ # 🤝 Multi-Agent — subagent spawning, team coordination
prompts/ # 📝 Context — system prompt assembly, CLAUDE.md, skills
config/ # ⚙️ Settings — multi-layer config, migrations
ui/ # 🖥️ React TUI — backend protocol + frontend
The heart of the harness. One loop, endlessly composable:
while True:
response = await api.stream(messages, tools)
if response.stop_reason != "tool_use":
break # Model is done
for tool_call in response.tool_uses:
# Permission check → Hook → Execute → Hook → Result
result = await harness.execute_tool(tool_call)
messages.append(tool_results)
# Loop continues — model sees results, decides next action
The model decides what to do. The harness handles how — safely, efficiently, with full observability.
flowchart LR
U[User Prompt] --> C[CLI or React TUI]
C --> R[RuntimeBundle]
R --> Q[QueryEngine]
Q --> A[Anthropic-compatible API Client]
A -->|tool_use| T[Tool Registry]
T --> P[Permissions + Hooks]
P --> X[Files Shell Web MCP Tasks]
X --> Q
| Category | Tools | Description |
|---|---|---|
| File I/O | Bash, Read, Write, Edit, Glob, Grep | Core file operations with permission checks |
| Search | WebFetch, WebSearch, ToolSearch, LSP | Web and code search capabilities |
| Notebook | NotebookEdit | Jupyter notebook cell editing |
| Agent | Agent, SendMessage, TeamCreate/Delete | Subagent spawning and coordination |
| Task | TaskCreate/Get/List/Update/Stop/Output | Background task management |
| MCP | MCPTool, ListMcpResources, ReadMcpResource | Model Context Protocol integration |
| Mode | EnterPlanMode, ExitPlanMode, Worktree | Workflow mode switching |
| Schedule | CronCreate/List/Delete, RemoteTrigger | Scheduled and remote execution |
| Meta | Skill, Config, Brief, Sleep, AskUser | Knowledge loading, configuration, interaction |
Every tool has:
Skills are on-demand knowledge — loaded only when the model needs them:
Available Skills:
- commit: Create clean, well-structured git commits
- review: Review code for bugs, security issues, and quality
- debug: Diagnose and fix bugs systematically
- plan: Design an implementation plan before coding
- test: Write and run tests for code
- simplify: Refactor code to be simpler and more maintainable
- pdf: PDF processing with pypdf (from anthropics/skills)
- xlsx: Excel operations (from anthropics/skills)
- ... 40+ more
Skills can live in bundled, user, ohmo, project, or plugin locations. User-level skills are loaded from:
~/.openharness/skills/<skill>/SKILL.md
~/.claude/skills/<skill>/SKILL.md
~/.agents/skills/<skill>/SKILL.md
Project-level skills are enabled by default and are discovered from the current working directory up to the git root:
<project>/.openharness/skills/<skill>/SKILL.md
<project>/.agents/skills/<skill>/SKILL.md
<project>/.claude/skills/<skill>/SKILL.md
Disable project skills for untrusted repositories with:
oh config set allow_project_skills false
Use /skills to list loaded skills with their source and path. User-invocable skills can be run directly as slash commands, for example /deploy staging.
Compatible with anthropics/skills — use the SKILL.md directory layout above.
Built-in web_search uses DuckDuckGo HTML search by default. In regions where that endpoint is unreachable, point OpenHarness at a trusted public HTML search endpoint or your own SearXNG instance:
export OPENHARNESS_WEB_SEARCH_URL="https://your-searxng.example/search"
web_search and web_fetch keep trust_env=False for SSRF safety, so they do not automatically inherit HTTP_PROXY / HTTPS_PROXY. If you need a proxy, opt in with an OpenHarness-specific variable:
export OPENHARNESS_WEB_PROXY="http://127.0.0.1:7890"
The proxy URL must be HTTP/HTTPS and cannot contain embedded credentials.
Compatible with claude-code plugins. Tested with 12 official plugins:
| Plugin | Type | What it does |
|---|---|---|
commit-commands | Commands | Git commit, push, PR workflows |
security-guidance | Hooks | Security warnings on file edits |
hookify | Commands + Agents | Create custom behavior hooks |
feature-dev | Commands | Feature development workflow |
code-review | Agents | Multi-agent PR review |
pr-review-toolkit | Agents | Specialized PR review agents |
# Manage plugins
oh plugin list
oh plugin install <source>
oh plugin enable <name>
OpenHarness is useful as a lightweight harness layer around Claude-style tooling conventions:
For concrete usage ideas instead of generic claims, see docs/SHOWCASE.md.
Multi-level safety with fine-grained control:
| Mode | Behavior | Use Case |
|---|---|---|
| Default | Ask before write/execute | Daily development |
| Auto | Allow everything | Sandboxed environments |
| Plan Mode | Block all writes | Large refactors, review first |
Path-level rules in settings.json:
{
"permission": {
"mode": "default",
"path_rules": [{"pattern": "/etc/*", "allow": false}],
"denied_commands": ["rm -rf /", "DROP TABLE *"]
}
}
React/Ink TUI with full interactive experience:
/ → arrow keys to select → Enter/permissions → select from list/resume → pick from historyoh [OPTIONS] COMMAND [ARGS]
Session: -c/--continue, -r/--resume, -n/--name
Model: -m/--model, --effort, --max-turns
Output: -p/--print, --output-format text|json|stream-json
Permissions: --permission-mode, --dangerously-skip-permissions
Context: -s/--system-prompt, --append-system-prompt, --settings
Advanced: -d/--debug, --mcp-config, --bare
Subcommands: oh setup | oh provider | oh auth | oh mcp | oh plugin
ohmo is a personal-agent app built on top of OpenHarness. It is packaged alongside oh, with its own workspace and gateway:
# Initialize personal workspace
ohmo init
# Configure gateway channels and pick a provider profile
ohmo config
# Run the personal agent
ohmo
# Run the gateway in foreground
ohmo gateway run
# Check or restart the gateway
ohmo gateway status
ohmo gateway restart
Key concepts:
~/.ohmo/
soul.md
identity.md
ohmo isuser.md
BOOTSTRAP.md
memory/
gateway.json
ohmo config uses the same workflow language as oh setup, so you can point the personal-agent gateway at:
Anthropic-Compatible APIClaude SubscriptionOpenAI-Compatible APICodex SubscriptionGitHub Copilotohmo init creates the home workspace once. After that, use ohmo config to update provider and channel settings; if the gateway is already running, the config flow can restart it for you.
Currently ohmo init / ohmo config can guide channel setup for:
| Suite | Tests | Status |
|---|---|---|
| Unit + Integration | 114 | ✅ All passing |
| CLI Flags E2E | 6 | ✅ Real model calls |
| Harness Features E2E | 9 | ✅ Retry, skills, parallel, permissions |
| React TUI E2E | 3 | ✅ Welcome, conversation, status |
| TUI Interactions E2E | 4 | ✅ Commands, permissions, shortcuts |
| Real Skills + Plugins | 12 | ✅ anthropics/skills + claude-code/plugins |
# Run all tests
uv run pytest -q # 114 unit/integration
python scripts/test_harness_features.py # Harness E2E
python scripts/test_real_skills_plugins.py # Real plugins E2E
from pydantic import BaseModel, Field
from openharness.tools.base import BaseTool, ToolExecutionContext, ToolResult
class MyToolInput(BaseModel):
query: str = Field(description="Search query")
class MyTool(BaseTool):
name = "my_tool"
description = "Does something useful"
input_model = MyToolInput
async def execute(self, arguments: MyToolInput, context: ToolExecutionContext) -> ToolResult:
return ToolResult(output=f"Result for: {arguments.query}")
Create ~/.openharness/skills/my-skill.md:
---
name: my-skill
description: Expert guidance for my specific domain
---
# My Skill
## When to use
Use when the user asks about [your domain].
## Workflow
1. Step one
2. Step two
...
Create .openharness/plugins/my-plugin/.claude-plugin/plugin.json:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "My custom plugin"
}
Add commands in commands/*.md, hooks in hooks/hooks.json, agents in agents/*.md.
OpenHarness is most useful when treated as a small, inspectable harness you can adapt to a real workflow:
json and stream-json output in automation flows.See docs/SHOWCASE.md for short, reproducible examples.
OpenHarness is a community-driven research project. We welcome contributions in:
| Area | Examples |
|---|---|
| Tools | New tool implementations for specific domains |
| Skills | Domain knowledge .md files (finance, science, DevOps...) |
| Plugins | Workflow plugins with commands, hooks, agents |
| Providers | Support for more LLM backends (OpenAI, Ollama, etc.) |
| Multi-Agent | Coordination protocols, team patterns |
| Testing | E2E scenarios, edge cases, benchmarks |
| Documentation | Architecture guides, tutorials, translations |
# Development setup
git clone https://github.com/HKUDS/OpenHarness.git
cd OpenHarness
uv sync --extra dev
uv run pytest -q # Verify everything works
Useful contributor entry points:
CONTRIBUTING.md for setup, checks, and PR expectationsCHANGELOG.md for user-visible changesdocs/SHOWCASE.md for real-world usage patterns worth documentingOpenHarness handles both common terminal delete sequences, including the raw DEL byte (0x7f) that macOS Terminal.app sends for Backspace. If Backspace inserts spaces or visible control characters instead of deleting text, upgrade OpenHarness first.
For older versions that do not include this fix, use a terminal that sends a standard Backspace sequence or adjust your terminal keyboard profile as a temporary workaround.
MIT — see LICENSE.
Oh my Harness!
The model is the agent. The code is the harness.
Thanks for visiting ✨ OpenHarness!
“Hi HN, I built OpenHarness , an open-source terminal coding agent that works with any LLM: Ollama (free, local), OpenAI, Anthropic, Deepseek, Qwen or any OpenAI-compatible API. Install and run: npm install -g @zhi…”
“I built this because I kept trying to use Claude Agent SDK, Codex, and OpenCode programmatically, and they were too "heavy" and uncustomizable for that. I wanted a TypeScript library I could import into my own app and bu…”
“OpenHarness – Composable TypeScript SDK for building powerful agent harnesses”
“OpenHarness: A code-first, composable SDK to build powerful AI agents”
“Good question! OpenHarness is built on top of Vercel's AI SDK, and so the tools generally follow their Zod/JSON schema: https://ai-sdk.dev/docs/reference/ai-sdk-core/tool#tool.tool... Eventually, there will be sets of to…”
AI
Companies use AI to filter candidates. I just gave candidates AI to choose companies. Career-Ops (career-ops.org, also known as careerops) turns any AI coding CLI into a full job search command center. Instead of manually tracking applications in a spreadsheet, you get an AI-powered pipeline that: Career-ops is agentic: Claude Code navigates career pages with Playwright, evaluates fit by reasoning about your CV vs the job description (not keyword matching), and adapts your resume per listing.
AI
CLI-Anything: Bridging the Gap Between AI Agents and the World's Software 🌐 CLI-Hub: pip install cli-anything-hub then cli-hub install — browse, install, and manage all community-built CLIs. Want to add your own? Open a PR — the hub updates instantly. 🎬 See Demos: Watch AI agents use generated CLIs plus preview, live preview, and trajectory loops to produce real artifacts — CAD builds, 3D scenes, diagrams, gameplay, subtitles, and more.
AI
A self-hosted AI workspace -- meant to be the self-hosted version of the UI experience you get from ChatGPT and Claude. But with more jank and fun. Running on your own hardware, with your own data -- local-first, privacy-first, and no trojan. A full, hover-to-play tour lives on the landing page (docs/index.html). Defaults work out of the box: clone, run, then configure models/search/email inside Settings. Only edit .env for deployment-level overrides like APPBIND, APPPORT, AUTHENABLED, DATABASEURL, or a pre-seeded admin password.
AI
Most AI material teaches in scattered pieces. A paper here, a fine-tuning post there, a flashy agent demo somewhere else. The pieces rarely line up. You ship a chatbot but can't explain its loss curve. You hook a function to an agent but can't say what attention does inside the model that's calling it. This curriculum is the spine. 20 phases, 503 lessons, four languages: Python, TypeScript, Rust, Julia. Linear algebra at one end, autonomous swarms at the other. Every algorithm gets built from raw math first. Backprop. Tokenizer. Attention. Agent loop. By the time PyTorch shows up, you already know what it's doing under the hood. Each lesson runs the same loop: read the problem, derive the math, write the code, run the test, keep the artifact. No five-minute videos, no copy-paste deploys,