본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 26. 20:38

브라우저 MCP 서버에 로그인 작업을 맡기지 않게 된 순간, LinkedIn과의 사투가 끝났다

요약

브라우저 에이전트가 LinkedIn이나 GitHub 로그인과 같은 인증 과정을 직접 수행할 때 발생하는 실패 문제를 다룹니다. 로그인을 브라우저 루프 외부로 분리하여 세션 상태나 API 토큰을 사용하는 아키텍처 개선 방안을 제시합니다.

핵심 포인트

  • 로그인 과정은 단순 탐색이 아닌 복잡한 인증 흐름임
  • 에이전트에게 로그인 작업을 맡기면 신뢰성과 비용 문제 발생
  • 인증을 브라우저 루프 외부로 분리하는 아키텍처가 핵심
  • Playwright 세션 상태나 OAuth를 활용한 해결 권장

저는 똑같은 벽에 12번 연속으로 부딪혔습니다.

Playwright가 LinkedIn을 열고, 로그인 화면을 거치며 방황하다가, 이메일 입력 필드에서 주춤하고, 리다이렉트(redirect) 과정에서 발을 헛디디더니, 제 에이전트(agent)는 "안전하게 진행할 수 없다"는 이유를 스스로 지어내기 시작했습니다.

GitHub도 별반 다르지 않았습니다.

저는 먼저 일반적인 해결책들을 시도해 보았습니다:

  • 더 나은 프롬프트 (prompts)
  • 더 엄격한 단계별 지침 (step-by-step instructions)
  • 더 작은 작업 단위 (smaller tasks)
  • 더 많은 재시도 (more retries)
  • 더 많은 가드레일 (guardrails)

그 어떤 것도 소용이 없었습니다.

결국 문제를 해결한 방법은 당황스러울 정도로 간단했습니다:

브라우저 에이전트(browser agent)에게 로그인 작업을 맡기는 것을 중단한 것입니다.

이 문제를 파헤치던 중, Conneclaw가 LinkedIn 스크래핑을 거부하는 문제에 대한 r/openclaw의 스레드를 발견했는데, 제가 겪고 있던 상황과 거의 정확히 일치했습니다. GitHub 로그인에 관한 또 다른 스레드도 비슷한 분위기였습니다. 모델이 불안정해 보였지만, 진짜 문제는 아키텍처(architectural)에 있었습니다. 로그인이 브라우저 루프(browser loop) 안에 억지로 밀어 넣어져 있었던 것입니다.

그것이 바로 실수입니다.

만약 당신의 브라우저 MCP 서버나 브라우저 에이전트가 LinkedIn 또는 GitHub 로그인에서 계속 실패한다면, 5번째 재시도 이후에는 프롬프트 튜닝(prompt-tuning)을 멈추세요. Playwright 세션 상태 (session state), OAuth, API 토큰, 또는 전용 MCP 서버를 사용하여 인증(authentication)을 브라우저 루프 외부로 옮기세요. 브라우저는 탐색(navigation)만 수행하도록 하세요.

이 변경을 적용한 후, 거의 매 실행마다 발생하던 반복적인 실패가 거의 제로에 가깝게 줄어들었습니다.

진짜 문제: 로그인은 브라우징 작업이 아니다

사람들은 브라우저 에이전트가 탭에 보이는 모든 것을 처리할 수 있어야 하는 것처럼 말합니다.

그 탭이 실제로 '신원 경계(identity boundary)'가 되기 전까지는 듣기 좋은 말입니다.

LinkedIn 로그인은 단순히 다음과 같은 과정이 아닙니다:

  1. 페이지 열기
  2. 이메일 입력
  3. 비밀번호 입력
  4. 제출 클릭

그보다는 다음과 같은 것에 가깝습니다:

  • 리다이렉트 (redirects)
  • 세션 확인 (session checks)
  • 안티 봇 체크 (anti-bot checks)
  • MFA (다요소 인증)
  • 동의 흐름 (consent flows)
  • 의심스러운 로그인 프롬프트
  • 가끔씩만 나타나는 기이한 중간 상태들

GitHub도 화면만 다를 뿐 동일한 문제를 가지고 있습니다.

이 과정을 에이전트 루프(agent loop) 안에 넣는 순간, 당신은 모델에게 계정 권한, 보안 상태, 그리고 탐색을 동시에 관리하라고 요구하는 것입니다.

그 지점에서 상황이 꼬이기 시작합니다.

실패 패턴은 대개 동일합니다:

  1. 에이전트(Agent)가 올바르게 탐색합니다.
  2. 로그인 장벽(Login wall)에 부딪힙니다.
  3. 당신은 모델의 성능이 낮다고 가정합니다.
  4. 인증 흐름(Identity flows)을 클릭하는 방법을 가르치기 위해 더 많은 모델 호출(Model calls)을 소비합니다.
  5. 워크플로우(Workflow)는 더 느려지고, 비용은 더 많이 들며, 신뢰성은 떨어집니다.

만약 n8n, Make, Zapier, OpenClaw 또는 자체 스케줄러(Scheduler)에서 자동화(Automations)를 실행하고 있다면, 단 한 번의 잘못된 로그인 루프가 전체 실행 과정을 망칠 수 있습니다.

