local-send / local-send-photo / ax-read
Send text or photos and read real messages without a server session, by driving the KakaoTalk UI directly.
No server contact, no local DB dependency
local-send, local-send-photo, and ax-read drive the real KakaoTalk macOS app through the Accessibility (AX) API — selecting a chat row, typing into the composer or driving the native file picker, and reading rendered message bubbles. None of them talk to Kakao's servers or the local SQLCipher database. This is why they keep working even while server login is broken and the local DB is unreliable on current KakaoTalk builds.
How it works
All three commands find the target chat by its exact display name, the same text shown in KakaoTalk's chat list — not a chat-id. There is no local database to cross-check the target against anymore, so:
- Matching is exact, not substring — a search for
"Alice"will not accidentally match an"Alice & Bob"group chat. - If more than one visible chat shares the exact same display name, all three refuse to guess and return an error.
local-sendandlocal-send-photoadditionally require the chat to be listed in a config allowlist before they will send for real (see Safety below).
Requirements:
- KakaoTalk.app installed, running, and already logged in on this Mac
- Accessibility permission granted to your terminal (System Settings → Privacy & Security → Accessibility)
- Touch ID or the macOS login password available for device-owner authentication before a real send
local-send
openkakao-cli local-send <chat_name> <message> [OPTIONS]| Flag | Description |
|---|---|
-y, --yes | Skip the confirmation prompt |
--dry-run | Preview the action without sending |
--json | Output as JSON (global flag) |
# Preview first
openkakao-cli local-send "chat display name" "Hello from CLI!" --dry-run
# Actually send
openkakao-cli local-send "chat display name" "Hello from CLI!" -yBefore typing, local-send verifies the running process has KakaoTalk's official bundle/team code signature, requires one unique exact-name row in the chat list and an empty composer, and asks macOS to authenticate the device owner. It then reads the selected row and exact composer value back immediately before pressing Enter. After Enter may have been delivered, it polls the target window and reports success only when the composer clears and an additional exact-text outgoing message bubble appears. An old or incoming identical bubble is not accepted as proof of a new send.
This is a native macOS Accessibility/CoreGraphics path inside openkakao-cli; Orca and agent $computer-use skills are not runtime dependencies.
local-send-photo
openkakao-cli local-send-photo <chat_name> <file> [OPTIONS]| Flag | Description |
|---|---|
-y, --yes | Skip the confirmation prompt |
--dry-run | Preview the action without sending |
--json | Output as JSON (global flag) |
# Preview first
openkakao-cli local-send-photo "chat display name" ./family.jpg --dry-run
# Actually send
openkakao-cli local-send-photo "chat display name" ./family.jpg -yThe file is validated before anything is driven: the path is canonicalized (symlinks resolve to their target) and must be a valid UTF-8 path to a regular file between 1 byte and 50 MiB whose content is actually a JPEG, PNG, GIF, WebP, or HEIF image — a renamed non-image file is rejected regardless of its extension.
Like local-send, the command verifies KakaoTalk's code signature, requires one unique exact-name chat row, and refuses to touch a chat whose composer already holds a draft. It then drives KakaoTalk's native file picker primarily through semantic AX controls, with focus-verified coordinate fallbacks: the unique Send Files (⌘O) button opens the picker, the photo's absolute path is entered via Go to Folder, and the picker must show the selected file's exact name. Pressing Open only advances the picker to KakaoTalk's own single-file attachment preview — it does not send. macOS device-owner authentication then runs, and the recipient window and the previewed filename are read back and revalidated immediately before the final Send button is pressed. Completion is reported only when one additional outgoing [사진] (photo) bubble appears in the target window; any ambiguous outcome once Send may have been pressed is reported as uncertain — inspect the chat in KakaoTalk before retrying, the photo may already have been sent.
local-send-photo shares local-send's config gates (see Safety below), which are also skipped for --dry-run.
ax-read
openkakao-cli ax-read <chat_name> [OPTIONS]| Flag | Description |
|---|---|
-n, --count <N> | Max messages to return (default: 20) |
--json | Output as JSON (global flag) |
openkakao-cli ax-read "chat display name" -n 20
openkakao-cli ax-read "chat display name" --jsonOnly what's on screen
ax-read returns messages already rendered in the chat window. It does not scroll for you — if you need older history, scroll up in KakaoTalk first, then re-run the command.
Safety
local-send and local-send-photo are disabled by default and need two things enabled in ~/.config/openkakao/config.toml:
[safety]
allow_ax_send = true
allowed_send_chats = ["chat display name you want to allow"]allow_ax_send— the general opt-in, since both commands drive a real KakaoTalk window to send on your behalf.allowed_send_chats— an exact-match allowlist. A chat not on this list is rejected before anything is typed or attached. At runtime, a duplicate exact display name is also refused, and the selected row is read back before the send is committed.
Real sends also require macOS device-owner authentication. -y skips only the CLI's ordinary confirmation prompt; it does not bypass Touch ID/login-password authentication. This applies to local-send-photo as well.
Both checks are skipped for --dry-run, so you can preview against any chat name without touching config.
ax-read has no equivalent gate — it only reads what's already rendered on screen, so there's nothing to protect against beyond the exact-match/ambiguity check all three commands share.
When to use this vs local DB vs LOCO
| Scenario | Recommended |
|---|---|
| Send a real message, server login broken | local-send |
| Send a photo, server login broken | local-send-photo |
| Read what's currently visible in a chat, server login broken | ax-read |
| Full message history, server login working | read (LOCO) |
| Full message history, server login broken | not currently available — ax-read only sees what's rendered |