홈시리즈멘토링

© 2026 정기창. All rights reserved.

본 블로그의 콘텐츠는 CC BY-NC-SA 4.0 라이선스를 따릅니다.

☕후원하기소개JSON Formatter러닝 대기질개인정보처리방침이용약관

© 2026 정기창. All rights reserved.

콘텐츠: CC BY-NC-SA 4.0

☕후원하기
소개|JSON Formatter|러닝 대기질|개인정보처리방침|이용약관

Claude Code에 Gmail MCP 붙여 받은편지함 대청소 시킨 기록

정기창·2026년 6월 22일

받은편지함을 열 때마다 마음 한구석이 무거웠습니다. 안 읽은 메일이 만 단위로 쌓여 있었고, 그 대부분은 한 번도 열어보지 않을 광고와 알림이었습니다. 언젠가 날 잡아 정리해야지 하면서도, 수천 통을 일일이 골라낼 엄두가 나지 않아 몇 년을 미뤄둔 일이었습니다. 그러던 차에, 마침 옆에 켜둔 Claude Code 세션에 메일을 다룰 손을 쥐여주면 이 청소를 대신 시킬 수 있지 않을까 하는 생각이 들었습니다. 이 글은 그 시도의 기록입니다. 다만 정작 값진 교훈은 "메일을 어떻게 붙였는가"가 아니라, 되돌릴 수 없는 부작용이 있는 대량 작업을 AI에게 맡길 때 무엇이 어긋나는가에 있었습니다.

AI에게 메일을 다룰 손을 쥐여주기 — Gmail MCP 연동

MCP(Model Context Protocol)는 AI 에이전트에 외부 도구를 붙이는 표준입니다. 평소 Claude Code는 코드와 파일만 다루지만, 여기에 메일 도구를 하나 물리면 "안 읽은 메일 찾아줘", "이 발신자가 보낸 거 정리해줘" 같은 말을 자연어로 시킬 수 있게 됩니다. 제가 쓴 것은 오픈소스로 공개된 Gmail MCP 서버였습니다.

그런데 막상 붙이려고 보니, 흔히 상상하는 "버튼 한 번 눌러 연결" 과는 거리가 멀었습니다. 인증부터가 그랬습니다.

API 키로는 안 됩니다 — 메일은 개인 데이터라 OAuth가 필요합니다

처음엔 으레 그렇듯 API 키 하나면 되겠거니 했습니다. 그런데 메일은 사정이 달랐습니다. API 키는 공개 데이터를 가져올 때 쓰는 출입증이고, 받은편지함은 철저히 개인 사용자의 데이터입니다. 내 동의 없이는 그 누구도 들여다봐선 안 되는 영역이라, "이 앱이 당신 메일에 접근해도 됩니까"를 사용자 본인이 직접 허락하는 OAuth 2.0 절차를 거쳐야 했습니다.

더 의외였던 건, 그 OAuth를 쓰려면 내 OAuth 클라이언트를 직접 발급해야 한다는 점이었습니다. 흔히 BYOC(Bring Your Own Credentials), 자기 자격증명을 직접 들고 오는 방식입니다. 절차를 추려보면 이렇습니다.

# OAuth 클라이언트 발급 절차
1. 클라우드 콘솔에서 프로젝트 선택 (또는 새로 생성)
2. 메일 API 활성화
3. OAuth 동의 화면 구성 → 테스트 사용자에 본인 계정 추가
4. OAuth 클라이언트 ID 생성 (앱 유형: 데스크톱 앱)
5. JSON 키 다운로드
6. 정해진 로컬 경로(홈 디렉토리 아래 점 폴더)에 배치

처음엔 단계가 많아 번거롭게 느껴졌지만, 한 번 해두면 그뿐이었습니다. 그리고 이 과정에서 알게 된 작은 사실 몇 가지가, 같은 길을 걸으실 분께는 시간을 아껴줄 듯하여 남겨둡니다.

이미 만들어 둔 프로젝트가 있다면 재활용할 수 있습니다

