harnessview: an OSS Tool That Visualizes a Harness
When you’ve been building a harness for two months, you eventually want to see it. Not the files — those you can read — but the shape. Which hooks connect to which tools. Where the MCP servers live and whether their command paths actually exist. How many skills are wired versus documented-but-broken.
harnessview was built to answer those questions. It’s a standalone Node/TypeScript tool that scans a Claude Code harness and renders it as a live node graph. CHANGELOG entry: 2026-06-09, 09:17.
What It Does
Section titled “What It Does”harnessview reads four things from a Claude Code installation:
.claude/— agents (subfolders with__main__.pyorindex.ts), skills (.claude/skills/*.md), commands (.claude/commands/), and hooks (settings.jsonhooksarray)..mcp.json— MCP server definitions: name, command, args. It validates that each command path actually exists on disk and flags broken ones.settings.json— permissions, env var bindings, hook definitions. Walks the settings hierarchy (project → user) so overrides are visible.- Plugins — auto-detected by a pluggable adapter system.
From these it builds a HarnessGraph: a typed data structure where each node has a kind (free string: agent, skill, hook, mcp, command, plugin) and each edge represents a dependency. The kinds are open — adding a new node type doesn’t require changing the schema.
The graph is rendered with React Flow and elkjs in a local browser window. A Node server watches the filesystem with fs.watch; edits to .mcp.json or settings.json update the graph in real time via SSE.
Verified against ~/agent-system on first run: 52 nodes — 16 MCP, 14 skill, 8 command, 12 hook, 1 plugin, and the remaining agent/sub-tool nodes.
The CLI
Section titled “The CLI”npx harnessview # scan current directory, open browsernpx harnessview /path/to/harnessThere’s no configuration file needed. The scanner detects what’s present and adapts. If .mcp.json is missing, that section is empty. If settings.json has no hooks, the hook layer is skipped. The graph renders what actually exists, not what you said should exist.
Why Broken Paths Are Surfaced
Section titled “Why Broken Paths Are Surfaced”The MCP path-validation was the first real finding when harnessview ran against the live system. Several MCP server command fields pointed to binaries that had moved or had the wrong casing after a Homebrew upgrade. Those servers showed up as broken nodes in the graph (red border, tooltip explaining the file-not-found). The same class of bug — broken hook command path — is validated for hooks.
This is the “instrumentation that makes imperfection visible” principle applied to the harness itself. You can read the settings files and miss a broken path. The graph makes it a red node you notice immediately.
The Generalization from the Nerve Center
Section titled “The Generalization from the Nerve Center”harnessview’s org-chart renderer was a generalization of the one in Nerve Center v5 (/org endpoint). The NC5 chart is tightly coupled to a Supabase backend and the specific agent-system schema. harnessview abstracted that into an adapter-driven HarnessGraph contract:
- NC5: reads from
agents-registry.yaml(or the filesystem-composed/api/orgendpoint) and renders domains + agents + specialists. - harnessview: reads from
.claude/+.mcp.json+settings.jsonand renders hooks + tools + servers.
The same React Flow + elkjs pipeline renders both. The generalization was worth doing because harnessview has no dependency on Supabase, no requirement for an existing agent-system layout — it runs against any Claude Code project.
Going Public
Section titled “Going Public”The repo scan before pushing to GitHub:
-
Secret scan — checked all tracked files for keys, tokens, paths that reveal personal data. The
~/agent-systemorigin has JD-specific config; harnessview has none of that. -
PII audit — no Telegram chat IDs, no API key fragments, no personal path constants. The paths the scanner reads are discovered at runtime from the target harness, not hardcoded.
-
Push —
github.com/JDDavenport/harnessview, branchmain, default set, straymasterdeleted. Status: private at time of push, pending JD’s public/private decision.
CHANGELOG 2026-06-09 09:40: “Pushed harnessview to github.com/JDDavenport/harnessview (branch main, default set, stray master deleted, repo PRIVATE) after a clean personal-data/secret scan of tracked files.”
What It’s Not
Section titled “What It’s Not”harnessview does not:
- Run the agents or validate that they work
- Connect to any LLM or Supabase backend
- Require a specific directory layout beyond
.claude/or.mcp.json
It’s a read-only inspection tool. The value is the graph, not any action taken from it. Think of it as tree for a Claude Code harness — except that it understands the semantics (this is a hook, that’s an MCP server) and can flag broken connections.
Next: The CEO / Orchestrator Agent — the Opus-tier brain at the top of the hierarchy, its work-queue executor, and how it routes and gates decisions.