원래 다음과 같아야 할 작업이:

  • 페이지 열기
  • 데이터 추출
  • 계속 진행

20번의 추가적인 모델 호출과 중단된 워크플로우로 변질됩니다.

나의 주관적인 규칙

브라우저 에이전트(Browser agents)는 LinkedIn이나 GitHub의 기본 로그인 권한을 가져서는 안 됩니다.

Playwright에서도 안 됩니다.
브라우저 MCP 서버에서도 안 됩니다.
OpenClaw에서도 안 됩니다.
커스텀 에이전트 프레임워크(Custom agent frameworks)에서도 안 됩니다.

만약 당신의 브라우저 에이전트가 매 실행마다 LinkedIn이나 GitHub에 비밀번호를 입력하고 있다면, 그 아키텍처(Architecture)는 잘못된 것입니다.

그렇다면 인증(Auth)은 무엇이 담당해야 하는가?

전용 인증 경로(Dedicated authenticated path)를 사용하세요.

이는 보통 다음 중 하나를 의미합니다:

  • API 토큰(API token) + 직접적인 API 접근
  • 에이전트 외부에서 처리되는 OAuth
  • 한 번 캡처하여 재사용하는 Playwright의 storageState
  • GitHub MCP 서버와 같은 서비스 전용 MCP 서버

역할 분담은 다음과 같아야 합니다:

작업담당자
계정 권한 (Account authority)OAuth, API 토큰, 세션 부트스트랩(Session bootstrap), 전용 MCP 서버
...

이러한 분리는 사람들이 생각하는 것보다 훨씬 중요합니다.

Model Context Protocol (MCP)은 이미 이 방향을 가리키고 있습니다. 즉, 도구(Tools)는 명확한 권한 경계(Authority boundaries)와 함께 명확한 기능(Capabilities)을 노출해야 합니다.

브라우저 탐색(Browser navigation)은 하나의 기능입니다.

계정 권한(Account authority)은 또 다른 기능입니다.

이 둘을 하나의 루프에 섞는 것이 혼란을 야기하는 원인입니다.

내가 변경한 사항

1) GitHub의 경우, 계정 작업을 위해 브라우저를 사용하는 것을 중단했습니다

작업이 "이슈 생성(Create an issue)" 또는 "레포지토리 메타데이터 읽기(Read repo metadata)"라면, GitHub API 또는 GitHub MCP 서버를 사용하세요.

브라우저 탭이 아니라 말입니다.

GitHub CLI를 사용한 예시:

gh auth login
gh issue create \
  --repo owner/repo \
...

또는 일반 HTTP 사용 시:

curl -X POST https://api.github.com/repos/OWNER/REPO/issues \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
...

이렇게 하면 한 종류의 실패 가능성을 즉시 제거할 수 있습니다.

2) 브라우저 전용 작업의 경우, 한 번 인증한 뒤 세션 상태 (session state)를 재사용했습니다

만약 실제로 렌더링된 페이지가 필요하다면, 에이전트(agent)가 매 실행마다 로그인하게 만드는 대신 Playwright 세션 상태 (session state)를 사용했습니다.

import { chromium } from 'playwright';