저는 예전에 다른 용도, 이를테면 영상 플랫폼 업로드 자동화 같은 일로 만들어 둔 클라우드 프로젝트가 이미 있었습니다. 새 프로젝트를 또 팔 필요 없이, 기존 프로젝트에 메일 API만 추가로 켜면 그만이었습니다.

다만 여기서 한참을 헤맨 함정이 하나 있었습니다. 분명 내가 만든 프로젝트인데 목록에서 안 보이는 것 같아 당황했는데, 알고 보니 프로젝트를 가리키는 값이 두 종류였습니다.

구분 형태 어디서 보이나
프로젝트 번호 숫자 다운로드한 키 파일 이름
프로젝트 ID 문자열 콘솔 화면

콘솔 화면은 문자열로 된 ID를 보여주는데, 키 파일 이름에는 숫자로 된 번호가 박혀 있다 보니, 같은 프로젝트를 다른 것으로 착각하기 딱 좋았습니다. 둘은 같은 프로젝트를 부르는 서로 다른 이름일 뿐이라는 걸 알고 나서야 마음이 놓였습니다.

한 가지 걱정이 더 있었습니다. 기존 클라이언트를 재활용하면, 그걸로 돌아가던 다른 자동화가 깨지지 않을까 하는 것이었습니다. 다행히 그럴 일은 없었습니다. 클라이언트는 앱의 신분증이고, 토큰은 동의의 결과인데, 토큰은 도구마다 따로 저장되기 때문입니다. 신분증 하나를 여러 앱이 공유해도, 각자 받아둔 동의는 별개로 보관되니 서로를 건드리지 않았습니다.

인증 실행, 그리고 가장 헷갈렸던 함정

키 파일을 자리에 놓은 뒤, 서버가 제공하는 인증 명령을 한 번 실행하니 브라우저가 떠올랐습니다. 거기서 OAuth 동의를 누르자 토큰이 로컬에 전역으로 저장되었고, 그것으로 인증 자체는 끝이었습니다.

저는 평소 작업 세션에 메일 도구가 늘 붙어 있는 걸 원치 않았습니다. 코드를 짜다가 실수로 메일을 건드리는 일도 피하고 싶었고, 무엇보다 메일을 만질 때만 그 도구가 있는 편이 집중에도 나았습니다. 그래서 메일 MCP만 켠 설정 프로파일(JSON)을 따로 만들고, 셸 alias 하나에 묶어두었습니다. 가령 cc-gmail 이라는 alias로 세션을 열면 그때만 메일 도구가 붙고, 평소 세션엔 얼씬도 하지 않게 한 것입니다. 보안과 집중을 한꺼번에 챙기는 작은 장치였습니다.

그런데 여기서 가장 헷갈리는 함정을 만났습니다. 인증을 분명히 마쳤는데도 도구가 하나도 안 보이는 것이었습니다. 인증이 잘못됐나 싶어 키 파일을 몇 번이나 다시 확인했지만, 원인은 엉뚱한 데 있었습니다.

MCP 서버는 세션이 시작되는 그 순간에 딱 한 번 로드됩니다. 인증 파일이 없는 상태로 세션을 먼저 열어버리면, 서버가 부팅에 실패해 도구가 0개로 붙습니다.

즉 인증을 마친 뒤에 도구가 안 보인다면, 인증이 틀린 게 아니라 그저 세션을 새로 열면 되는 것이었습니다. 이걸 모르고 인증 설정만 붙들고 있던 시간이 아까웠습니다. 셋업에서 막히신다면 이 한 가지를 가장 먼저 의심해보시길 권합니다.

받은편지함 대청소 — 가장 오래된 메일부터

손이 붙었으니 이제 본 작업입니다. 목표는 단순했습니다. 가장 오래된 메일부터 거슬러 올라가며 정리하기. 케케묵은 것부터 걷어내고 싶었습니다. 그런데 이 단순한 목표가 첫 함정이었습니다.

"가장 오래된 메일"을 곧장 집을 수 없었습니다

