# Hopper Debugger

Hopper debugging: macOS/iOS binaries, ObjC/Swift symbols, dyld, LLDB.

- Repository: https://github.com/steipete/agent-scripts (7431 stars)
- Category: Testing
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add steipete/agent-scripts --skill hopper-debugger -g -a claude-code -y`
Codex: `npx skills add steipete/agent-scripts --skill hopper-debugger -g -a codex -y`
Cursor: `npx skills add steipete/agent-scripts --skill hopper-debugger -g -a cursor -y`
Gemini CLI: `npx skills add steipete/agent-scripts --skill hopper-debugger -g -a gemini-cli -y`

## Description

Hopper debugging: macOS/iOS binaries, ObjC/Swift symbols, dyld, LLDB.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Hopper Debugger

Use Hopper through `mcporter` as a queryable disassembler, then combine the result with local source, LLDB, logs, and focused repros.

## Setup (one time)

Hopper 6.0+ **ships its own MCP server**. Do not install a third-party one.

```bash
mcporter config add hopper --scope home \
  --command "/Applications/Hopper Disassembler.app/Contents/MacOS/HopperMCPServer" \
  --description "Hopper Disassembler built-in MCP server (stdio)"
```

`--scope home` is required. The default scope is **project**, which writes `config/mcporter.json` into whatever repo you are standing in (untracked repo dirt, lost with the worktree).

Verify:

```bash
MCPORTER_LIST_TIMEOUT=25000 timeout 40 mcporter list hopper --brief
```

## Call convention, the one that bites

**Always pass arguments with `--args`. Never `--params`.** `mcporter` accepts an unknown `--params` flag *silently*, drops the payload, and the call arrives with no arguments. Hopper then answers `Document not found.`, which reads like a licensing or state problem and is not.

```bash
# WRONG, arguments silently dropped, fails with "Document not found."
mcporter call hopper.list_segments --params '{"document":"AppKit"}'

# RIGHT
mcporter call hopper.list_segments --args '{"document":"AppKit"}'
```

Related: the server does **not** fall back to the current document. A call with no `document` argument fails even when `current_document` returns a valid name. Pass `document` on every document-scoped call.

Document names come from `list_documents` and carry **no `.hop` extension** (window title `AppKit.hop` → document name `AppKit`).

If a call still fails, drive the server directly over stdio to see the raw JSON-RPC, this bypasses mcporter entirely and isolates who is at fault:

The rest: https://github.com/steipete/agent-scripts/blob/HEAD/skills/hopper-debugger/SKILL.md