async function bootstrapSession() {
...

그 다음 자동화 과정에서 이를 재사용합니다:

import { chromium } from 'playwright';

async function runScrape() {
...

이제 브라우저는 자신이 잘하는 일을 수행합니다:

  • 페이지 열기
  • 렌더링된 콘텐츠 기다리기
  • 데이터 추출하기
  • 일반적인 네비게이션 요소 클릭하기

반면, 자신이 못하는 일은 하지 않습니다:

  • 사용자의 신원 계층 (identity layer) 역할 수행하기

3) 내부 도구의 경우, 제한된 세션을 워크플로 (workflow)에 전달했습니다

같은 개념입니다.

에이전트 외부에서 인증을 수행합니다. 그런 다음 작업에 실제로 필요한 범위가 제한된 자격 증명 (credentials)이나 세션만을 전달합니다.

이는 OAuth 토큰, 보안 비밀 저장소 (secure secret store)의 쿠키, 수명이 짧은 자격 증명 (short-lived credentials), 또는 좁은 동작 범위를 노출하는 서비스 래퍼 (service wrapper)가 될 수 있습니다.

더 잘 작동하는 간단한 아키텍처

제가 처음부터 사용했더라면 좋았을 패턴은 다음과 같습니다:

[Scheduler / n8n / Make / Zapier / custom worker]
                |
                v
...

브라우저는 전체 시스템이 아니라 하나의 구성 요소 (component)일 뿐입니다.

결과론적으로는 당연하게 들릴 수 있습니다. 하지만 로그인 페이지에서 재시도 (retry)를 반복하며 고군분투할 때는 전혀 당연하게 느껴지지 않았습니다.

이것이 에이전트 워크플로 (agent workflows)에서 더 중요한 이유

일회성 스크립트를 실행하는 경우라면, 불안정한 로그인 (flaky login)은 짜증 나는 일일 뿐입니다.

하지만 에이전트를 24시간 내내 실행하고 있다면, 불안정한 로그인은 모든 것에 부과되는 세금과 같습니다:

  • 더 많은 재시도 (retries)
  • 더 높은 지연 시간 (latency)
  • 더 취약해지는 실행 (brittle runs)
  • 막다른 화면에서 낭비되는 더 많은 모델 호출 (model calls)
  • 모델의 역할이 아니었던 문제에 소비되는 더 많은 디버깅 시간

그리고 맞습니다, 더 많은 비용이 발생합니다.

이 지점에서 가격 모델 (pricing model)이 중요해지기 시작합니다.

워크플로 (workflows)가 인증 장벽 (auth walls)에 계속 부딪히면, 유용한 작업 대신 무의미한 작업에 모델 호출 (model calls) 비용을 쓰게 됩니다. 이것이 바로 자동화 (automations)에서 토큰당 과금 (per-token billing) 방식이 끔찍하게 느껴지는 바로 그 낭비의 유형입니다.

만약 n8n, Make, Zapier, OpenClaw 또는 커스텀 워커 (custom workers)에서 많은 에이전트 루프 (agent loops)를 실행한다면, 예측 가능한 정액제 컴퓨팅 (flat-rate compute)이 왜 그토록 매력적인지 알 수 있습니다. 물론 아키텍처 (architecture)를 수정하고 싶겠지만, 실제 자동화를 반복하는 과정에서 모든 실패한 재시도 (retry)가 또 다른 작은 과금 이벤트로 나타나지 않는다는 것은 엄청난 안도감을 줍니다.

이러한 종류의 워크로드 (workload)에 Standard Compute가 흥미로운 이유 중 하나는 바로 이것입니다. 이는 고정된 월간 가격을 가진, 즉시 사용 가능한 OpenAI 호환 API (OpenAI-compatible API)이므로, 토큰 소모 (token burn)를 계속 감시하지 않고도 에이전트 중심의 워크플로를 실행할 수 있습니다. 만약 당신의 자동화가 하루 종일 실제 작업을 수행하고 있다면, 모든 우회와 재시도에 대해 비용을 지불하는 것보다 이 가격 모델이 훨씬 더 합리적입니다.

유용한 원칙 (A good rule of thumb)

브라우저 (browser) 기능이 꼭 필요한 경우에만 브라우저를 사용하세요.

작업이 실제 시스템 동작인 경우에는 API 또는 서비스 전용 MCP 도구 (MCP tools)를 사용하세요.

예시:

작업최적의 도구
GitHub 이슈 생성GitHub API 또는 GitHub MCP 서버
...

만약 브라우저 탭이 당신의 보안 인증 시스템 (secure identity system)인 척하고 있다면, 고생하게 될 것입니다.

분리 후의 결과

브라우저가 마치 유령에 홀린 듯한 동작을 멈췄습니다.

브라우저 에이전트 (browser agent)의 작업에서 로그인을 제거하자 다음과 같이 바뀌었습니다:

  • Playwright가 페이지를 열고
  • 정상적으로 탐색하며
  • 필요한 정보를 추출하고
  • 다음 단계로 넘어갔습니다.

GitHub Actions는 브라우저 탭이 신뢰할 수 있는 권한 계층 (authority layer)인 척하는 대신, GitHub API 경로를 통해 진행되었습니다.

에이전트는 더 적게 일했습니다.

시스템은 더 많이 일했습니다.

이것이 사람들이 놓치는 부분입니다.

이것은 우아함 (elegance)에 관한 것이 아닙니다. 신뢰성 (reliability)에 관한 것입니다.

많은 팀이 이러한 실패를 보고 더 똑똑한 모델이 필요하다고 결정합니다.

제 생각에 그것은 대개 잘못된 진단입니다.

대부분의 경우, 해결책은 브라우저를 인증 시스템 (auth system)으로 사용하는 것을 중단하는 것입니다.

실무 체크리스트 (Practical checklist)

만약 브라우저 MCP 서버가 LinkedIn이나 GitHub에서 계속 실패한다면, 다음을 시도해 보세요:

[ ] 동일한 로그인 프롬프트(login prompt)를 반복해서 시도하지 마세요
[ ] 에이전트 루프(agent loop)에서 비밀번호 입력 과정을 제거하세요
[ ] 가능한 경우 API 토큰을 사용하세요
...

최종 결론 (Final take)

제가 브라우저 MCP 서버에게 로그인을 시키는 것을 멈춘 순간, 서버는 LinkedIn과의 사투를 멈췄습니다.

모델이 더 똑똑해졌기 때문이 아닙니다.

Playwright, LinkedIn, GitHub, 그리고 MCP에게 같은 장소에서 잘못된 일을 시키는 것을 마침내 그만두었기 때문입니다.

만약 여러분의 에이전트가 로그인 장벽(login wall)에서 계속 막힌다면, 비밀번호 입력 필드(password field)를 프롬프트 튜닝(prompt-tuning)하는 데 또 다른 오후 시간을 허비하지 마세요.

인증(auth)과 탐색(navigation)을 분리하세요.

그것이 해결책입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0