메일 검색은 늘 최신순으로만 결과를 돌려줍니다. 역방향 정렬도, 맨 끝 페이지로 건너뛰는 기능도 없었습니다. 그러니 "가장 오래된 메일을 보여줘"라고 한들 곧장 집어낼 방법이 없었습니다. 페이지를 처음부터 끝까지 넘겨갈 수도 있지만, 수천 통을 그렇게 넘기는 건 현실적이지 않았습니다.

그래서 날짜로 경계를 좁혀나가는 방식을 택했습니다. before:연도 형태로 "이 연도 이전 메일"을 물어보면서, 마치 사전을 펼치듯 범위를 반씩 좁히는 이진탐색을 한 것입니다.

# 가장 오래된 메일의 경계를 좁히는 이진탐색
before:2015 → 결과 있음  (더 과거로)
before:2010 → 결과 있음  (더 과거로)
before:2008 → 결과 없음  (이 사이 어딘가)
before:2009 → 결과 있음  → 계정 개설 시점 부근 확인

이렇게 계정이 처음 열리던 시점까지 거슬러 올라가, 가장 오래된 메일의 경계를 찾아냈습니다. 검색이 최신순밖에 모른다는 제약을, 날짜라는 다른 축으로 우회한 셈입니다.

발신자별로 묶어 세 갈래로 나눴습니다

오래된 것부터 훑되, 메일을 한 통 한 통 판단하는 대신 발신자별로 묶어 성격을 가렸습니다. 같은 곳에서 온 메일은 대개 운명이 같았기 때문입니다. 크게 세 갈래였습니다.

분류 대상 처리
정리 대상 광고·마케팅 뉴스레터, 비즈니스 SNS 알림, 이미 종료된 서비스의 알림 휴지통으로
검토 필요 영수증·결제 명세, 은행 거래내역 알림, 계정·보안 알림 손대지 않고 보류
보존 실제 사람·업무 메일, 가입 환영 메일 그대로 유지

검토 필요로 분류한 것들은 지우면 곤란한 기록이었습니다. 결제 명세나 은행 거래내역 알림은 나중에 무언가를 증빙해야 할 때 필요할 수 있어, 아예 손대지 않기로 했습니다. 보존 칸에 가입 환영 메일을 둔 건 조금 사적인 이유였는데, 어떤 계정이 언제 태어났는지를 알려주는 기록이라 일종의 추억처럼 느껴졌기 때문입니다.

지우는 기본값은 영구삭제가 아니라 휴지통이었습니다

여기서 가장 신경 쓴 결정이 있습니다. 정리 대상을 완전삭제(영구)가 아니라 휴지통 이동으로 처리한 것입니다. 휴지통에 들어간 메일은 30일 안에는 되살릴 수 있습니다. 다시 말해, AI가 잘못 골라 엉뚱한 걸 집어넣더라도 되돌릴 수 있는 안전한 기본값이라는 뜻입니다. 영구삭제는 한 번 누르면 끝이라, 그 마지막 한 걸음만큼은 사람인 제가 직접 하기로 남겨두었습니다.

수십에서 수백 통을 한 통씩 옮기는 건 비효율적이라, 라벨을 한꺼번에 바꾸는 방식으로 처리했습니다. 메일이 받은편지함에 있다는 것도, 휴지통에 있다는 것도 결국 라벨 하나로 표현되기에, 받은편지함 라벨을 떼고 휴지통 라벨을 붙이는 배치 작업 한 번으로 무더기를 옮길 수 있었습니다.

AI에게 대량 작업을 맡길 때, 무엇이 어긋났는가

여기까지는 비교적 매끄러웠습니다. 그런데 정작 이 글에서 가장 하고 싶은 이야기는 지금부터입니다. 돌이켜 생각해보면, 이 작업에서 진짜 값진 것은 메일을 붙이는 셋업이 아니라 "부작용 있는 대량 작업을 AI에게 맡기니 무엇이 어긋나더라"는 경험이었습니다. 직관이 몇 번이나 배신당했고, 그 지점들이 결국 이 청소를 신뢰할 만하게 만든 안전장치가 되었습니다.

하위 에이전트에 다 욱여넣자 컨텍스트가 터졌습니다

