zeekay 4770743afb
Hanzo CI/CD / test (linux-amd64) (push) Skipped
Hanzo CI/CD / test (linux-arm64) (push) Skipped
Hanzo CI/CD / test-advisory (push) Skipped
publish / publish (push) Successful in 57s
Hanzo CI/CD / test-amd64 (push) Successful in 10m22s
Hanzo CI/CD / cicd (push) Successful in 1m40s
CI/CD / cicd (push) Successful in 12m7s
hanzo-mcp 1.1.33: the hanzo login when no key is set
A desktop app starts hanzo-mcp with no environment of its own, and
`hanzo login` never writes an apiKey into ~/.hanzo/config.json, so on a
fresh machine every Kai and Enso call answered NO_API_KEY. With no key
set, hanzo-mcp now asks the hanzo CLI beside it (or at hanzo.sh's
install path) for the login's token, `hanzo auth token`, and keeps it
for five minutes. Never a hanzo found on PATH: the Hanzo IDE package
installs /usr/bin/hanzo, which opens its window on any arguments.

Claude-Session: https://claude.ai/code/session_01M8RoubcPN71KgJuZ8LdBUL
2026-10-15 05:29:25 -07:00
2026-09-08 23:53:37 -07:00
2026-09-01 09:42:54 -07:00
2026-02-14 05:26:48 -08:00
2026-09-01 09:42:54 -07:00

Hanzo MCP

@hanzo/mcp

An MCP server for coding agents: files, shell, code, git, HTTP, project context and UI components, plus tools that call the Hanzo API. It speaks MCP over stdio, or over streamable HTTP with --transport http.

npm

Register it with an agent

The package declares Node 18 or newer. For Claude Code:

claude mcp add hanzo -- npx -y @hanzo/mcp serve

npx -y @hanzo/mcp install --claude-code runs that command with --scope user, which registers the server for every project.

claude mcp list then reports hanzo: npx -y @hanzo/mcp serve - ✔ Connected. With --scope project the entry goes into the project's .mcp.json instead, and Claude Code asks before it starts a server from that file. Other MCP clients take the same command in their server config:

{
  "mcpServers": {
    "hanzo": {
      "command": "npx",
      "args": ["-y", "@hanzo/mcp", "serve"]
    }
  }
}

The first start downloads the package; with an empty npm cache that took 80 to 100 seconds.

Tools

serve with no flags offers these, in the groups src/tools/unified/index.ts defines:

group tools
core fs, exec, code, git, fetch, workspace, ui
optional think, memory, hanzo, plan, tasks, mode, gimp
code intelligence code_search, code_context, code_ask, code_index
tracker tracker_boards, tracker_issues, tracker_create, tracker_update
kai kai_decide, kai_choice, kai_score, kai_noul, kai_tool_select, kai_next_action, kai_command_guard, kai_injection_screen, kai_extract, kai_log_triage, kai_recover, kai_agent_step

The core and optional tools take an action argument that picks the operation; ui takes method. The code intelligence, tracker and kai tools call https://api.hanzo.ai with the key in HANZO_API_KEY, or a local Kai instance via LOCAL_KAI_URL (a local kai serve, e.g. http://127.0.0.1:8080).

The kai tools ask Kai, Hanzo's decision model, typed questions about a case (POST /v1/decisions) and answer with calibrated probabilities: kai_choice picks a label, kai_score an ordinal level, kai_noul the probability that a statement holds, and kai_decide asks up to 100 of them in one call.

Beside the decision primitives: kai_injection_screen (rules and Kai's planted capability, kai-1.3), kai_command_guard (allow, ask or deny before a command runs), kai_tool_select (named tool, then BM25), kai_log_triage (failure signatures), kai_recover (loop breaker and a step for each failure class), kai_next_action (precondition filter, then BM25) and kai_extract (typed fields, abstaining near uniform). Only the screen, kai_extract and kai_decide call Kai; the others decide by rules because kai-1.2 measured at or near chance there. The cookbook has the held-out reads and fifteen runnable recipes. instructions is optional on every question and recommended. A kai_choice call:

{ "state": "I was charged twice for my March invoice. Please refund the duplicate.",
  "instructions": "Which team should handle this ticket?",
  "criteria": { "billing": "charges, invoices and refunds", "product": "how to use the product" } }

hanzo reaches every Hanzo Cloud subsystem: resource names one, action one of its operations, args that operation's arguments. With no action it lists the resource's operations, and resource: "describe" with args: {subsystem, op} says what one takes. The list is generated from cloud's catalog.

{ "resource": "graph", "action": "graphResolve",
  "args": { "entity": "acme/svc/api", "relation": "owner", "as_of": "2026-09-01T00:00:00Z" } }

Flags on serve change the set:

flag effect
--disable-tools plan,tasks removes the named tools
--core-only only the core group
--enable-ui adds the ui_* component tools
--enable-desktop adds hanzo_desktop and playwright_control
--enable-autogui, --enable-orchestration, --enable-ui-registry, --enable-github-ui, --enable-community-cryptuon add those tool sets
--full-surface adds the UI, AutoGUI, orchestration, UI registry and GitHub UI sets together

npx -y @hanzo/mcp serve --help lists every flag. This prints the tool names a server offers; put any flags after serve:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| npx -y @hanzo/mcp serve 2>/dev/null \
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{for(const l of s.split("\n"))if(l.includes("\"id\":2"))console.log(JSON.parse(l).result.tools.map(t=>t.name).join(" "))})'

Over HTTP

npx -y @hanzo/mcp serve --transport http --port 3000

The endpoint is the root path, http://127.0.0.1:3000/. POST JSON-RPC to it with Accept: application/json, text/event-stream; answers come back as server-sent events.

When a client shows no tools

Start the server by hand. A working one answers initialize with its name and version:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
  | npx -y @hanzo/mcp serve

With HANZO_MCP_DEBUG=1 in the server's environment, stderr also shows its working directory, the resolved binary, its arguments and the start of PATH.

Python

hanzo-mcp on PyPI is a separate server, built from hanzoai/python-sdk.

Development

pnpm install
pnpm build
pnpm smoke    # runs dist/cli.js over stdio: initialize, tools/call, resources

License

MIT

S
Description
Model Context Protocol server with 260+ tools for AI agents
Readme MIT
435 MiB
Languages
Rust 57.4%
TypeScript 37.7%
JavaScript 2.8%
Python 0.9%
Go 0.9%