OriginTrace: Protecting the DEV Community from Content Theft using Sanity Context MCP
Sanity Context MCP로 DEV.to 게시물 도용을 추적하는 OriginTrace
OriginTrace는 DEV.to 게시물의 웹상 복제본을 찾고, 문구 유사도와 출처 표기 여부를 분석하는 프로토타입입니다. 분석 결과를 Sanity에 구조화해 저장하고, Sanity Context MCP 기반 AI 에이전트가 이를 질의해 복제본 판별과 DMCA 통지 초안 작성을 돕습니다.
- 주제
AI 요약
OriginTrace는 DEV.to 글의 무단 복제를 찾아내고 출처 표기 여부까지 분류하는 콘텐츠 출처 추적 도구입니다. 제작자는 자신의 글이 낯선 사이트에 그대로 올라온 일을 계기로, 복제본을 직접 비교하고 저자 이름이나 원문 링크가 있는지 확인하는 과정을 자동화했습니다. 이 프로젝트는 Sanity Challenge의 ‘실제 콘텐츠를 질의하는 에이전트’ 부문 출품작입니다.
복제 후보 탐색과 유사도 분석
사용자가 DEV.to 글 주소를 넣으면 OriginTrace가 본문에서 특징적인 문구를 뽑습니다. Google 검색 API인 Serper로 웹을 검색한 뒤 후보 페이지를 최대 15개까지 가져와 원문과 비교합니다. 비교에는 단어 집합의 Jaccard 유사도(가중치 20%), 5단어 단위 구간인 5-gram shingling(50%), 최장 공통 부분 수열인 LCS(30%)를 씁니다. 문장 하나를 삭제하거나 단어를 바꾸는 경우, 단어 순서를 일부 바꾸거나 중간에 단어를 끼워 넣는 경우에도 겹치는 정도를 계산하도록 구성했습니다.
출처 표기 판정과 Sanity 데이터 구조
유사도가 높은 후보를 찾으면 단순히 ‘일치’라고 판정하지 않습니다. 복제 페이지에 원저자 이름이 있는지, 원문 링크가 있는지, ‘via’나 ‘originally published on’ 같은 출처 표기 문구가 있는지를 각각 확인합니다. 이 신호를 바탕으로 credited_syndication(출처를 표기한 재게시), unattributed_repost(출처 표기 없는 재게시), no_match로 결과를 나눕니다. 제작자는 앞의 경우 별도 조치가 필요하지 않고, 출처를 누락한 경우 DMCA 통지를 고려하도록 설계했습니다.
Sanity Content Lake에는 네 종류의 문서를 저장합니다. article은 원문과 저자 참조를 담고, provenanceCheck는 후보별 유사도 점수, 판정값, 출처 표기 불리언 필드, 발견·누락 신호, DMCA 통지 초안, 일치한 문구를 기록합니다. author는 이름과 핸들을, user는 계정 정보를 담습니다. 글과 검사 결과를 구조화된 JSON으로 축적해 출처 추적 기록으로 활용합니다. 현재 데이터는 로그인으로 분리되지 않은 공개 장부 형태이며, 사용자별 비공개 데이터 격리는 향후 과제로 남아 있습니다.
Sanity Context MCP 에이전트
AI 에이전트는 Sanity Context MCP를 통해 Content Lake의 구조화된 필드를 질의합니다. 예를 들어 “유사도가 가장 높으면서도 원저자를 표기한 복제본은 무엇인가?”라는 질문에는 verdict가 no_match가 아닌 문서를 고르고, overlapPercent를 내림차순으로 정렬한 뒤 hasAuthorName, hasOriginalLink, signals를 확인해야 합니다. 키워드 검색만으로는 숫자 점수와 불리언 조건을 여러 문서에 걸쳐 비교하기 어렵다는 것이 제작자의 설명입니다.
실행 시 에이전트는 먼저 initial_context로 지식 기반의 개요를 받고, groq_query로 GROQ 질의를 작성해 데이터를 가져옵니다. 답변에는 근거가 된 문서도 인용합니다. 요약 통계는 MCP 요청을 거치지 않도록 백엔드가 fetchSanityContext()에서 직접 조회해 시스템 프롬프트에 넣습니다. 도구 호출과 답변 생성에는 AI SDK와 NVIDIA NIM의 nvidia/nemotron-3.5-lightning-30b-a3b 모델을 사용합니다. 채팅에서 새 검사 실행도 요청할 수 있으며, DMCA 통지 초안도 생성합니다.
구현 범위와 다음 단계
구현에는 Next.js 16, Sanity Content Lake, Sanity Context MCP, Serper, Mozilla Readability, Cheerio, JSDOM, TypeScript 기반 NLP 엔진을 사용했습니다. 현재는 해커톤 범위의 기능성 프로토타입이며, AI 에이전트와 Sanity 장부도 베타 단계입니다. 이후 계획에는 NextAuth/JWT 기반 사용자별 대시보드와 에이전트, Hashnode·Medium·개인 블로그 지원, 정기 검사와 알림, 전통적인 단어 중복 검사로 잡기 어려운 바꿔 쓰기 탐지가 포함됩니다. 바꿔 쓰기 탐지에는 LLM 임베딩을 추가할 예정입니다.
dev.to 반응
- @dj29 — OriginTrace가 정식 공개됐습니다. DEV.to 게시물의 복제본을 웹에서 찾고, 복제본이 출처를 제대로 표기했는지 확인하며, AI 에이전트로 증거를 분석하고 필요하면 DMCA 통지문을 작성합니다. 내일 내 게시물이 복제된 걸 발견한다면 세 기능 중 무엇부터 쓰시겠습니까?
- @yug_vasava — 좋은 아이디어에 실행도 훌륭합니다. 행운을 빕니다!
- @dj29 — 고맙습니다!
- @indiainfranotes — 문제를 잘 설정했습니다. 실무에서 계속 부딪히는 빈틈은 누가 고객 데이터나 학습 데이터에 접근했는지 사후에 입증하는 일입니다. 서명된 접근 로그와 각 읽기 작업의 명확한 목적 태그가 없으면 삭제 요청과 침해 대응 모두 막힙니다. 이 정보를 MCP나 에이전트 도구 경계에 어떻게 연결할지 궁금합니다.
- @dj29 — 좋은 질문 감사합니다. 현재 OriginTrace는 공개 장부로 동작합니다. 고객 데이터나 학습 데이터를 비공개로 다루려면 신원과 목적을 MCP 경계에 연결해야 합니다. Next.js 프런트엔드가 AI SDK로 MCP 서버에 접속할 때 서명된 JWT를 헤더에 전달하고, MCP 서버가 토큰을 검증한 뒤 도구와 리소스를 공개하는 방식입니다. 도구에는 목적 인자를 필수로 둡니다. 예를 들어
fetch_provenance(articleId, purpose="dmca_investigation")처럼 호출하게 합니다. MCP 서버가 데이터를 반환하기 전에 Sanity에 접근 로그 문서를 기록합니다. 로그에는 시각, JWT에서 가져온 사용자 ID, 호출한 도구, 전달된 목적을 담습니다. MCP 서버 단계에서 요청을 가로채 기록하면 LLM이 로그 기록을 우회하지 못합니다. Sanity Content Lake를 규정 준수 담당자가 조회할 수 있는 시간순 에이전트 활동 장부로 활용하는 설계입니다.
- @dj29 — 좋은 질문 감사합니다. 현재 OriginTrace는 공개 장부로 동작합니다. 고객 데이터나 학습 데이터를 비공개로 다루려면 신원과 목적을 MCP 경계에 연결해야 합니다. Next.js 프런트엔드가 AI SDK로 MCP 서버에 접속할 때 서명된 JWT를 헤더에 전달하고, MCP 서버가 토큰을 검증한 뒤 도구와 리소스를 공개하는 방식입니다. 도구에는 목적 인자를 필수로 둡니다. 예를 들어
- @abhijitsahoo18190 — 안녕하세요.
- @abhijitsahoo18190 — 안녕하세요!
원문: dev.to / 번역·요약: Trawling