Claude 내부에서 SEO 갭 분석을 수행할 수 있도록 백링크 API를 MCP 서버로 래핑하기
요약
SEO 분석 워크플로우를 자동화하기 위해 백링크 API를 MCP(Model Context Protocol) 서버로 구현하는 방법을 소개합니다. Claude Code와 같은 AI 에이전트 내에서 직접 경쟁사 갭 분석을 수행할 수 있도록 설계되었습니다.
핵심 포인트
- 백링크 API를 MCP 서버로 래핑하여 AI 에이전트와 통합
- Common Crawl 데이터를 활용한 공개 데이터 기반의 재현 가능한 분석
- 단순 API 매핑을 넘어선 복합 도구(Composite Tool) 설계 방식 제안
- 중복성 필터링을 통한 고품질 SEO 타겟 도메인 추출 로직
저는 경쟁사 백링크 조사를 꽤 많이 수행하는데, 그 워크플로우(workflow)가 항상 저를 짜증 나게 했습니다. 대시보드를 열고, 쿼리(query)를 실행하고, CSV를 내보내고, 눈으로 확인하고, 도메인을 문서에 복사하고, 이메일로 전환하는 과정 말이죠. 본질적으로 에이전트(agent)가 처리해야 할 데이터 필터링 문제임에도 불구하고 너무 많은 탭 전환이 필요했습니다.
그래서 제가 사용하던 백링크 API를 MCP 서버로 래핑(wrapped)했습니다. 이제 저는 Claude Code(또는 Cursor, Cline, Zed, Windsurf)에 머물면서 목표를 설명하기만 하면 됩니다. 다음은 구축 과정입니다: 아키텍처(architecture), 4가지 도구, 그리고 제가 아직 확신하지 못하는 한 가지 설계 결정에 대해 다룹니다.
데이터 소스
이 서버는 Common Crawl 하이퍼링크 웹그래프(webgraph)를 기반으로 작동합니다. 이는 1억 2천만 개의 도메인에 걸쳐 약 44억 개의 엣지(edges)를 포함하며, 분기별로 Parquet 형식으로 게시됩니다. 이는 특히 MCP 도구에 있어 중요한데, 데이터가 공개되어 있어 에이전트에게 전달할 때 스크래핑된 독점 인덱스(scraped-proprietary-index)에 대한 책임 문제가 없으며, 누구나 동일한 쿼리를 재현할 수 있기 때문입니다.
그 앞단의 HTTP API(CrawlGraph)가 무거운 DuckDB 작업을 수행하며, MCP 서버는 그 위에서 작동하는 얇은 TypeScript stdio 클라이언트입니다. 서버를 가볍게 유지한 것은 의도적인 결정이었습니다. 모든 쿼리 비용, 캐싱(caching), 할당량(quota) 로직이 서버 측에 존재하므로, MCP 패키지는 API 키를 넘겨주기 전에 감사(audit)하기 쉬운 약 300줄 정도의 래퍼(wrapper) 상태를 유지합니다.
4가지 도구
backlinks → 대상에 대한 참조 도메인(referring domains) 및 권위 점수(authority scores)
gap_analysis → 귀하에게는 링크를 걸지 않지만 경쟁사에게는 링크를 거는 도메인
gap_outreach_targets → 복합적인 플레이 (아래 참조)
...
backlinks와 gap_analysis는 API 엔드포인트(endpoints)와 1:1로 매핑됩니다. gap_analysis는 흥미로운 기본 요소(primitive)입니다. 귀하의 도메인과 2~5개의 경쟁사를 제출하면, 최소 하나 이상의 경쟁사에는 링크를 걸지만 귀하에게는 걸지 않는 모든 도메인을 반환하며, 각 도메인에는 어떤 경쟁사에 링크를 걸고 있는지 나열하는 found_on 배열이 태그로 붙습니다.
복합 도구, 그리고 제가 확신하지 못하는 결정
대부분의 API 래퍼 (API-wrapper) MCP 서버는 순수한 1:1 매핑 방식입니다. 저는 주관적인 관점이 반영된 복합 도구(composite tool)인 gap_outreach_targets를 하나 추가했습니다. 왜냐하면 가공되지 않은 갭 (gap) 출력값 그 자체는 사용자가 실제로 원하는 것이 아니라, 사용자가 원하는 것을 만들기 위한 원재료에 불과하기 때문입니다.
gap_analysis 위에서 이 도구가 수행하는 작업은 다음과 같습니다:
- 완전한 중복(total overlap)으로 필터링. 사용자가 나열한 모든 경쟁사를
found_on이 포함하는 도메인만 유지합니다. 한 명의 경쟁사에게만 링크를 거는 사이트는 우연이거나 유료 광고일 수 있습니다. 하지만 세 명 모두에게 링크를 거는 사이트는 귀하의 니치 (niche) 시장 전체를 다루면서 단지 귀하를 들어본 적이 없는 퍼블리셔 (publisher)입니다. 그 중복성이 바로 자격 요건입니다. - 플랫폼 노이즈 제거.
amazonaws.com,github.io,facebook.com, CDN, URL 단축 서비스 등은 모든 백링크 프로필에 등장하며 결코 아웃리치 (outreach) 대상이 될 수 없습니다. 접미사 매칭 (suffix matching)을 지원하는 차단 목록 (denylist)이 있어 서브도메인 (subdomain)도 함께 걸러집니다. - 권위도(authority)에 따른 순위 지정. 살아남은 상위 N개 도메인에 대해 저렴한 도메인별 권위도 조회를 수행하고 정렬하여, 가치가 가장 높은 잠재적 타겟이 먼저 나타나도록 합니다. 각 조회는 할당량(quota)에서 API 호출 1회를 소모하므로, 이 기능은 선택 해제 방식(
enrich_top: 0)으로 설정되어 있습니다.
// 핵심 필터 로직 (대략적인 예시)
const priority = gaps
.filter(g => !isPlatformNoise(g.linking_domain))
...
제가 계속해서 고민하고 있는 결정 사항: MCP 서버로서 주관적인 관점이 반영된 복합 도구를 만드는 것이 옳은 결정일까요, 아니면 순수한 API 미러 (API mirror) 상태를 유지하여 에이전트 (agent)가 자신의 추론 과정에서 직접 필터링과 순위 지정을 수행하게 두어야 할까요?
복합 도구를 지지하는 논거:
- 모델이 매번 재구성해야 하는 워크플로우 (workflow)를 인코딩함으로써, 토큰 소모를 줄이고 실수를 방지합니다 (저는 에이전트가 플랫폼 필터링을 잊어버리는 것을 한두 번 이상 목격했습니다).
- 모델이 소화해야 하는 1,000줄짜리 데이터 덤프 (dump) 대신, 작고 순위가 매겨진, 즉시 의사결정이 가능한 리스트를 반환합니다.
반대하는 논거:
- 이는 누수되는 추상화 (leaky abstraction)입니다. 누군가가 약간 다른 필터(예: 3개 중 2개의 중복, 다른 노이즈 리스트)를 원하게 되는 순간, 그들은 기본 요소 (primitives)를 조합하는 대신 저의 의견과 싸워야 합니다.
- 플랫폼의 차단 목록 (denylist)을 숨기는데, 이는 가시적으로 보여야 마땅한 판단 영역입니다.
저는 원시적인 gap_analysis 기본 요소와 복합 도구 (composite)를 모두 출시하는
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기