Himalaya: 터미널에서 이메일을 관리하는 CLI 도구

Himalaya: 터미널에서 이메일을 관리하는 CLI 도구

터미널에서 작업하다가 이메일 하나 확인하려고 브라우저를 여는 게 은근 번거롭지 않나요? 코드 리뷰 알림이 왔는지 확인하려고 Gmail 탭을 열었다가 어느새 유튜브까지 넘어가 있는 자신을 발견하곤 합니다. 😅

Himalaya는 이런 상황에 딱 맞는 CLI 이메일 클라이언트예요. IMAP과 SMTP를 지원하기 때문에 터미널을 떠나지 않고도 이메일을 읽고, 보내고, 정리할 수 있습니다. Rust로 만들어져서 빠른 건 물론이고 TUI가 아닌 CLI라 다른 도구와 엮어 쓰기에도 좋아요.

이번 글에서는 설치부터 실제로 이메일을 주고받는 데까지 쭉 다뤄보겠습니다.

Himalaya란?

Himalaya는 Pimalaya 프로젝트에서 개발 중인 오픈소스 CLI 이메일 클라이언트입니다. GitHub 별이 5,000개가 넘고 NLnet 재단과 유럽 위원회의 NGI 프로그램 지원까지 받고 있어서 프로젝트 지속성 면에서도 믿을 만해요.

터미널 이메일 클라이언트라고 하면 Mutt나 NeoMutt를 떠올리기 쉬운데, 이 도구들은 TUI(Terminal User Interface) 방식입니다. 터미널 화면 전체를 차지하고 그 안에서 키보드로 조작하는 형태죠. Himalaya는 이와 달리 의도적으로 CLI를 택했습니다.

# TUI는 이런 식으로 터미널을 점유하지만
mutt

# Himalaya는 일반 커맨드처럼 실행하고 바로 결과를 받습니다
himalaya envelope list

이 차이가 생각보다 큽니다. CLI니까 셸 스크립트에 넣을 수 있고 jq로 JSON 출력을 파이프할 수도 있고 cron에 물려서 자동화하는 것도 가능하거든요. 이메일 처리를 스크립팅하고 싶은 분이라면 눈여겨볼 만합니다.

설치

여러 패키지 매니저를 지원해서 설치가 어렵지 않습니다.

macOS라면 Homebrew가 가장 편합니다.

brew install himalaya

Rust 개발 환경이 갖춰져 있다면 Cargo로도 됩니다.

cargo install himalaya --locked

Linux(Arch)에서는 pacman을 쓰면 되고요.

pacman -S himalaya

Windows에서는 Scoop을 쓰면 됩니다.

scoop install himalaya

Nix나 Fedora COPR 같은 다른 패키지 매니저도 지원하고, 공식 설치 스크립트로 미리 빌드된 바이너리를 바로 받을 수도 있어요.

curl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | sh

설치가 끝나면 버전을 확인해볼까요?

himalaya --version

계정 설정

설치 후 himalaya를 처음 실행하면 설정 파일이 없다는 걸 감지하고 마법사를 띄울지 물어봅니다.

 himalaya
Cannot find configuration at ~/.config/himalaya/config.toml.
> Would you like to create one with the wizard? Yes

Yes를 선택하면 대화형 마법사가 이메일 주소, IMAP/SMTP 서버, 인증 방식 등을 하나씩 물어보면서 설정을 잡아줍니다. Gmail 계정을 연결하는 경우를 예로 들면 이런 흐름이에요.

Configuring your default account

> Email address: me@gmail.com
> Account name: gmail
> Full display name: 홍길동
> Downloads directory: ~/Downloads
> Default backend: IMAP
> IMAP hostname: imap.gmail.com
> IMAP encryption: SSL/TLS
> IMAP port: 993
> IMAP login: me@gmail.com
> IMAP authentication strategy: Use a shell command to retrieve my password (recommended)
> Shell command: security find-generic-password -a 'gmail' -s 'himalaya-gmail-imap' -w
> Backend for sending messages: SMTP
> SMTP hostname: smtp.gmail.com
> SMTP encryption: SSL/TLS
> SMTP port: 465
> SMTP login: me@gmail.com
> SMTP authentication strategy: Use a shell command to retrieve my password (recommended)
> Shell command: security find-generic-password -a 'gmail' -s 'himalaya-gmail-smtp' -w
> Where to save the configuration? ~/.config/himalaya/config.toml

