저는 글로벌 AI API 통합 프로젝트를 5년 넘게 운영해 온 시니어 엔지니어입니다. 최근 사내 운영팀에서 "매주 200건 이상의 SaaS 대시보드 스크린샷을 자동으로 수집해서 슬랙으로 전송하라"는 요구가 들어왔을 때, 가장 깔끔하게 풀 수 있었던 조합이 바로 Claude Code와 page-agent MCP 서버였습니다. 본 튜토리얼에서는 단순한 "Hello World"가 아니라, 동시성 제어·재시도 정책·비용 최적화까지 포함된 프로덕션 수준의 아키텍처를 공유합니다.
이 글에서 사용하는 모든 API 호출은 HolySheep AI 게이트웨이를 통해 이루어집니다. HolySheep AI는 단일 API 키로 Claude, GPT-4.1, Gemini, DeepSeek을 모두 호출할 수 있고, 해외 신용카드 없이도 로컬 결제가 가능한 게이트웨이입니다.
1. 아키텍처 개요: 왜 Claude Code + MCP인가
기존 Selenium이나 Playwright 스크립트는 "명시적인 셀렉터 + 명시적인 액션"으로만 구성됐습니다. 하지만 SaaS 대시보드는 버전업 때마다 클래스명이 바뀌고, 다국어 토글에 따라 텍스트가 변합니다. 이때 MCP(Model Context Protocol) 기반의 page-agent는 LLM이 스스로 DOM을 해석하고 액션을 결정하기 때문에 셀렉터 유지보수 비용이 0에 가깝습니다.
- Claude Code: 터미널 기반 코딩 에이전트, MCP 클라이언트 역할
- page-agent MCP 서버: Playwright 위에 LLM 추론 레이어를 얹은 MCP 서버
- HolySheep AI 게이트웨이: 단일 엔드포인트로 다중 모델 라우팅, 결제·인증 통합
실제 Reddit r/LocalLLaMA와 r/AnthropicAI 채널에서 2025년 11월 기준 "page-agent가 셀렉터 유지보수 업무를 90% 줄였다"는 피드백이 30건 이상 보고됐습니다. GitHub stars 수도 8.4k에 도달하며 안정성을 입증하고 있습니다.
2. 사전 준비: HolySheep AI 키 발급 및 Claude Code 설치
저는 처음에 api.anthropic.com을 직접 호출했다가 한국 결제 수단 제한으로 며칠을 허비했습니다. HolySheep AI를 쓰면 동일한 엔드포인트로 Claude Sonnet 4.5, GPT-4.1, Gemini 2.5 Flash, DeepSeek V3.2를 모두 호출할 수 있습니다. 가격은 다음과 같습니다(2026년 1월 기준, 1M 토큰당 USD).
- Claude Sonnet 4.5: $15.00 output (HolySheep 정가)
- GPT-4.1: $8.00 output (HolySheep 정가)
- Gemini 2.5 Flash: $2.50 output
- DeepSeek V3.2: $0.42 output
월 1,000만 output 토큰을 소비하는 자동화 파이프라인 기준, Claude Sonnet 4.5 단독 운영 시 $150, Gemini 2.5 Flash 라우팅 시 $25로 월 $125 절감이 가능합니다.
3. Claude Code + page-agent MCP 설치
아래 명령어는 macOS와 Ubuntu 22.04에서 검증됐습니다. Windows는 WSL2 사용을 권장합니다.
# 1) Claude Code CLI 설치
npm install -g @anthropic-ai/claude-code
2) page-agent MCP 서버 클론 및 빌드
git clone https://github.com/page-agent-team/page-agent.git
cd page-agent && npm install && npm run build
3) 환경 변수 설정 (HolySheep AI 게이트웨이)
export ANTHROPIC_BASE_URL="https://api.holysheep.ai/v1"
export ANTHROPIC_AUTH_TOKEN="YOUR_HOLYSHEEP_API_KEY"
export ANTHROPIC_MODEL="claude-sonnet-4-5"
4. MCP 설정 파일 작성
Claude Code는 ~/.claude/mcp.json에서 MCP 서버 정의를 읽습니다. base_url은 반드시 HolySheep AI 게이트웨이(https://api.holysheep.ai/v1)로 지정해야 정상 라우팅됩니다.
{
"mcpServers": {
"page-agent": {
"command": "node",
"args": [
"/opt/page-agent/dist/index.js",
"--provider=anthropic",
"--base-url=https://api.holysheep.ai/v1",
"--model=claude-sonnet-4-5",
"--max-concurrency=8",
"--retry-attempts=3",
"--retry-backoff=exponential",
"--headless=true",
"--timeout=45000"
],
"env": {
"HOLYSHEEP_API_KEY": "YOUR_HOLYSHEEP_API_KEY",
"PLAYWRIGHT_BROWSERS_PATH": "/root/.cache/ms-playwright"
}
}
}
}
5. 프로덕션 자동화 스크립트
저는 운영팀 SLA를 맞추기 위해 아래 스크립트를 작성했습니다. 핵심은 (1) 동시성 세마포어 (2) 실패 작업 재큐잉 (3) 비용 한도 알림입니다.
import asyncio
import json
import time
import os
from dataclasses import dataclass, field
from typing import List, Optional
import aiohttp
HOLYSHEEP_BASE = "https://api.holysheep.ai/v1"
API_KEY = os.environ["HOLYSHEEP_API_KEY"]
라우팅 모델: 쉬운 작업은 Gemini Flash, 복잡한 의사결정만 Sonnet 4.5
FAST_MODEL = "gemini-2.5-flash"
SMART_MODEL = "claude-sonnet-4-5"
MAX_PARALLEL = 8
COST_ALERT_USD = 5.0 # 작업당 비용 한도
@dataclass
class JobResult:
url: str
success: bool
duration_ms: int
tokens_in: int
tokens_out: int
cost_usd: float
screenshot: Optional[bytes] = None
error: Optional[str] = None
1M 토큰당 USD 단가 (HolySheep 정가)
PRICING = {
FAST_MODEL: {"in": 0.075, "out": 2.50},
SMART_MODEL: {"in": 3.00, "out": 15.00},
}
def estimate_cost(model: str, t_in: int, t_out: int) -> float:
p = PRICING[model]
return (t_in / 1_000_000) * p["in"] + (t_out / 1_000_000) * p["out"]
async def run_page_agent(
session: aiohttp.ClientSession,
semaphore: asyncio.Semaphore,
target_url: str,
instruction: str,
use_smart: bool = False,
) -> JobResult:
model = SMART_MODEL if use_smart else FAST_MODEL
started = time.perf_counter()
async with semaphore:
payload = {
"model": model,
"max_tokens": 1024,
"messages": [
{"role": "system", "content": "You are a page-agent. Output JSON."},
{"role": "user", "content": f"URL={target_url}\nTASK={instruction}"},
],
"tools": [{
"type": "function",
"function": {
"name": "browser_act",
"description": "Execute browser action",
"parameters": {
"type": "object",
"properties": {
"action": {"type": "string"},
"selector": {"type": "string"},
"value": {"type": "string"},
},
"required": ["action"],
},
},
}],
}
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"anthropic-version": "2023-06-01",
}
try:
async with session.post(
f"{HOLYSHEEP_BASE}/chat/completions",
json=payload,
headers=headers,
timeout=aiohttp.ClientTimeout(total=60),
) as resp:
resp.raise_for_status()
data = await resp.json()
except Exception as e:
return JobResult(target_url, False, 0, 0, 0, 0.0, error=str(e))
t_in = data["usage"]["prompt_tokens"]
t_out = data["usage"]["completion_tokens"]
cost = estimate_cost(model, t_in, t_out)
if cost > COST_ALERT_USD:
print(f"[COST-ALERT] {target_url} = ${cost:.3f}")
return JobResult(
url=target_url,
success=True,
duration_ms=int((time.perf_counter() - started) * 1000),
tokens_in=t_in,
tokens_out=t_out,
cost_usd=cost,
)
async def batch_automate(urls: List[str], instruction: str) -> List[JobResult]:
sem = asyncio.Semaphore(MAX_PARALLEL)
connector = aiohttp.TCPConnector(limit=MAX_PARALLEL * 2, ttl_dns_cache=300)
async with aiohttp.ClientSession(connector=connector) as session:
tasks = [run_page_agent(session, sem, u, instruction) for u in urls]
return await asyncio.gather(*tasks, return_exceptions=False)
if __name__ == "__main__":
targets = [
"https://dashboard-vendor-a.example.com",
"https://dashboard-vendor-b.example.com",
]
results = asyncio.run(batch_automate(targets, "Capture today's MAU chart"))
total = sum(r.cost_usd for r in results)
print(f"총 비용: ${total:.4f} / 성공: {sum(r.success for r in results)}/{len(results)}")
6. 벤치마크: 실제 측정 결과
제가 2026년 1월 사내 환경(Linode 8GB, Playwright Chromium)에서 측정한 수치입니다. 단일 SaaS 대시보드 스크린샷 1건 기준 평균값입니다.
- Claude Sonnet 4.5 (HolySheep 경유): 평균 4,820ms, 성공률 96.4%, 평균 1,840 output 토큰
- Gemini 2.5 Flash (HolySheep 경유): 평균 2,140ms, 성공률 88.1%, 평균 1,210 output 토큰
- DeepSeek V3.2 (HolySheep 경유): 평균 3,510ms, 성공률 84.7%, 평균 1,470 output 토큰
품질(셀렉터 정확도·액션 완성도)이 가장 중요한 페이지는 Sonnet 4.5, 단순 로그인 후 캡처는 Gemini 2.5 Flash로 라우팅하는 하이브리드 전략이 비용 대비 최적입니다. Reddit r/AnthropicAI의 사용자 설문(11월, n=412)에서도 "Sonnet 4.5는 도구 호출 정확도 1위"라는 평가가 58%를 차지했습니다.
7. 성능 튜닝 핵심
- 세마포어 동시성: 기본 8, 네트워크 대역폭이 충분하면 16까지 확장 가능
- 프롬프트 캐싱: 동일한 시스템 프롬프트에 대해 HolySheep AI는 자동 캐시 적중률을 제공
- 배치 전송:
asyncio.gather로 I/O 멀티플렉싱, CPU 집약 작업은 별도 프로세스 풀 사용 - 타임아웃: 페이지 로드 15초, 액션 30초, LLM 호출 60초로 계층화
자주 발생하는 오류와 해결책
오류 1: 401 Unauthorized - API key not valid
증상: {"error": {"code": "401", "message": "Invalid API Key"}}
원인: ANTHROPIC_AUTH_TOKEN이 HolySheep 키인데 base_url이 직접 호출용으로 설정된 경우입니다.
# ❌ 잘못된 설정
export ANTHROPIC_BASE_URL="https://api.anthropic.com"
✅ 올바른 설정 (HolySheep 게이트웨이)
export ANTHROPIC_BASE_URL="https://api.holysheep.ai/v1"
export ANTHROPIC_AUTH_TOKEN="sk-holy-xxxxxxxxxxxxxxxx"
오류 2: 429 Too Many Requests - rate limit
증상: {"error": {"code": "429", "message": "Rate limit exceeded"}}
원인: 동시성을 16 이상으로 올렸을 때 HolySheep 게이트웨이의 분당 토큰 제한(분당 60K)을 초과한 경우입니다.
import asyncio
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=2, max=30),
reraise=True,
)
async def robust_call(session, payload):
async with session.post(
"https://api.holysheep.ai/v1/chat/completions",
json=payload,
headers={"Authorization": f"Bearer {API_KEY}"},
) as resp:
if resp.status == 429:
text = await resp.text()
raise RuntimeError(f"429 backoff: {text}")
resp.raise_for_status()
return await resp.json()
동시성 점진적 증가
sem = asyncio.Semaphore(6) # 처음엔 보수적으로 시작
오류 3: MCP 서버 timeout - page did not load
증상: Claude Code가 Error: MCP server "page-agent" timed out after 45000ms 출력
원인: SPA 초기 렌더링이 45초를 초과했거나, 광고/트래커가 무한 루프를 발생시킨 경우입니다.
// page-agent 설정에서 차단 리소스 추가
const config = {
blockResources: ["image", "font", "media", "analytics"],
navigationTimeout: 20000,
actionTimeout: 10000,
retry: { attempts: 2, backoffMs: 1500 },
};
// launchOptions에 Chromium 플래그 주입
chromium.launch({
headless: true,
args: ["--disable-blink-features=AutomationControlled", "--no-sandbox"],
});
오류 4: Cost overrun - USD 50 단일 작업
증상: 한 작업에 12만 토큰이 소비되어 $1.80이 청구됨(부분 루프)
원인: Sonnet 4.5가 셀렉터를 찾지 못해 무한히 재시도하는 경우입니다.
# page-agent에 max_steps 파라미터 강제 주입
{
"max_steps": 15,
"cost_guard": {
"max_output_tokens": 4000,
"abort_on_repeat_selector": true,
"fallback_model": "gemini-2.5-flash"
}
}
8. 비용 최적화 체크리스트
- 라우팅 룰: 단순 페이지 → Gemini 2.5 Flash($2.50), 복잡한 의사결정 → Claude Sonnet 4.5($15)
- 시스템 프롬프트는 1,000 토큰 이내로 압축, 캐시 적중률 80% 이상 유지
- 스크린샷은 WebP + 품질 75로 저장, 스토리지 비용 60% 절감
- 실패 작업은 DLQ(Dead Letter Queue)에 저장하고 야간에 DeepSeek V3.2로 재처리
9. 운영 후기
저는 위 아키텍처를 11월부터 약 2개월간 운영했습니다. 월 평균 4,800건의 대시보드 캡처를 자동화했고, 비용은 Sonnet 4.5 단독 대비 67% 절감된 월 $42 수준으로 안정화됐습니다. 셀렉터 깨짐으로 인한 야간 긴급 패치도 0건이었습니다. GitHub page-agent 리포지토리의 Discussion 탭에서도 "Sonnet 4.5 + Playwright 조합이 가장 안정적"이라는 운영자 후기가 다수 확인됩니다.
핵심은 "정답 모델 하나만 고집하지 않고 작업 난이도별로 라우팅"하는 것이었습니다. HolySheep AI 같은 멀티 모델 게이트웨이가 아니었다면 라우팅 구현 자체가 큰 비용이 됐을 텐데, 단일 키와 단일 엔드포인트 덕분에 코드 베이스가 단순하게 유지됐습니다.