비공식 도구를 만들 때 가장 위험한 순간은 기능이 부족할 때가 아니라 기본값이 관대할 때입니다. 카카오톡 데스크톱 앱을 터미널에서 다루는 CLI를 오픈소스로 공개하면서 제일 먼저 정한 것도 어떤 기능을 넣느냐가 아니라 무엇을 기본값에서 잠글까였습니다. 사용자가 아무 옵션도 주지 않고 명령을 실행했을 때 계정에 가장 안전한 상태가 되어야 한다는 원칙입니다. 이 글은 그 원칙이 실제 명령 구조로 어떻게 굳어졌는지 정리합니다.
왜 기본값이 전부인가
메시징 자동화 도구의 사고는 대부분 "실수로 보냈다"에서 시작합니다. 반복문 안에 전송 명령이 들어갔거나, 테스트 스크립트가 진짜 방에 메시지를 뿌렸거나, 무인 스케줄러가 예상보다 자주 돌았거나 하는 식입니다. 문제는 이런 실수가 상대에게 스팸으로 보이고 스팸으로 보이는 계정은 제재로 직결된다는 점입니다.
그래서 이 도구는 "위험한 것은 켜야만 동작한다"를 뼈대로 삼았습니다. 사용자가 명령어를 잘못 조합하더라도 기본 상태에서는 서버에 쓰기 요청이 나가지 않게 막아 뒀습니다. 편의를 조금 포기하는 대신, 가장 흔한 사고 유형을 구조적으로 없애는 쪽을 택했습니다.
쓰기는 명시적 opt-in
전송, 삭제, 수정, 반응처럼 서버에 쓰기를 일으키는 작업은 기본적으로 비활성입니다. 이 명령들을 쓰려면 설정 파일에 allow_loco_write = true를 직접 적어 넣어야 합니다. 값 하나를 사람이 손으로 켜는 이 마찰이 의도적인 안전장치입니다. 복사해 온 스크립트가 무심코 메시지를 보내는 상황을, 설정을 켜지 않았다는 이유만으로 막아 줍니다.
읽기 전용 작업은 이 잠금과 무관하게 언제나 동작합니다. 채팅 목록과 메시지를 보는 일은 계정에 위험이 낮으니 잠그는 것은 어디까지나 쓰기뿐입니다. 안전과 편의의 경계선을 "서버에 무엇을 바꾸는가"로 그은 셈입니다.
dry-run으로 먼저 본다
쓰기를 켠 뒤에도 곧바로 실행하도록 두지 않았습니다. send, delete, edit, react 모두 --dry-run 플래그를 지원해서 실제로 서버에 나가는 대신 "무엇을, 어디로, 어떻게 보낼지"만 구조화해 보여 줍니다. --json과 함께 쓰면 이 미리보기가 그대로 기계가 읽는 형식이 됩니다.
이 흐름은 특히 에이전트나 스크립트가 도구를 부를 때 빛을 냅니다. 사람이든 LLM이든 먼저 dry-run으로 결과를 확인하고 그 결과가 의도와 맞을 때만 진짜 실행으로 넘어가는 습관을 도구가 자연스럽게 유도합니다. 테스트가 필요하면 나와의 채팅으로 보내는 전용 플래그를 써서 남에게 영향을 주지 않고 확인할 수도 있습니다.
속도 제한과 무인 모드
무인 모드에서 연속으로 전송할 때는 최소 실행 간격이 걸립니다. 사람이 손으로 메시지를 치는 것보다 빠르게 쏟아지는 트래픽은 그 자체로 비정상 신호이기 때문입니다. hook과 webhook에도 각각 최소 간격이 있어 이벤트가 몰려도 후속 동작이 폭주하지 않습니다.
이 값들은 설정 파일에서 조정할 수 있게 열어 뒀지만 기본값이 이미 보수적입니다. 무인 자동화를 완전히 막지는 않되 아무 설정 없이 돌렸을 때 상대 서버가 부담을 느끼지 않을 속도를 기본으로 잡았습니다. 안전장치를 완화하는 것은 사용자의 명시적 선택이어야 한다는 원칙을 여기서도 지켰습니다.
도구가 오남용을 부추기지 않게
기술적 안전장치만큼 중요했던 것은 문서와 태도였습니다. 프로젝트는 첫 화면에서부터 비공식 도구임을 경고하고 카카오 약관과 정책은 사용자가 직접 확인하도록 안내합니다. AI 에이전트를 위한 가이드에서도 안전 명령과 위험 명령을 분명히 나누고 "먼저 읽고, dry-run으로 미리보고, 사용자 확인 뒤에만 실행한다"는 흐름을 권장 순서로 못 박았습니다.
이 도구의 안전은 한 가지 장치가 아니라 겹겹의 기본값입니다. 쓰기는 잠겨 있고, 켜도 미리보기가 있고, 실행에는 속도 제한이 붙고, 문서는 오남용을 권하지 않습니다. 개인 운영 편의와 아카이빙이라는 정당한 필요만 남기고 위험한 여지를 기본값에서 지운 결과입니다. 이 도구가 왜 이렇게 설계됐는지 전체 맥락은 카카오톡 자동화 CLI 오픈소스 사례에서 볼 수 있고 서버를 아예 건드리지 않는 가장 안전한 읽기 경로는 로컬 DB 읽기에서 이어집니다.
자주 묻는 질문
쓰기를 기본으로 잠그면 불편하지 않나요?
한 번만 설정하면 되는 마찰이라 실사용에서는 부담이 크지 않습니다. 대신 이 작은 마찰이 복사해 온 스크립트나 잘못 조합한 명령이 실수로 메시지를 보내는 사고를 구조적으로 막아 줍니다. 편의를 조금 내주고 가장 흔한 사고 유형을 없애는 거래라고 보면 됩니다.
dry-run은 무엇을 보여 주나요?
실제로 서버에 요청을 보내지 않고 어떤 작업을 어느 방에 어떤 내용으로 실행할지를 구조화해 보여 줍니다. --json과 함께 쓰면 사람이 눈으로 확인하는 미리보기가 그대로 스크립트나 에이전트가 읽는 형식이 됩니다. 실행 전에 의도와 결과를 맞춰 보는 안전 단계입니다.
속도 제한은 왜 필요한가요?
사람이 손으로 치는 것보다 빠른 연속 전송은 그 자체로 비정상 신호로 읽혀 계정 제재로 이어질 수 있습니다. 무인 전송과 hook·webhook에 최소 실행 간격을 걸어 두면 이벤트가 몰려도 후속 동작이 폭주하지 않아 상대 서버에 부담을 주지 않습니다. 기본값이 이미 보수적이라 별도 설정 없이도 안전한 속도로 동작합니다.