이메일 주소를 입력하면 Gmail, Outlook 같은 주요 서비스의 IMAP/SMTP 설정값을 자동으로 채워주니까 직접 호스트명이나 포트 번호를 외울 필요가 없어요. 인증 방식도 앱 비밀번호를 직접 입력하는 것부터 셸 명령어로 키체인에서 가져오는 것까지 선택할 수 있습니다.

나중에 계정을 추가하거나 설정을 다시 하고 싶으면 himalaya account configure로 마법사를 언제든 다시 띄울 수 있습니다.

Gmail 앱 비밀번호

Gmail은 보안 정책상 계정 비밀번호로 직접 IMAP/SMTP에 로그인할 수 없습니다. 대신 앱 비밀번호(App Password)를 생성해서 써야 해요.

Google 앱 비밀번호 페이지에 접속해서 앱 이름(예: himalaya)을 입력하고 만들기를 누르면 16자리 비밀번호가 나옵니다. 이 비밀번호는 한번 닫으면 다시 볼 수 없으니 바로 저장해야 해요.

앱 비밀번호를 만들려면 Google 계정에 2단계 인증이 켜져 있어야 합니다.

앱 비밀번호를 만들었으면 안전한 곳에 저장해야 합니다. macOS에서는 키체인에 넣어두는 게 가장 편해요. security 명령어로 IMAP용과 SMTP용을 각각 등록합니다.

# IMAP 비밀번호 등록 (입력 후 동일한 비밀번호를 한 번 더 입력)
security add-generic-password -a 'gmail' -s 'himalaya-gmail-imap' -w

# SMTP 비밀번호 등록
security add-generic-password -a 'gmail' -s 'himalaya-gmail-smtp' -w

비밀번호를 두 번 입력하라고 하는데, 앱 비밀번호의 공백을 빼고 16자리를 그대로 붙여넣으면 됩니다. IMAP과 SMTP에 같은 앱 비밀번호를 쓰면 되니까 두 곳에 같은 값을 넣어주세요.

Linux에서는 passsecret-tool 같은 도구로 저장하고, 마법사에서 셸 명령어를 그에 맞게 지정하면 됩니다.

# pass에 비밀번호 저장
pass insert email/himalaya-gmail

# 마법사에서 셸 명령어를 이렇게 지정
# > Shell command: pass show email/himalaya-gmail

등록이 끝나면 바로 테스트해볼 수 있습니다.

 himalaya envelope list

이메일 목록이 쭉 나오면 인증 설정이 제대로 된 거예요.

수동 설정

마법사 대신 설정 파일을 직접 작성하는 것도 가능합니다. ~/.config/himalaya/config.toml에 TOML 형식으로 만들면 돼요.

Gmail을 앱 비밀번호로 연결하는 예시입니다.

~/.config/himalaya/config.toml
[accounts.gmail]
email = "me@gmail.com"
display-name = "홍길동"

folder.aliases.inbox = "INBOX"
folder.aliases.sent = "[Gmail]/Sent Mail"
folder.aliases.drafts = "[Gmail]/Drafts"
folder.aliases.trash = "[Gmail]/Trash"

backend.type = "imap"
backend.host = "imap.gmail.com"
backend.port = 993
backend.login = "me@gmail.com"
backend.auth.type = "password"
backend.auth.raw = "앱 비밀번호를 여기에"

message.send.backend.type = "smtp"
message.send.backend.host = "smtp.gmail.com"
message.send.backend.port = 465
message.send.backend.login = "me@gmail.com"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "앱 비밀번호를 여기에"

비밀번호를 평문으로 남기기 싫다면 auth.raw 대신 auth.cmd를 써서 외부 명령어로 가져오게 할 수도 있습니다.

backend.auth.type = "password"
backend.auth.cmd = "pass show email/himalaya-gmail"

