ihme
Manage iCloud Hide My Email addresses โ list, create, edit, deactivate, export
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Manage iCloud Hide My Email addresses โ list, create, edit, deactivate, export
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | ihme |
| description | Manage iCloud Hide My Email addresses โ list, create, edit, deactivate, export |
| triggers | ["hide my email","HME","icloud email","private relay","generate email","email alias","disposable email"] |
| tools | ["ihme"] |
Prefer the local checkout when available, so agents use the newest CLI changes:
cd worktree/ihme-cli
make install
make install builds ihme and copies it to $GOPATH/bin/ihme, or to
~/go/bin/ihme when $GOPATH is unset. Make sure that directory is on PATH.
If the checkout is unavailable, install a release:
# macOS (Apple Silicon)
curl -sL https://github.com/lroolle/ihme-cli/releases/latest/download/ihme_macOS_arm64.tar.gz | tar xz && sudo mv ihme /usr/local/bin/
# macOS (Intel)
curl -sL https://github.com/lroolle/ihme-cli/releases/latest/download/ihme_macOS_x86_64.tar.gz | tar xz && sudo mv ihme /usr/local/bin/
# Linux
curl -sL https://github.com/lroolle/ihme-cli/releases/latest/download/ihme_linux_x86_64.tar.gz | tar xz && sudo mv ihme /usr/local/bin/
# Or via Go
go install github.com/lroolle/ihme-cli/cmd/ihme@latest
First run requires ihme auth login (interactive โ Apple ID + 2FA).
Session lookup uses IHME_SESSION_PATH when set; otherwise it reads
$XDG_CONFIG_HOME/ihme/session.json, falling back to ~/.config/ihme/session.json.
ihme auth status --json first reads the local session file, then checks whether
that session can currently access iCloud. It includes Apple's /validate payload
as rawResponse. Use ihme auth status --local --json only when you want the
local file/timestamp check without a network request.
--verbose only logs method, URL, status, and size.
Current /validate success responses are account-info payloads with dsInfo
and webservices; they may omit a success boolean.
list --json โ {"addresses":[{anonymousId,label,hme,isActive,createTimestamp,note,...}],"count":N,"hints":{...}}
view --json โ {"result":{anonymousId,label,hme,forwardToEmail,isActive,...},"hints":{...}}
new --json โ {"candidates":["a@icloud.com",...],"label":"...","hint":"ihme new <label> --address <addr>"}
new -y --json โ {anonymousId,label,hme,isActive,...}
forward --json โ {"forwardTo":"...","available":[...],"hint":"ihme forward set <email>"}
auth status โ {"loggedIn":true,"appleId":"...","expired":false,"canAccessICloud":true,"rawResponse":{...},...}
deactivate โ {"status":"deactivated","hme":"...","id":"...","hints":{...}}
reactivate โ {"status":"reactivated","hme":"...","id":"...","hint":"..."}
# Auth check: local file + current iCloud access
ihme auth status --json
# Local auth file/timestamp only
ihme auth status --local --json
# List and search (hundreds of addresses supported)
ihme list --json --jq '.addresses[0:5]'
ihme list --search netflix --json
ihme list --active --tag dev --json
ihme list --sort label --json
# Create (two-step: generate candidates, then reserve)
ihme new github.com --json # step 1: get candidates
ihme new github.com --address abc@icloud.com --json # step 2: reserve one
ihme new github.com --yes --json # one-shot: take first
# View and edit
ihme view github.com --json --jq '.result.hme'
ihme edit github.com --label GitHub --tag dev,work
# Lifecycle
ihme deactivate github.com --json
ihme reactivate github.com --json
ihme delete github.com --yes --json
# Export
ihme export --format json
ihme export --search github --active -o filtered.csv
# Forward-to
ihme forward --json
ihme forward set user@icloud.com
All commands accepting <ref> resolve in order: anonymousId (prefix >= 6 chars) > email > label (exact) > label (fuzzy).
You'll see this address for years โ in password managers, email threads, account settings. It's a mask, but it's still yours. The core test:
Does it make a picture, and is the picture one you'd keep?
Two checks, in order:
Can you see it? Concrete nouns with physicality beat abstractions.
hilltop_desert is a landscape. pollen_pipe is an object. 63.fryer.immune
is a serial number. Specific things are memorable; categories are forgettable.
Would you keep it? No deficit words (debts, gristle, paupers), no clinical tone (immune, generic, baseline), nothing that carries weight. An address is a micro-identity โ it shouldn't feel assigned.
Bonus (elevates good to great, not a gate):
oranges.lobby for a service
whose developer is @oran_ge and whose logo is an O isn't luck โ it's fit.
Most addresses won't have this. When it's there, it's decisive.Secondary signals (tiebreakers, not filters):
65.ampere reads like a form field. Letters first.hilltop-desert beats relay_strop regardless of format.The best HME addresses feel like they could be a place on a map, a cocktail name, or an album title โ evocative without trying.
Errors include the fix command:
Error: <ref> required โ an address label, email, or ID
Usage: ihme deactivate <ref>
Example: ihme deactivate github.com
ihme auth login)Derive the label and search key. For a URL, use the registrable domain
without public suffix as the canonical label/search key: https://atypica.ai/...
becomes atypica; https://linear.app/... becomes linear. Drop paths,
query strings, callback URLs, referral parameters, dates, and campaign text.
Keep the full URL only as context for the user or note.
Check auth. Confirm the stored session can access iCloud before generating candidates:
ihme auth status --json
If it exits 2 or returns canAccessICloud:false, the user must run
ihme auth login interactively.
Check first. Search for existing addresses before creating:
ihme list --search <search-key> --json
--search matches label, address, and note by substring, so search the
canonical key, then inspect returned labels for the intended service.
Interpret matches by label, not by search key:
ask_user). When
you cannot ask, an explicit new <label> request has already decided
creation โ proceed, and flag the existing duplicate prominently in the
summary.Generate and evaluate. Get candidates and apply the taste test above:
ihme new <label> --json
Evaluate each candidate individually โ don't let bad neighbors taint a good
one. A pool with two duds and one strong image is not a "weak pool."
Reserve the best immediately โ don't ask unless no single candidate passes
taste ("does it make a picture you'd keep?"). When NO candidate passes
after rotation: interactively (embedded: ask_user), offer your top two
with a one-line image each and let the user pick; non-interactively,
reserve the least-bad and say plainly it was a compromise. Embedded runs
must articulate the verdict: reserve_address requires rationale (the
winner's image and why it fits) plus one rejected entry per candidate
you passed on, each naming its failure โ the user judges your pick
against these on the consent card.
Reserve with a useful note. ihme new supports --note; Apple stores it
in the address metadata, and ihme list --search searches it. Keep notes
compact and durable: why the address exists, the full signup/origin URL when
useful, account/workspace context, referrer/invite code, or owner/team. Do not
put passwords, recovery codes, API keys, cookies, or other secrets in notes.
ihme new <label> --address <candidate> --note "signup: https://example.com/auth/signup?via=team; workspace: acme" --json
Refresh the pool if it is weak. Apple's generate returns a FIXED pending pool that repeats โ calling generate again returns the SAME candidates until a slot is consumed. So if no candidate passes taste and the pool stops changing, do not keep generating. Consume a slot to force a fresh pool: reserve a throwaway and immediately delete it, then generate again.
refresh_candidates does the whole maneuver in
one call (reserve + delete + regenerate), capped at 2 per task.ihme new <label> --address <throwaway> --json # consume a slot
ihme delete <throwaway-id> --yes --json # clean it up
ihme new <label> --json # fresh pool
Show the result. State what was reserved and one line on why it was picked. If a compromise was made (weak pool, no good images), say so.
Use the service or team name as a bare noun. Dates age; names don't.
github, linear, colaos, atypica240501_chatgpt openai, 0315 claude felix 2, full signup URLs,
referral/callback parametersApply from a small controlled set when the user specifies context.
Common tags: #work, #dev, #personal, #throwaway, #team-<name>.
ihme list --sort date:asc to surface old addresses for audit.
Suggest pruning dead services quarterly.
You keep a memory across runs โ a plain markdown graph (journals for what you did, pages per topic, a flashcards page loaded into every run). Use it for continuity:
ihme memory search <service>. Embedded:
recall_memory.flashcards topic to have it loaded into
every future run; use any other topic for on-demand recall. Never
store secrets. Shell: ihme memory card <note>. Embedded:
remember.The procedure and taste rules above are shared by two executors; only the operation mapping differs.
External agent (Claude Code etc.): run the shell commands as written above.
Harnessed agent (ihme agent --via codex|claude|opencode): you
are a full coding agent driven BY ihme; the operations arrive as MCP
tools from the server named ihme (possibly prefixed, e.g.
mcp__ihme__reserve_address). Use only those tools for HME work โ
never the ihme shell CLI โ and follow the Embedded agent column
below. Consent and caps are enforced inside the tools.
Embedded agent (ihme new <label> --agent for scoped creation,
ihme agent for the general interactive assistant): the same file is
embedded in the binary and invoked with the user's task. There is no
shell โ operations map to in-process tools:
| Shell command | Embedded tool |
|---|---|
ihme auth status --json | auth_status |
ihme list --search <key> --json | search_addresses |
ihme new <label> --json (candidates) | generate_candidates |
| reserve + delete a throwaway, then generate | refresh_candidates |
ihme new <label> --address <a> --note <n> --json | reserve_address |
ihme deactivate <ref> --json | deactivate_address |
ihme edit <ref> ... | edit_note |
ihme memory search <query> | recall_memory |
ihme memory card <note> (or editing a page) | remember |
Embedded runs enforce the rotation cap (3 generation rounds) and
call budgets in code, and gate mutating actions outside the run's
granted scope behind user consent (--grant ask, the default) or
allow them unattended (--grant auto). Interactive embedded runs
also expose ask_user โ one short question, answered on the
terminal, max 3 per run. Non-interactive runs must decide within
the task scope and record assumptions instead of stalling.