Metadata-Version: 2.4
Name: hanary-mcp
Version: 0.22.13
Summary: Hanary MCP Server - Task management for Claude Code, OpenCode & OpenAI Codex
Author: Hanary
License: MIT
Keywords: claude,codex,hanary,mcp,openai,task-management
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: mcp>=1.0.0
Requires-Dist: requests>=2.32.5
Description-Content-Type: text/markdown

# Hanary MCP Server

[Hanary](https://hanary.org) MCP Server for Claude Code & OpenCode - task management that keeps new work outside the priority list until the user decides.

## What Hanary MCP Is For

Hanary MCP is an operating layer for AI coding assistants. It lets agents read, start, update, and complete work from Hanary while preserving the user's priority decisions.

The key rule is: agents may capture and organize new work, but they should not silently insert it into the active priority order. New tasks default to `needs_decision`, staying outside top-task, start, and complete candidates until the user explicitly chooses to prioritize them.

Use Hanary MCP when you want Claude Code, OpenCode, or Codex to work from your confirmed Hanary task structure instead of inventing its own task order.

Mental model:
- Hanary owns the user's task hierarchy and priority order.
- The AI assistant follows that order.
- New work is captured safely as `needs_decision`.
- Only explicit user intent promotes work into the active priority list.
- `executor_type: "ai"` means user-approved execution delegation, not AI-owned priority judgment.
- Meaning, priority, and completion judgment stay with the user.

## API vs MCP

Hanary's REST API remains the canonical product API. Use it for first-party apps, mobile or desktop clients, custom integrations, and any workflow where you control the application code that calls Hanary.

MCP is the AI-assistant integration surface on top of that API. Use it when you want tools like Claude Code, OpenCode, or Codex to discover Hanary actions automatically through `tools/list`, call them through `tools/call`, and receive the priority-boundary guidance directly in tool schemas and server instructions.

In practice:
- REST API is for application integrations.
- MCP is for agent integrations.
- `hanary-mcp` is the installable stdio bridge plus commands, skills, and agent guidance for local coding assistants.

MCP is not required to perform Hanary operations, but it avoids rebuilding the same tool wrapper for every AI host and keeps the assistant's behavior aligned with Hanary's user-owned priority model.

## Features

- **MCP Server**: Direct tool integration with Claude Code and OpenCode
- **Slash Commands**: `/hanary-status`, `/hanary-start`, `/hanary-done`
- **Skills**: Task management workflow with estimation patterns
- **Agents**: Task planner that drafts complex work decomposition for user review
- **Project Sync**: Safe checks, diffs, and updates for generated assistant files
- **Full Compatibility**: Works with both Claude Code and OpenCode

## Installation

```bash
# Using uvx (recommended)
uvx hanary-mcp --squad my-project

# Or install globally
uv tool install hanary-mcp
```

## Configuration

### Project-Scoped Setup (Recommended)

Use project-scoped setup when different repositories should bind to different Hanary squads. Run this from the project root:

```bash
uvx hanary-mcp init --squad your-squad-slug .
```

This creates project-local integration files:

- `.mcp.json` for Claude Code
- `opencode.json` for OpenCode
- `.codex/config.toml` for OpenAI Codex

Repeat the command in each project with that project's squad slug. This keeps AI assistants working inside the right Hanary squad without sharing one global `--squad` value across all projects.

The value after `--squad` is the squad slug, not the display name. For example,
if Hanary shows `FutureGate (futuregate)`, use `futuregate`:

```bash
uvx hanary-mcp init --squad futuregate .
```

After setup, verify the local binding:

```bash
uvx hanary-mcp doctor --squad your-squad-slug
```

Inside an AI assistant, use `get_current_scope` when the active project or squad is unclear before creating, starting, completing, or reordering tasks.
In project-scoped squad mode, the MCP server exposes the squad as the working boundary: use `get_top_task` for "what should I do next" inside that project. `get_overall_top_task` is intentionally not exposed in squad mode; use a separate personal/global Hanary MCP only when the user explicitly asks to leave the project scope.

### Keeping Project Files Synced

Use `hanary-mcp sync` after upgrading `hanary-mcp` when an existing project should
receive updated commands, skills, agents, or generated MCP config.

Start with a status check:

```bash
uvx hanary-mcp sync --squad your-squad-slug .
```

Review diffs before writing:

```bash
uvx hanary-mcp sync --squad your-squad-slug --dry-run .
```

Write only safe changes:

```bash
uvx hanary-mcp sync --squad your-squad-slug --write .
```

`sync --write` creates missing files and updates files that still match the last
managed template hash. It does not overwrite user-modified files. Local config
files such as `.mcp.json`, `opencode.json`, and `.codex/config.toml` are marked
for review instead of being overwritten, because they may contain squad slugs,
tokens, uv cache settings, or other project-specific choices.

Use `init --force` only when you intentionally want to overwrite existing
generated files. It can replace local edits in `.codex/config.toml`,
`.mcp.json`, and `opencode.json`; after using it, re-check any OS-specific
command, token, and cache settings.

The sync manifest is stored in `.hanary-mcp-sync.json`. It records template
hashes for files managed by `hanary-mcp`, so future upgrades can distinguish
safe generated-file updates from user edits. AI guidance changes are listed
separately in sync output because they affect assistant judgment boundaries.

### Claude Code Setup

1. Set your API token as a system environment variable:

```bash
export HANARY_API_TOKEN='your-token-here'
```

On Windows PowerShell, set a persistent user environment variable:

```powershell
[Environment]::SetEnvironmentVariable("HANARY_API_TOKEN", "your-token-here", "User")
```

Or set it only for the current PowerShell session:

```powershell
$env:HANARY_API_TOKEN = "your-token-here"
```

Restart your AI coding assistant after changing environment variables. Existing
Codex, Claude Code, or OpenCode processes do not inherit newly saved user
environment variables; if they start the MCP server without the token, you may
see an initialize/handshake failure such as `connection closed`.

2. Prefer `hanary-mcp init` above, or add this to your project's `.mcp.json` manually:

```json
{
  "mcpServers": {
    "hanary": {
      "command": "uvx",
      "args": ["hanary-mcp", "--squad", "your-squad-slug"]
    }
  }
}
```

Global CLI registration is useful only when one Hanary squad should be used everywhere:

```bash
claude mcp add hanary -- uvx hanary-mcp --squad your-squad-slug
```

Do not use global CLI registration with `--squad` when you need project-by-project squad separation. In that case, keep the `--squad` binding in each project's `.mcp.json` or `.codex/config.toml` instead.

### OpenAI Codex Notes

`hanary-mcp init` generates `.codex/config.toml` for the current operating
system. On macOS/Linux it uses `zsh -lc` so shell profile environment variables
can load. On native Windows it runs `uvx` directly because `zsh` is not available
by default:

```toml
[mcp_servers.hanary]
command = "uvx"
args = ["hanary-mcp", "--squad", "your-squad-slug"]

[mcp_servers.hanary.env]
UV_CACHE_DIR = ".uv-cache"
```

Keep `UV_CACHE_DIR` in the project root, such as `.uv-cache`, so Codex sandboxed
runs can write to it. If you edit the Codex config manually on Windows, avoid
copying a macOS/Linux `zsh -lc` command into that file.

### Environment Variables

Set these in your shell profile (`.bashrc`, `.zshrc`, etc.) or OS user
environment:

| Variable | Required | Description |
|----------|----------|-------------|
| `HANARY_API_TOKEN` | Yes | Your Hanary API token |
| `HANARY_API_URL` | No | API URL (default: https://hanary.org) |

## Available Tools

### Default Agent Workflow

Use Hanary MCP around one confirmed focus at a time:

```text
get_top_task -> get_task/update_task for context and notes -> start_task
-> do the work -> stop_task/complete_task against user-defined criteria
-> get_top_task for the next focus
```

`list_tasks`, `search_tasks`, `get_tasks_summary`, and `get_task_tree` are context tools. They help inspect related work, duplicates, blockers, hierarchy, or review state, but they should not replace `get_top_task` as the source of current focus.
When this server is started with `--squad`, `get_top_task` is the project focus boundary. Do not switch to overall/global focus unless the user explicitly asks to work outside the current project squad.

If `get_top_task` returns `is_llm_boundary=true`, treat it as a judgment boundary, not as permission to pick from a list. The response may include `human_prioritized_candidates`: these are user-prioritized tasks that are still marked `executor_type: "human"`. Report that prioritized work exists but has not been delegated to AI. Do not start the task, change `executor_type`, or skip to a lower-priority AI task unless the user explicitly delegates AI execution or explicitly chooses that lower-priority work.

### Task Management

- `get_current_scope` - Show whether this MCP server is in personal mode or bound to a project squad
- `get_top_task` - Get the current AI focus without bypassing the user's confirmed priority order
- `get_overall_top_task` - Personal mode only: get the user's highest-priority task across personal and accessible squad work. This tool is not exposed when the MCP server is bound to a project squad.
- `get_task` - Inspect a specific task with its purpose, process notes, children, ancestors, and time summary
- `list_tasks` - List tasks as supporting context; use `get_tasks_summary` for overviews
- `search_tasks` - Find related tasks, duplicates, or blockers without choosing focus automatically
- `get_task_tree` - Inspect hierarchy and decomposition without treating the tree as a new priority order
- `create_task` - Create a new task. Defaults to `needs_decision`; use `planning_status: "prioritized"` only when the user explicitly wants immediate priority placement.
- `update_task` - Update task title, description, completion criteria, or notes
- `complete_task` - Mark task as completed against user-defined completion criteria
- `uncomplete_task` - Mark task as incomplete
- `delete_task` - Soft delete a task
- `reorder_task` / `batch_reorder_tasks` - Change priority order only after explicit user-confirmed placement
- `move_task` / `batch_move_tasks` - Clarify hierarchy after user confirmation; moving does not make work executable by itself
- `hold_task` / `unhold_task` - Pause or resume focus eligibility only after explicit user intent

### Squad

- `list_my_squads` - List squads the current user belongs to so the user can choose a project-scoped squad slug
- `get_squad` - Get squad details and shared-problem context
- `list_squad_members` - List members who share the squad problem context
- `list_squad_events` - List events and deadlines for shared-problem coordination
- `get_online_members` - Check current presence when coordination is needed

### Messages

- `list_messages` - List squad messages for recent decisions, blockers, and shared context
- `create_message` - Send a squad message around the shared problem, decisions, or blockers

### Inquiry

- `list_questions` / `get_question` - Review questions used for Socratic analysis
- `add_claim` / `add_premise` - Draft claims and premises for user review; AI drafts are not final judgment

### Task Creation Policy

`create_task` records new work without assuming it belongs in the priority list. By default, new tasks are created as `needs_decision`, so they stay outside top-task, start, or complete candidates until the user decides whether to break them down or place them into priority. Use `planning_status: "prioritized"` only when the user explicitly wants the task placed in the priority order now, and provide `rank` with it. `rank` is ignored unless `planning_status: "prioritized"` is explicit, and required when it is explicit.

Work Notes and child tasks have different jobs. Use Work Notes for context, hypotheses, references, formulas, research results, deliverables, and overall reasoning. If a checklist item can be executed independently, have its result recorded separately, and be judged complete on its own, create it as a child task candidate with `parent_id` instead of burying it in notes. Measurements, tests, checks, and concrete actions often belong in child task candidates when they can be performed one by one. Creating child task candidates clarifies hierarchy only; it does not make them executable or prioritized unless the user explicitly asks for priority placement.

If the user explicitly asks to make a new child task the first executable child under a parent now, create it in one call with `parent_id`, `planning_status: "prioritized"`, and `rank: 0`. Otherwise, even the first child task under a parent remains a `needs_decision` candidate.

`executor_type: "ai"` does not mean the assistant decided the work is important. It means the user has approved AI execution for that task. Use it only when the user explicitly wants AI to do the work; otherwise omit it and let Hanary classify or leave the task waiting for human decision.

Priority placement and AI delegation are separate decisions. A task can be `planning_status: "prioritized"` and still remain a human task. In that case `get_top_task` should stop at the boundary and explain that the user must explicitly delegate AI execution or explicitly choose lower-priority AI work before the assistant changes `executor_type`, starts work, or moves down the priority list.

### Completion Policy

`complete_task` should be called against user-defined completion criteria. If the criteria are clear and verifiable, the agent may judge completion from evidence such as tests, deployment status, or document changes. If the criteria are missing, vague, or depend on taste, values, social agreement, or priority judgment, ask the user to define or confirm them. `completion_criteria` is required when completing through MCP so the user's completion standard is recorded; do not invent that criterion on the user's behalf.

## Development

```bash
# Clone and install
git clone https://github.com/hanary/hanary-mcp.git
cd hanary-mcp
uv sync

# Run locally
HANARY_API_TOKEN=your_token uv run hanary-mcp --squad test

# Run tests
uv run --with pytest python -m pytest
```

## Enhanced Features

Beyond the MCP tools, this project includes commands, skills, and agents for better UX.

### Slash Commands

| Command | Description |
|---------|-------------|
| `/hanary-status` | Show current task status and squad overview |
| `/hanary-start` | Begin working on top priority task |
| `/hanary-done` | Complete current task against user-defined completion criteria and get next |

### Skills

- **hanary-workflow**: Complete task management workflow with estimation patterns and best practices

### Agents

- **task-planner**: Drafts structured subtasks and estimates for user review

## Platform Setup

### Claude Code

Files auto-discovered from `.claude/` directory:

```
.claude/
├── commands/          # /hanary-status, /hanary-start, /hanary-done
├── skills/
│   └── hanary-workflow/
│       └── SKILL.md
└── agents/
    └── task-planner.md
```

For project-specific squad separation, use the `.mcp.json` generated by `hanary-mcp init --squad ...` in each project. Global CLI registration binds `hanary` to one squad across projects, so use it only for a single shared default:

```bash
claude mcp add hanary -- uvx hanary-mcp
```

### OpenCode

Files auto-discovered from `.opencode/` directory:

```
.opencode/
├── commands/          # /hanary-status, /hanary-start, /hanary-done
└── agents/
    └── task-planner.md
```

Skills are shared via `.claude/skills/` (OpenCode reads both `.opencode/skills/` and `.claude/skills/`).

Configuration in `opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcpServers": {
    "hanary": {
      "command": "uvx",
      "args": ["hanary-mcp"]
    }
  }
}
```

Note: `HANARY_API_TOKEN` must be set as a system environment variable.

## Directory Structure

```
hanary-mcp/
├── .claude/                    # Claude Code files
│   ├── commands/
│   │   ├── hanary-status.md
│   │   ├── hanary-start.md
│   │   └── hanary-done.md
│   ├── skills/
│   │   └── hanary-workflow/
│   │       ├── SKILL.md
│   │       └── references/
│   └── agents/
│       └── task-planner.md
├── .opencode/                  # OpenCode files
│   ├── commands/
│   │   ├── hanary-status.md
│   │   ├── hanary-start.md
│   │   └── hanary-done.md
│   └── agents/
│       └── task-planner.md
├── .mcp.json                   # MCP server config
├── opencode.json               # OpenCode config
└── src/hanary_mcp/             # MCP Server implementation
```

## License

MIT