Outlook이라면 IMAP 호스트를 outlook.office365.com으로, SMTP 호스트를 smtp-mail.outlook.com으로 바꾸면 됩니다.

Proton Mail은 좀 특이한데 Proton Bridge라는 앱을 로컬에 띄워놓고 거기에 IMAP/SMTP로 접속하는 구조예요.

Proton Mail 설정 예시
[accounts.proton]
email = "me@proton.me"

backend.type = "imap"
backend.host = "127.0.0.1"
backend.port = 1143
backend.encryption = false
backend.login = "me@proton.me"
backend.auth.type = "password"
backend.auth.raw = "Bridge에서 생성된 비밀번호"

message.send.backend.type = "smtp"
message.send.backend.host = "127.0.0.1"
message.send.backend.port = 1025
message.send.backend.encryption = false
message.send.backend.login = "me@proton.me"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "Bridge에서 생성된 비밀번호"

여러 계정 관리

개인 메일과 회사 메일을 따로 쓰는 분이 많을 텐데, Himalaya는 하나의 설정 파일에서 여러 계정을 관리할 수 있습니다.

~/.config/himalaya/config.toml
[accounts.gmail]
email = "me@gmail.com"
backend.type = "imap"
backend.host = "imap.gmail.com"
# ... 나머지 Gmail 설정

[accounts.work]
email = "me@company.com"
backend.type = "imap"
backend.host = "mail.company.com"
# ... 나머지 회사 메일 설정

등록된 계정 목록을 보려면 이렇게 합니다.

himalaya account list

특정 계정의 메일을 볼 때는 --account 옵션을 붙이면 돼요.

himalaya envelope list --account work

--account 없이 실행하면 설정 파일에서 맨 위에 있는 계정이 기본으로 쓰입니다.

이메일 목록 조회

계정 설정을 마쳤으면 이제 메일함을 열어봅시다. 받은편지함 이메일 목록은 envelope list로 볼 수 있습니다.

himalaya envelope list

임시보관함이나 보낸편지함 같은 특정 폴더를 보려면 --folder를 붙이면 돼요.

himalaya envelope list --folder Drafts

메일이 많으면 페이지를 넘겨가며 볼 수도 있습니다.

himalaya envelope list --page 3

JSON으로 뽑아내면 다른 도구랑 조합하기 좋습니다.

himalaya envelope list --output json | jq '.[].subject'

jq와 파이프로 연결하면 이메일 제목만 깔끔하게 뽑아낼 수 있죠.

이메일 읽기

목록에서 이메일 ID를 확인했다면 내용을 읽어봅시다.

himalaya message read <id>

텍스트 형식으로 출력되는데 HTML 이메일도 텍스트로 변환해서 보여주니까 터미널에서 읽는 데 별 지장은 없습니다.

이메일 작성과 전송

새 이메일을 작성하려면 message write 명령어를 사용합니다.

himalaya message write

실행하면 $EDITOR 환경변수에 지정된 편집기(vim, neovim, nano 등)가 뜹니다. 여기서 MML(MIME Meta Language) 형식으로 이메일을 작성하는데 일반 텍스트랑 거의 같아서 어렵지 않아요.

From: me@gmail.com
To: friend@example.com
Subject: 터미널에서 보내는 편지

안녕하세요!
Himalaya로 터미널에서 이메일을 보내고 있어요.

편집기를 저장하고 닫으면 이메일이 전송됩니다.

답장은 message reply, 전달은 message forward를 쓰면 돼요.

himalaya message reply <id>
himalaya message forward <id>

파일을 첨부하고 싶다면 MML 형식 안에서 첨부 파일을 지정할 수 있습니다.

From: me@gmail.com
To: friend@example.com
Subject: 보고서 첨부합니다

보고서 파일을 첨부했습니다.
확인 부탁드려요.

<#part filename="report.pdf">

폴더 관리

폴더 관련 작업도 직관적입니다.

# 폴더 목록 보기
himalaya folder list

# 새 폴더 만들기
himalaya folder create "프로젝트/2026"

# 폴더 삭제
himalaya folder delete "프로젝트/2026"

플래그 관리

