헤르메스 에이전트(Hermes Agent)와 n8n 조합 개꿀
요약: n8n은 공개 이벤트를 받고 최소 payload만 넘기는 브릿지로 두고, Hermes Agent가 Linear MCP로 이슈 본문과 댓글을 직접 읽어 작업·검증·완료 처리까지 맡게 했다.
왜 n8n 하나로는 부족했나
n8n으로 사내 챗봇도 만들어봤고, 캘린더 비서도 만들어봤다. 트리거 받아서 API 몇 개 호출하고 조건 분기하는 자동화는 n8n이 정말 잘한다.
근데 어느 순간 벽에 부딪혔다. 판단이 필요한 작업, 예를 들어 "이 PR 리뷰 코멘트 보고 실제로 코드 고쳐라", "이 Linear 이슈 보고 관련 파일 찾아서 초안 작성해라" 같은 건 n8n 노드 조합으로는 안 된다. AI Agent 노드를 넣어봐도 결국 프롬프트 하나 던지고 텍스트 응답 받는 수준이지, 파일 시스템을 만지거나 여러 단계를 거쳐 뭔가를 실제로 완성시키는 건 완전히 다른 이야기였다.
그래서 최근에 홈 서버에 올려둔 Hermes Agent를 n8n 뒤에 실행기로 붙이는 구조를 시험해봤는데, 써보니 이 조합 진짜 개꿀이다.
역할 분리: n8n은 얼굴, Hermes는 손발
아이디어 자체는 별거 없다. n8n은 바깥 세상과 접촉하는 레이어, Hermes는 안쪽에서 실제로 일하는 레이어로 나누는 거다.
- n8n (공개/트리거 레이어)
- Linear webhook, GitHub webhook, Slack 메시지, 스케줄 트리거를 받는다.
- 외부 서비스(Notion, Slack, Google 등)와의 인증/연동을 관리한다.
- 들어온 이벤트를 정제해서 "이 작업을 해줘"라는 형태로 다듬는다.
- 결과를 다시 Slack이나 Linear 코멘트로 되돌려주는 것도 n8n 몫이다.
- Hermes Agent (신뢰된 내부 실행기)
- 실제 판단이 필요한 작업, 즉 코드 수정, 파일 탐색, 여러 단계 추론이 필요한 작업을 맡는다.
- 세션 간 메모리를 유지하니까 "저번에 하던 그 작업 이어서 해줘" 같은 것도 가능하다.
- 내부적으로 Claude Code를 오케스트레이션해서 실제 리포지토리를 건드리는 작업(브랜치 생성, 커밋, PR 초안)까지 위임한다.
- 서버 로컬 파일 시스템, 내부 DB, 사내 API에 직접 접근할 수 있는 유일한 레이어다.
결국 n8n이 못 하는 "진짜 일"은 전부 Hermes로 넘기고, n8n은 그 앞단에서 트래픽을 정리하고 결과를 사람이 보는 채널로 되돌리는 배달원 역할만 하는 셈이다.
와 n8n 조합 개꿀/image.png)
왜 이 구조가 안전한가: 프라이빗 네트워크 경계
여기서 제일 신경 쓴 부분은 Hermes를 절대 인터넷에 직접 노출하지 않는다는 거다.
내 서버 구조는 이렇다.
[외부 웹훅/사용자]
│ (HTTPS, 공개)
▼
┌────────┐
│ n8n │ ← 공개 진입점. Cloudflare/Nginx 리버스 프록시 뒤
└───┬────┘
│ (Docker bridge network, 내부 전용)
▼
┌──────────────┐
│ hermes-agent │ ← 외부 포트 없음. n8n 컨테이너에서만 접근 가능
└──────────────┘
│
▼
Claude Code / 로컬 파일시스템 / 내부 DB
중요한 건 세 가지다.
- n8n만 공개 도메인/포트를 가진다. Hermes gateway는 Docker bridge 네트워크 내부 IP로만 열려 있고, 호스트에 포트를 바인딩하지 않는다.
- 맥북에서 관리용으로 붙을 때는 Tailscale을 쓴다. 이건 나만 접근하는 관리 채널이고, n8n → Hermes 트래픽과는 완전히 다른 경로다.
- 인증 경계 자체가 다르다. n8n은 webhook URL + secret 정도로 외부 요청을 받지만, Hermes 쪽 엔드포인트는 n8n 컨테이너의 내부 네트워크 접근 자체가 인증이다. 외부에서 Hermes를 직접 때릴 방법이 물리적으로 없다.
이렇게 나누면 "공개된 표면적"과 "실제로 시스템을 조작할 수 있는 권한"이 분리된다. n8n 웹훅이 뚫려도 공격자가 할 수 있는 건 n8n 워크플로우 안에서 노출한 것뿐이고, Hermes가 가진 파일 시스템/Claude Code 실행 권한까지는 못 건드린다.
실제로 붙여본 예시들
1. Linear 이슈 → 예지 위임 자동 처리
여기가 이번에 제일 많이 갈아엎은 부분이다. 처음엔 n8n이 이슈 본문까지 통째로 읽어서 정리한 다음 Hermes한테 던지는 구조로 짰는데, 쓰다 보니 이건 방향이 틀렸다는 걸 깨달았다. n8n이 이슈 내용을 파싱하고 가공하기 시작하면, 결국 "판단"의 일부를 n8n이 떠안게 된다. 그러면 Hermes를 붙인 의미가 없어진다.
그래서 최종적으로는 n8n을 얇은 공개 브릿지로만 쓰기로 했다.
- n8n은 Linear 이벤트를 받아서, "이슈가 예지(Yeji)한테 새로 할당/위임됐는지"만 필터링한다.
- 본문이나 코멘트 내용은 절대 읽지도, 가공하지도 않는다. 이슈 ID, 팀, 액션 타입 정도만 들어간 최소 payload를 만든다.
- 여기에 요청 ID와 내부 secret을 붙여서 Hermes webhook(
linear-yeji-agent-session)으로 그대로 던진다. - 실제 이슈 본문/코멘트/컨텍스트는 Hermes가 Linear MCP로 직접 가져온다.
get_issue,list_comments로 전체 맥락을 읽고, 어떤 리포지토리 작업인지 매핑한 다음 Claude Code를 오케스트레이션해서 실제로 작업하고, 결과를 검증한 뒤save_comment로 Linear에 코멘트를 남기고save_issue로 상태를 Done으로 바꾼다.
Linear 이벤트
→ n8n: 예지 위임 여부 필터
→ n8n: 최소 payload 생성 (issue id, request id, secret)
→ POST → Hermes webhook (linear-yeji-agent-session)
→ Hermes: Linear MCP로 get_issue / list_comments
→ Hermes: 리포지토리 매핑 → Claude Code 오케스트레이션
→ Hermes: 결과 검증 → save_comment
→ Hermes: save_issue (status: Done)
n8n은 최소한의 이벤트 정보만 정리해서 호출하고 끝이다. 처음엔 중간에 별도 워커 하나를 두고 n8n이 그 워커 상태를 폴링하는 과도기 구조도 써봤는데, 정리하고 보니 n8n → Hermes webhook → Linear MCP로 바로 이어지는 쪽이 훨씬 깔끔했다. 그 워커는 어디까지나 전환기용 런처였고, 이 조합의 핵심은 아니다.
와 n8n 조합 개꿀/image-2.png)
와 n8n 조합 개꿀/image-3.png)
2. GitHub PR 리뷰 코멘트 → 자동 반영
GitHub PR에 리뷰 코멘트가 달리면 n8n이 받아서 Hermes에 넘긴다. Hermes가 Claude Code로 실제 코드를 고치고 커밋 푸시까지 하면, n8n이 PR에 "반영 완료" 코멘트를 남긴다. 물론 이건 신뢰도가 높은 저장소/브랜치에서만, 그리고 항상 PR 형태로 남겨서 최종 머지는 사람이 하도록 걸어뒀다.
3. 배포 알림 + 사후 분석
배포 파이프라인이 실패하면 n8n이 로그를 모아서 Hermes에 "이 로그 보고 원인 추정해줘"라고 요청하고, Hermes가 분석 결과를 정리해서 Slack으로 알림을 보낸다. 이건 판단만 하고 실행은 안 하는 케이스라 권한 경계가 특히 느슨해도 되는 예시다.
4. (초반 삽질) Hermes가 n8n 워크플로우를 직접 짜주면 어떨까 해봤던 실험
이건 최종 구조는 아니고, 중간에 잠깐 곁길로 샜던 실험이다. n8n과 Hermes를 같은 서버에 올려두면, Hermes가 n8n 워크플로우 파일이나 API에 직접 접근해서 워크플로우 자체를 만들어줄 수도 있지 않을까 싶어서 시험해본 적이 있다. 실제로 프롬프트 한 번으로 대충 동작하는 워크플로우가 나오긴 했다.
근데 이건 결국 메인 구조로 채택하지 않았다. Hermes가 n8n 워크플로우 정의까지 손대기 시작하면 경계가 다시 흐려진다 — n8n은 얇은 공개 브릿지로 남아있어야 하는데, 그 브릿지 자체를 내부 실행기가 마음대로 고쳐 쓸 수 있으면 "공개 표면적 = n8n만"이라는 전제가 깨진다. 그래서 최종적으로는 3번(Linear 예지 위임)에서 정리한 것처럼, Hermes는 Linear MCP로 이슈를 읽고 쓰는 것까지만 맡고, n8n 워크플로우 자체는 사람이 관리하는 쪽으로 정리했다. 재미있는 실험이었지만 핵심 얘기는 아니다.
보안 경계에서 신경 쓴 것들
- 쓰기 권한은 항상 브랜치/PR 단위로 제한한다. Hermes가 main에 직접 푸시하는 경로는 아예 만들지 않았다.
- n8n → Hermes 요청에도 내부 전용 토큰을 넣는다. 네트워크가 분리돼 있어도 컨테이너 하나가 뚫렸을 때를 대비한 이중 방어다.
- Hermes가 접근 가능한 리포지토리/디렉토리를 명시적으로 화이트리스트해뒀다. 아무 경로나 건드릴 수 있게 열어두지 않는다.
- 실행 결과는 항상 사람이 보는 채널(Slack, Linear 코멘트)로 되돌아오게 해서, 뭔가 이상하게 돌아가면 바로 눈에 띄게 만들었다.
삽질했던 지점들
- n8n이 이슈 본문을 읽고 가공하던 초기 구조. 처음엔 n8n이 이슈 제목/본문/코멘트를 다 정리해서 Hermes한테 넘기는 식으로 짰다. 근데 이러면 n8n이 "무슨 내용인지 이해하고 정리하는" 역할까지 떠안게 되고, Hermes는 그냥 실행만 하는 처지가 된다. 결국 n8n은 필터링과 최소 payload 조립까지만 하고, 본문/코멘트는 Hermes가 Linear MCP로 직접 읽어오는 구조로 정리했다.
- 중간에 잠깐 거쳐간 별도 워커. n8n과 Hermes 사이에 상태를 관리하는 중간 워커를 하나 두고 폴링하는 과도기 구조를 써본 적이 있다. 하지만 최종 방향은 n8n → Hermes webhook → Linear MCP로 바로 잇는 쪽이다. 책임이 줄고, 장애 지점도 줄고, 설명도 쉬워졌다.
- Docker bridge 네트워크 이름 충돌. n8n과 Hermes를 각각 다른 docker-compose로 올렸더니 기본 네트워크가 분리돼서 서로 못 봤다. 명시적으로 external network를 하나 만들어서 두 컴포즈 파일이 같은 네트워크를 참조하게 고쳐서 해결했다.
- 권한을 너무 넓게 줬던 것. 처음엔 편의를 위해 Hermes에 파일 시스템 접근을 넓게 줬다가, 이건 아니다 싶어서 필요한 만큼만 남기고 다시 좁혔다. 자동화가 편해질수록 권한 경계는 오히려 더 타이트하게 잡아야 한다는 걸 이번에 체감했다.
실전 시작 아키텍처 (요약)
처음 이 조합을 시작한다면 이 정도 구조부터 권한다.
- Docker Compose로 n8n + Hermes를 같은 internal network에 올린다. Hermes는 호스트 포트 바인딩 없이, n8n 컨테이너에서만 접근 가능하게.
- n8n은 리버스 프록시 뒤에서 공개 webhook만 받는다. HTTPS + secret 검증은 필수.
- n8n은 이벤트 필터링과 최소 payload 조립까지만 한다. 이슈 본문/코멘트 같은 실제 컨텍스트는 Hermes가 Linear MCP로 직접 가져오게 하고, n8n은 절대 그 내용을 읽거나 실행하지 않는다.
- Hermes의 쓰기 권한은 브랜치/디렉토리 화이트리스트로 제한하고, 결과는 항상 사람이 확인하는 채널(Linear 코멘트 등)로 되돌린다.
- 관리자 접근(나)은 Tailscale로만, n8n → Hermes 트래픽과 완전히 분리된 경로를 유지한다.
이 다섯 가지만 지켜도 "n8n은 얼굴, Hermes는 손발" 구조를 안전하게 돌릴 수 있다.
정리
n8n만으로는 트리거와 연동은 되는데 진짜 판단이나 실행은 안 됐고, Hermes만 쓰자니 외부 서비스 연동과 트리거 관리가 번거로웠다. 둘을 역할별로 나눠 붙이니까 각자 잘하는 것만 하게 됐다. 처음엔 n8n이 이슈 내용을 정리해서 넘겨주는 구조로 짰다가, 그게 결국 n8n이 판단의 일부를 떠안는 거라는 걸 깨닫고 방향을 바꿨다. 지금은 n8n이 필터링과 최소 payload 전달까지만 하고, Hermes가 Linear MCP로 직접 컨텍스트를 읽고 작업하고 코멘트 남기고 이슈를 Done으로 바꾸는 데까지 전부 맡는 구조로 정리됐다.
- n8n: 공개 트리거, 이벤트 필터링, 최소 payload 전달
- Hermes: 신뢰된 내부 실행기, Linear MCP로 컨텍스트 조회/코멘트/상태 변경, Claude Code 오케스트레이션
- 경계: Docker internal network + 화이트리스트 권한 + Tailscale 관리 채널
아직 실전 검증이 더 필요한 구간이 남아있지만, 방향 자체는 확실히 맞다고 본다.
작업 환경: Ubuntu 미니PC, n8n (Docker), Hermes Agent (Nous Research), Claude Code, Tailscale