처음엔 받은편지함 전체 분석을 하위 에이전트 하나에게 통째로 맡겼습니다. "받은편지함을 다 훑어서 발신자별로 정리해줘" 하면 알아서 해주리라 기대한 것입니다. 그런데 수백 통의 메타데이터가 차곡차곡 쌓이면서, 어느 순간 컨텍스트 한계를 넘어 prompt too long 에러로 작업이 멈춰버렸습니다.

당연한 일이었습니다. 한 에이전트가 들고 있을 수 있는 정보의 양에는 한계가 있는데, 거기에 전수를 다 부어버렸으니 넘칠 수밖에 없었습니다. 여기서 배운 것은 분명했습니다. 대량 수집은 한 곳에 다 몰아넣지 말고 범위를 쪼개거나, 집계는 결정적인 스크립트로 빼라는 것입니다. 세는 일, 묶는 일처럼 정답이 정해진 작업은 코드가 훨씬 잘하고, 무엇보다 컨텍스트를 잡아먹지 않습니다.

AI가 만든 중간 산출물을 진실로 믿으면 안 됩니다

이게 가장 뼈아픈 교훈이었습니다. AI에게 "발신자별 메일 ID 목록"을 JSON으로 만들게 했고, 저는 그 목록을 그대로 믿고 삭제로 넘기려 했습니다. 그런데 그 목록을 자세히 들여다보니 곳곳에 구멍이 있었습니다.

  • 실제로는 존재하지 않는 손상된 ID가 섞여 있었습니다.
  • 전수를 다 본 게 아니라 일부만 분석한 결과였습니다.
  • 서로 다른 그룹에 같은 ID가 중복으로 들어가 있었습니다.

만약 이 목록을 진실로 삼아 삭제 버튼을 눌렀다면, 엉뚱한 걸 지우거나 정작 지워야 할 건 그대로 남는 사고가 났을 겁니다. 여기서 깨달은 것은 진짜 진실은 AI가 만든 목록이 아니라 라이브 쿼리, 즉 실시간 검색 결과라는 점이었습니다. 지금 이 발신자가 보낸 메일이 무엇인지는 검색창에 다시 물어보면 정확히 나옵니다. AI가 만든 목록은 어디까지나 작업을 돕는 보조 메모일 뿐, 삭제의 근거(ground truth)로 삼아선 안 되는 것이었습니다.

"이 발신자는 광고니까 전부"가 사고를 부릅니다

가장 위험한 유혹은 "이 발신자에서 온 건 광고니까 통째로 지우자"였습니다. 빠르고 시원하지만, 바로 이 생각이 사고를 부릅니다. 한 발신 도메인 안에 성격이 전혀 다른 메일이 함께 살고 있었기 때문입니다.

예를 들어 전 직장 도메인 안에는 마케팅 뉴스레터만 있는 게 아니라, 제 업무 계정에서 받은 백업 메일과 인사 관련 안내가 같이 섞여 있었습니다. 어느 구직 플랫폼 도메인 안에는 추천 광고와 더불어, 제가 실제로 지원했던 활동 기록이 함께 들어 있었습니다. 도메인만 보고 통째로 밀어버렸다면 지우면 안 될 것까지 휩쓸렸을 겁니다.

그래서 삭제의 기준을 "발신 도메인"이 아니라 "마케팅 전용 발신 주소"로 좁혔습니다. 답장이 오갈 일 없는 noreply 류의 주소처럼, 명백히 일방적 발송만 하는 자리를 골라 그것만 정리한 것입니다. 같은 회사에서 와도 사람이 보낸 메일과 기계가 보낸 광고는 발신 주소가 달랐고, 그 차이가 안전한 칼금이 되어주었습니다.

되돌릴 수 있게 만드는 네 가지 안전장치

이런 실패들을 거치며, 결국 이 청소를 믿고 맡길 수 있게 해준 안전장치는 네 가지였습니다. 화려한 것은 하나도 없고, 모두 "잘못돼도 되돌릴 수 있게" 또는 "잘못됐는지 확인할 수 있게" 만드는 장치였습니다.

  1. 휴지통을 기본값으로. 정리는 전부 휴지통 이동으로 했습니다. 영구삭제라는 마지막 한 걸음은 사람의 몫으로 남겼습니다.
  2. 유지대상 역검증. 작업이 끝난 뒤, 지우면 안 되는 발신자(은행·결제 등)가 혹시 휴지통에 잘못 들어가지 않았는지 거꾸로 검색해 확인했습니다.
  3. 보존대상 명시 제외. 가입 환영 메일처럼 남겨둘 것은 삭제 목록에서 아예 빼고 시작했습니다.
  4. 처리 후 검증. 정리 대상 발신자가 실제로 받은편지함에서 줄었는지, 유지대상은 그대로인지를 다시 검색해 눈으로 맞춰봤습니다.

눈에 띄는 공통점이 있습니다. 안전장치의 절반은 실시간 검색으로 결과를 다시 확인하는 일이라는 점입니다. 앞서 AI가 만든 목록을 믿지 않기로 한 결정이, 여기 검증 단계에서도 그대로 이어졌습니다. 작업 전에도 검색을 진실로 삼고, 작업 후에도 검색으로 결과를 맞춰본 것입니다.

AI 자동화의 핵심은 똑똑함이 아니라 되돌릴 수 있는 설계

이 청소를 끝내고 든 생각을 한 문장으로 줄이면 이렇습니다. AI에게 부작용 있는 일을 맡길 때 중요한 것은, AI가 얼마나 똑똑한가가 아니라 그 작업을 얼마나 되돌릴 수 있게 설계했는가라는 것입니다.

AI는 분명 수천 통을 빠르게 분류해주었지만, 그 과정에서 손상된 ID를 끼워 넣었고, 일부만 보고 전부라 했으며, 도메인 하나를 통째로 지우려 들었습니다. 똑똑함만 믿었다면 사고가 났을 겁니다. 그걸 막아준 것은 더 영리한 프롬프트가 아니라, 휴지통이라는 복구 가능한 기본값과, 실시간 검색으로 다시 맞춰보는 검증, 그리고 "도메인 전부" 대신 "마케팅 주소만"으로 범위를 좁힌 절제였습니다.

그러니 AI에게 메일 정리처럼 실제 부작용이 있는 일을 맡겨보려 하신다면, 먼저 물어보시길 권합니다. 이 작업이 잘못됐을 때, 나는 되돌릴 수 있는가. 그 답을 "예"로 만들어두는 일, 즉 휴지통과 검증과 범위 좁히기를 갖추는 일이야말로 AI에게 손을 쥐여주기 전에 마쳐야 할 준비였습니다. 받은편지함 청소라는 사소한 일이었지만, 거기서 배운 것은 메일에만 머무는 이야기는 아니었다는 생각이 듭니다.

Gmail MCPClaude CodeMCPOAuthAI 자동화받은편지함 정리

관련 글

Claude Code에 Google Search Console MCP를 추가하고, OAuth 토큰 만료를 해결한 경험

GA4 MCP를 운영하다 OAuth 토큰이 만료되고, GSC MCP를 추가하면서 gcloud CLI 설치 오류까지 겪었습니다. ADC 토큰 갱신부터 Python 호환성 문제까지, 실전에서 마주친 트러블슈팅 과정을 정리했습니다.

관련도 91%

Claude Code에서 블로그 글 작성하기: MCP를 직접 만들어 활용한 경험

Claude Code로 개발하면서 얻은 지식을 블로그에 정리하고 싶었습니다. 하지만 AI에게 블로그 관리자 권한을 모두 주기엔 불안했고, 필요한 API만 분기 처리하기엔 번거로웠습니다. MCP(Model Context Protocol)를 직접 만들어서 권한을 명확히 분리하고, Few-shot 예시와 SEO 가이드라인을 1회 호출로 제공하도록 개선한 경험을 공유합니다.

관련도 91%

Claude Code, 메모리 관점에서 mcp 바라보기

맥북 32GB의 상당량을 평상시에 잡아먹고 있던 원인 중 하나는 모든 MCP를 켜둔 Claude Code 세션이었습니다. 세션별 alias로 필요한 MCP만 활성화하는 방식으로 메모리 압박을 줄여본 기록입니다.

관련도 91%