읽음/안읽음 처리나 중요 표시 같은 플래그 조작도 됩니다.

# 읽음 표시
himalaya flag add <id> seen

# 중요 표시
himalaya flag add <id> flagged

# 안읽음으로 되돌리기
himalaya flag remove <id> seen

셸 스크립트와의 조합

CLI 도구의 진짜 힘은 다른 도구와 엮을 때 나옵니다.

안 읽은 메일 개수를 셸에서 확인하고 싶다면 이런 스크립트를 만들 수 있어요.

unread.sh
#!/bin/bash
count=$(himalaya envelope list --output json | jq '[.[] | select(.flags | contains(["Seen"]) | not)] | length')
echo "📬 안 읽은 메일: ${count}통"

tmux 상태 바나 Starship 프롬프트에 이 출력을 넣어두면 브라우저를 열지 않고도 안 읽은 메일이 있는지 바로 알 수 있습니다.

특정 사람한테서 메일이 오면 데스크톱 알림을 띄우는 것도 해볼 만하죠.

notify.sh
#!/bin/bash
himalaya envelope list --output json \
  | jq -r '.[] | select(.from | test("boss@company.com")) | .subject' \
  | while read -r subject; do
      notify-send "팀장님 메일" "$subject"
    done

cron에 등록해두면 주기적으로 돌릴 수 있으니 메일 확인 자동화가 완성됩니다.

PGP 암호화

민감한 내용을 주고받을 때 PGP 암호화가 필요할 수 있는데 Himalaya도 이를 지원합니다.

# GPG 바인딩 사용
[accounts.secure]
pgp.type = "gpg"

# 셸 명령어를 통한 GPG 사용
[accounts.secure]
pgp.type = "commands"
pgp.encrypt.cmd = "gpg --encrypt --armor --recipient <recipient>"
pgp.decrypt.cmd = "gpg --decrypt"

OpenPGP의 네이티브 Rust 구현체를 쓰는 옵션도 있어서 시스템에 GPG가 깔려 있지 않아도 괜찮습니다.

IMAP 외의 백엔드

IMAP으로 원격 서버에 접속하는 것만 되는 게 아닙니다. 로컬에 저장된 메일을 다루는 Maildir이나 Notmuch 백엔드도 쓸 수 있어요.

# Maildir 백엔드
[accounts.local]
email = "me@localhost"
backend.type = "maildir"
backend.root-dir = "/home/me/Mail"

# Notmuch 백엔드
[accounts.search]
email = "me@localhost"
backend.type = "notmuch"
backend.db-path = "/home/me/Mail"

Maildir를 쓰면 오프라인에서도 메일을 다룰 수 있고 Notmuch를 쓰면 전문 검색이 강력합니다. mbsyncofflineimap으로 메일을 미리 동기화해놓고 Himalaya로 로컬에서 읽는 조합도 잘 맞아요.

디버깅

메일 서버 연결이 안 될 때는 환경변수로 로그 레벨을 높여서 원인을 추적할 수 있습니다.

RUST_LOG=debug himalaya envelope list

뭐가 문제인지 더 파고 싶다면 백트레이스까지 켜봅시다.

RUST_LOG=trace RUST_BACKTRACE=full himalaya envelope list

마치며

터미널에서 벗어나지 않고 이메일을 처리하고 싶다면 Himalaya가 좋은 선택입니다. CLI답게 jq나 셸 스크립트, cron 같은 도구와 잘 어울리고, 이메일 관련 작업을 자동화하는 데 딱이에요.

IMAP뿐 아니라 Maildir과 Notmuch까지 지원하고, PGP 암호화와 OAuth 2.0까지 갖추고 있어서 웬만한 상황에는 다 대응할 수 있습니다.

GUI만큼 화려하진 않지만 tmuxZellij 같은 터미널 멀티플렉서 옆 패널에 띄워놓고 쓰면 꽤 쾌적합니다. 코딩하다가 옆 패널에서 메일 한번 확인하고 다시 코드로 돌아오는 흐름이 은근 중독성 있거든요.

더 자세한 내용은 공식 GitHub 저장소에서 확인해보세요.

This work is licensed under CC BY 4.0 CC BY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord