2026.10.13 화
ESP32 iPhone Agent: 맥 없이 에이전트에게 아이폰 맡기기
오늘의 픽: ESP32 iPhone Agent
ESP32 iPhone Agent 는 비전 모델이 아이폰을 직접 조작하게 하는 오픈소스 프로덕트다. 7달러짜리 ESP32-S3 보드를 아이폰에 꽂아 마우스와 키보드 역할을 맡기고, 화면은 AirPlay 미러링으로 읽는다.
오늘의 픽으로 선정한 이유는 맥도 개발자 계정도 없이 에이전트가 아이폰을 화면과 포인터만으로 조작하게 만들어서다.

- 출처
- GitHub
- 만든 방식
- Python, FastAPI, Arduino, UxPlay, Claude Opus 5.5
무엇이 문제인가
README 에 따르면 아이폰 자동화는 대부분 XCTest 나 WebDriverAgent 를 거친다. 그 방식에는 네 가지가 필요하다.
- 맥과 Xcode.
- 서명된 도우미 앱.
- 애플 개발자 계정. 무료 계정의 서명은 7일마다 만료된다.
- 접근성 트리. 앱은 이 기능으로 화면의 버튼과 글자를 목록으로 알려 준다. 게임처럼 앱이 목록을 주지 않으면 통하지 않는다.
README 의 비교표에는 다른 프로젝트 여덟 개가 있다. ESP32 블루투스 마우스나 HDMI 캡처 보드를 사용하는데, 대부분 맥이나 별도 캡처 장비가 필요하거나 폰에 앱을 설치해야 한다.
어떻게 해결했나
ESP32 iPhone Agent 는 사용자와 같은 방법으로만 아이폰을 다룬다. 화면은 AirPlay 미러링으로 읽는다. 아이폰이 컴퓨터의 UxPlay 로 화면을 보내고 GStreamer 가 그것을 JPEG 프레임으로 바꾼다. 입력은 USB HID마우스와 키보드 같은 입력 장치의 USB 규격. 운영체제가 별도 드라이버 없이 인식한다.로 넣는다. 7달러짜리 ESP32-S3 보드가 아이폰 USB 단자에 꽂혀 마우스와 키보드로 인식되고, iOS 의 AssistiveTouch 를 활성화하면 화면에 둥근 포인터가 생긴다. 클릭이 탭이고 드래그가 스와이프다. 보드에는 로직이 없다. Wi-Fi 로 서버에 접속해 move, click, type 같은 한 줄 명령을 받아 실행할 뿐이다. 모델은 OpenAI 호환 비전 모델이면 무엇이든 된다. 계획자가 목표와 화면으로 짧은 계획을 작성하고, 행동자가 새 스크린샷마다 다음 행동을 고른다. 폰에는 아무것도 설치하지 않는다.
무엇이 다른가
포인터가 상대 좌표라 서버는 포인터가 어디 있는지 알 수 없다. 그래서 탭 전에 포인터를 12 단위 흔들어 미러링 화면에서 찾아 보정하고, 행동 뒤에는 화면이 실제로 바뀌었는지 픽셀 차이로 확인해 빗나간 탭을 모델에 알린다. 같은 행동이 세 번 반복되면 다시 계획한다. 트레이드오프는 속도와 보이지 않는 화면이다. README 에 따르면 속도는 DGX Spark 두 대로 행동당 약 1.3초이고, 잠금 화면과 Apple Pay, DRM 영상은 미러링되지 않아 에이전트가 볼 수 없다. 키보드 입력은 ASCII 뿐이다.
어떻게 만들었나
- 커밋 20개가 2026-10-12 하루에 몰려 있고, 마지막 커밋은 기록 전날 밤이다.
- 그중 16개에 Co-authored-by 트레일러로 Claude Opus 5.5 가 적혀 있다.
- README 의 Quick start 첫 항목은 지시문이고, 사용자가 아니라 코딩 에이전트개발자 대신 코드를 읽고 고치고 명령을 실행하는 AI 프로그램. Claude Code, Codex 등이 있다.에게 붙여 넣게 되어 있다. 지시문에는 보드에 펌웨어기기에 내장돼 하드웨어를 제어하는 프로그램. TV 같은 기기에서는 운영체제를 포함한 시스템 프로그램 전체를 가리킨다.를 기록하고, UxPlay 와 서버를 설치하고, .env 를 작성하라고 적혀 있다.
- 파이썬 서버는 1,100줄 정도, 펌웨어는 Arduino 스케치 155줄, 테스트는 28개다.
실행해 보니
오늘은 서버만 확인했다. 보드도 아이폰도 없어 에이전트가 실제로 탭하는지는 보지 못했다. 서버는 아래 순서로 시험했다.
- 설치와 테스트.
python3 -m venv와pip install -e ".[dev]"로 18초가 걸렸고, 의존성이 FastAPI, uvicorn, httpx, Pillow 네 개라 가상환경은 91 MB 다. 테스트 28개는 1.45초에 통과했다. - 서버 실행.
.env에 가짜 모델 주소를 적고 서버를 실행하니 583 ms 만에 웹 UI 가 열렸다. UxPlay 가 없어 화면 수신 스레드는 FileNotFoundError 로 종료됐지만 서버는 그대로 작동했다. - 가짜 보드. 보드 프로토콜을 확인하려고 TCP 클라이언트를 만들어 7300 포트에 접속했다. 이 클라이언트는 무엇을 받든 ok 만 답한다. 서버는 그것을 보드로 받아들여 상태가 device true 로 바뀌었고, 웹 UI 의 첫 단계 Plug in the controller 가 초록으로 바뀌었다.
- 명령 전달. 디버그 전용 /api/raw 로 ping 과 move 10 -5 를 보내자 두 줄이 그대로 클라이언트에 도착했다. README 의 설명대로 보드에는 로직이 없다.
- 거절 응답. 보정 없이 탭을 요청하면 409 pointer not calibrated, 화면 없이 에이전트를 시작하면 409 no phone screen 으로 거절한다.
- 스크린샷 비교. 코드에서 비교 방식을 하나 더 확인했다. 포인터와 상태 표시줄을 가리고 나머지 픽셀만 비교하며, 체크 표시 하나 정도의 작은 변화도 여섯 픽셀 이상이면 바뀐 것으로 판단한다.
status 200 after 583 ms
hidagent.device board connected from ('127.0.0.1', 50552) hello power-on 1234
hidagent.device move 10 -5 -> ok (0 ms)
"POST /api/tap HTTP/1.1" 409 Conflict

확인하지 못한 것
- 에이전트 루프 전체. 보드에 펌웨어를 기록하고 아이폰을 미러링해야 에이전트가 계획을 작성하고 탭할 수 있다. README 의 행동당 1.3초도 측정하지 못했다.
- phone.py 의 보정. 포인터를 흔들어 찾을 때 밝은 배경과 어두운 배경에서 모두 통하는지, AssistiveTouch 의 포인터 속도를 바꾸면 얼마나 어긋나는지 다음에 확인하자.
판정
서버는 작동한다. 명령 네 줄로 설치와 테스트가 끝난다. 다만 보드와 아이폰이 없으면 에이전트가 화면을 보지도 탭하지도 못한다. 맥 없이 컴퓨터 한 대와 7달러짜리 보드로 아이폰을 에이전트에게 맡겨 보고 싶고, 행동마다 1초 넘게 기다려도 되는 경우에 써 볼 만하다. 작업 중에 잠금 화면이나 결제 화면을 거쳐야 한다면 이 프로덕트는 적합하지 않다. 그런 화면은 미러링되지 않아 에이전트에게 보이지 않는다.
얻어갈 것
- 화면이 버튼과 글자의 목록을 알려 주지 않으면(게임 등), 화면 픽셀과 입력 장치만으로도 자동화할 수 있는지 검토해 보자. 이 프로덕트는 AirPlay 와 USB HID 로 그렇게 했다.
- 프로덕트에 하드웨어가 필요하다면, 하드웨어 없이도 서버가 실행되고 테스트가 통과하는지부터 확인하면 된다. 여기서는 가짜 보드가 ok 만 답해도 프로토콜까지 확인됐다.
- 에이전트 루프에서는 행동마다 화면이 실제로 바뀌었는지 확인하자. 여기서는 여섯 픽셀 기준의 비교가 빗나간 탭을 모델에 알린다.
시작하기
git clone https://github.com/onehumanbeing/esp32-iphone-agentcd esp32-iphone-agent/server && python3 -m venv .venv && .venv/bin/pip install -e .cp .env.example .env && set -a && . ./.env && set +a && .venv/bin/python -m hidagent
- 필요한 것
- Python 3.10 이상 · XIAO ESP32S3 보드(약 7달러)와 arduino-cli, ESP32 코어 3.x · UxPlay(AirPlay 수신기)와 GStreamer · OpenAI 호환 비전 모델 API. 클라우드 API 또는 자체 운영 서버 · 아이폰의 AssistiveTouch 설정과 2.4 GHz Wi-Fi
- 비용
- MIT 라이선스, 무료. 비용은 보드 약 7달러와 비전 모델 API 사용료다. README 에 따르면 개발에는 로컬 모델을 NVIDIA DGX Spark 두 대로 운영했다.
보드에는 hardware/flash.sh 로 펌웨어를 기록하고, 서버는 http://<컴퓨터 IP>:8890 에서 웹 UI 를 연다. 오늘은 보드와 아이폰 없이 서버만 실행했다.
실행해서 확인한 절차다.
진행
- 3일확인 못 함
- 7일활발
- 15일예정
- 30일예정
- 90일예정
- 180일예정
- 365일예정
최근 확인 7일, 2026.10.19 월
- 런칭 이후 커밋
- 40
- 스타
- 473 → 3,107
- 최신 릴리스
- v0.1.0
- 마지막 커밋
- 2026.10.18
- 에이전트가 컴퓨터 없이 iPhone 앱에서 실행되도록 구조를 바꿨다. 보드가 iPhone 화면을 AirPlay 로 직접 받고, 앱과는 저전력 블루투스(BLE)로 통신한다.
- 모델 제공자로 OpenRouter 를 설정하고 모델을 검색해 선택할 수 있다. 실행이 실패하면 원인을 표시하고, 다시 연결한 뒤 재시도한다.
- v0.1.0: 구조를 바꾸기 전 방식을 첫 태그 릴리스로 남겼다. iPhone 화면을 AirPlay 로 Mac이나 Linux 컴퓨터에 보내는 방식이다.
3일 확인 못 함: 진행 확인을 2026.10.16 에 시작해서 그 전에는 확인하지 못했다.