iOS 17+ · SwiftUI and UIKit
brew install ooolzhas/tap/annotate

Visual feedback for iOS apps that goes straight to your coding agent.

Freeze your running app, draw on it, tap an element or hold on an exact spot, and say what should change. Hit send, and the agent already open on your Mac gets the screenshots, the exact coordinates and your notes. You don't copy and paste anything or tag any views, and it lives only in your DEBUG build.

How you use it

  1. Tap the Annotate pill in your running app. The screen freezes.
  2. Draw around anything, tap an element to outline it, or hold for half a second to pin an exact spot.
  3. Type what should change. The chip says Fix; switch it to Question when you only want an explanation.
  4. Add as many notes as you like. To cover another screen, leave annotate mode, navigate and come back. One send carries them all.
  5. Hit ↑. Claude Code, already open on your Mac, picks it up.
  6. Keep watching the pill. It narrates the agent's progress, and each note's badge spins until it's handled, then turns into a green check.

It works the same from the Simulator and from a physical iPhone, with no extra setup. Every overlay type is behind #if DEBUG, so none of it ships in Release.

What your agent gets

An agent finds things by looking, so every note arrives with numbers it can check instead of a description it has to interpret.

Without it, you write "the blue button near the bottom is too small" and the agent guesses which one. With it, the agent reads Button "Get started" at (24, 300, 120×44), tapped at (84, 322), next to the text "Light that follows your day".

Part of the prompt the agent receives:

UI annotations from the running app: 3 pins on 1 screen. Please make these changes in the code.

Device: iPhone 17 Pro · iOS 26.0 · 402×874 pt @3x · dark · Dynamic Type L
Coordinates are iOS points, origin top-left. Screen images are 1x, so pixel = point.

1. Button "Get started" at (24, 300, 120×44) — tapped (84, 322), 21% across, 37% down
   bigger, tighter
   Nearby text: "Light that follows your day"
   Crop: …/crops/1.png

2. Spot at (179, 678, 44×44) — tapped (201, 700), 50% across, 80% down
   too much empty space here

Agents talk back

Sending isn't the end of it. The agent reports to the phone while it works, pin by pin.

Agents report with the MCP tools or with the CLI:

annotate resolve <id> <pin> "what changed"
annotate dismiss <id> <pin> "why not"
annotate ask <id> <pin> "question"      # waits for the answer and prints it

Install

Let your agent do it

Tell Claude Code, Cursor or Codex:

Set up AnnotateKit from github.com/ooolzhas/annotatekit in this app.

The repo ships an annotate-setup skill that walks the agent through every project shape (Xcode project, XcodeGen, Tuist, SwiftPM), the CLI and the connection. In Claude Code, the plugin brings the skill, the MCP server and the CLI in one step:

/plugin install annotate --marketplace ooolzhas/annotatekit

On Claude Code older than 2.1.275, run /plugin marketplace add ooolzhas/annotatekit, then /plugin install annotate@annotatekit.

By hand

1. The overlay. Add the package with Swift Package Manager and link AnnotateKit to your app target (iOS 17+).

https://github.com/ooolzhas/annotatekit
import AnnotateKit

@main
struct MyApp: App {
    init() {
        Annotate.install()   // DEBUG-only; a no-op in Release
    }
    var body: some Scene { WindowGroup { ContentView() } }
}

Then add .annotate/ to your .gitignore.

2. The CLI. Skip this if you installed the Claude Code plugin. Pick one:

brew install ooolzhas/tap/annotate
npm install -g annotate-ios
mint install ooolzhas/annotatekit

Connect your agent

Pick how a send reaches your agent.

Claude Code + channels Recommended
Pushed into your open session the moment you hit send, even while Claude is idle. Start with claude --dangerously-load-development-channels plugin:annotate@annotatekit, or server:annotate without the plugin.
Claude Code, no flags
Run /annotate-watch. A watcher picks up each send.
Unattended
annotate run in the project root runs claude -p per send, with --permission-mode acceptEdits, resuming the conversation.
Cursor, Codex, VS Code, Claude desktop, any MCP client
Add the MCP server and ask the agent to "keep calling annotation_wait". Each call waits for your next send. Or say "check my latest annotation" now and then.

Channels are a Claude Code research preview. The development-channels flag lifts the allowlist check only for the server you name, and Claude Code asks you to confirm. Team and Enterprise orgs need an admin to turn channels on.

MCP configs for Cursor, VS Code and Codex

The server is annotate mcp over stdio, run from the project root.

// Cursor: .cursor/mcp.json
{ "mcpServers": { "annotate": { "command": "annotate", "args": ["mcp"] } } }

// Nothing installed? npx fetches the CLI on first run (macOS)
{ "mcpServers": { "annotate": { "command": "npx", "args": ["-y", "annotate-ios", "mcp"] } } }

// VS Code: .vscode/mcp.json
{ "servers": { "annotate": { "type": "stdio", "command": "annotate", "args": ["mcp"] } } }
# Codex: ~/.codex/config.toml
[mcp_servers.annotate]
command = "annotate"
args = ["mcp"]

Claude Code without the plugin: claude mcp add annotate --scope project -- annotate mcp