AI‑네이티브 데이터 디스커버리를 위한 MCP 서버 구축: Rust Crates 생태계: Part I
Source: Building an MCP Server for AI‑Native Data Discovery – Rust Crates Ecosystem (Part I)
Introduction
전통적인 데이터 탐색은 미리 정의된 쿼리—SQL 코드, 대시보드, 혹은 BI 도구—에 의존합니다.
데이터 웨어하우스를 대화형으로 탐색하면서, 개방형 질문을 하고 AI가 여러분이 생각지도 못한 패턴을 찾아내도록 할 수 있다면 어떨까요?
Model Context Protocol (MCP) 은 이를 가능하게 합니다. 저는 Rust 생태계를 분석하기 위해 MCP 서버를 구축하고, Claude에게 이를 탐색하도록 하여 크레이트, 의존성, 트렌드에 관한 질문에 답하도록 했습니다.
따라서 따라하고 싶다면 전체 프로젝트를 위한 Rust Crates Analytics Repo 를 확인하세요.
Source: …
crates.io 데이터 이해
crates.io DB 덤프를 다운로드하고 압축을 푼 후(README의 download link 참고) 다음을 받게 됩니다:
- 로컬에 로드하기 위한 지침이 포함된 PostgreSQL 덤프.
- 실제 내용을 나타내는 CSV 파일들이 들어 있는
data폴더.
엔터티 개요
| 엔터티 | 설명 |
|---|---|
crates | crates.io에 게시된 Rust 패키지 |
versions | 특정 크레이트의 릴리스 (예: serde v1.0.228) |
categories | 분류 체계 (예: science::bioinformatics) |
keywords | 검색성을 위한 사용자 정의 태그 (예: cargo, sql) |
teams | 크레이트를 소유할 수 있는 조직 계정 (GitHub) |
users | 개인 개발자 계정 (GitHub) |
팩트 테이블
version_downloads– 버전별, 일별 다운로드 수 시계열(최근 3개월 데이터만).crate_downloads– 크레이트별 전체 다운로드 수(누적).
조인 테이블
crates_categories– 크레이트와 카테고리를 연결.crate_owners– 크레이트와 사용자 또는 팀을 연결.crates_keywords– 크레이트와 키워드를 연결.dependencies– 버전과 해당 버전이 의존하는 크레이트를 연결.
지원 테이블
metadata–total_downloads가 들어 있는 단일 행.reserved_crate_names– 보호/사용 불가 크레이트 이름 목록.default_versions– 크레이트와 기본 버전을 연결.
히스토리 데이터
version_downloads테이블은 가장 최근 3개월 데이터만 보관합니다.- 오래된 일일 CSV 덤프(크레이트.io 사이트에서 제공)에는
version_id와downloads열이 있으며, 날짜는 파일명에서 추론해야 합니다. - 다른 모든 테이블은 덤프 시점의 생태계 상태를 나타냅니다(예:
crates.created_at,crates.updated_at).
핵심 요점
- DB 덤프는 매일 새로 고쳐지며, 다운로드 시점의 생태계를 반영합니다.
- 매일 3개월 창에서 한 날치 데이터가 삭제되고 CSV 아카이브에 저장됩니다.
- 분석에 가장 중요한 테이블은
crates,versions,version_downloads,dependencies입니다.
아키텍처 개요
ELT 파이프라인 설계
| 레이어 | 목적 |
|---|---|
| raw | crates.io 덤프에서 직접 CSV 로드 |
| staging | 정제 및 검증된 데이터 (stg_ 접두사가 붙은 테이블) |
| marts | 분석용 준비된 테이블 (이 게시물에서는 다루지 않음) |
추출
- crates.io DB 덤프(
.tar.gz)를 다운로드합니다. - 아카이브에서 CSV 파일을 추출합니다.
적재
- 전체 CSV를
raw스키마에 전체 새로 고침 전략으로 가져옵니다. - 각 새로운 덤프는 raw 테이블을 교체하여 현재 상태의 깨끗한 스냅샷을 제공합니다.
변환
staging스키마에서 데이터 품질 규칙을 적용합니다:- 모든 타임스탬프를 UTC로 정규화합니다.
stg_version_downloads를 점진적으로 로드합니다(새 날짜만 추가).- 첫 실행에서는 사용 가능한 모든 날짜를 수집합니다.
- 이후 실행에서는 새로 사용 가능한 데이터만 추가합니다.
- 차원 테이블(
categories,crates,versions, …)에 대해 전체 새로 고침을 수행하여 업데이트를 반영합니다. - 데이터 계약을 강제하고 품질 테스트를 실행합니다.
이 접근 방식은 3개월 롤링 윈도우를 효율적으로 처리하면서 stg_version_downloads에 전체 이력 아카이브를 보존합니다.
과거 다운로드 백필링
- 2014‑11‑11부터의 과거 아카이브가 존재합니다.
- 시작/종료 날짜를 매개변수로 하는 백필 스크립트가 오래된 CSV를 직접
stg_version_downloads에 수집합니다. crates,dependencies,versions의 스냅샷도 덤프 간 변경 사항을 포착하기 위해 찍습니다.
제약 조건 및 기술 스택
| 제약 조건 | 해결책 |
|---|---|
| 인프라 오버헤드 없음 | DuckDB – 임베디드, 단일 파일 OLAP 데이터베이스 |
| 크로스 플랫폼 | Python + uv (빠른 패키지 관리자) |
| 빠른 반복 | dbt – SQL 변환, 테스트 및 스냅샷용 |
| 저장 효율성 | DuckDB 파일 ~10 GB (2014‑11‑11부터 2025‑11‑29까지 데이터); 노트북에서 실행 (≈8 GB RAM, ≈20 GB 여유 디스크) |
| 시각화 | Streamlit – 빠른 데이터 검증 대시보드용 |
모든 프로젝트 의존성은 uv 로 관리됩니다; 전제 조건은 uv 가 설치되어 있는 것뿐입니다.
고아 버전 조사
흥미로운 데이터 품질 검사 중 하나는 stg_version_downloads 테이블의 고아 버전을 조사하는 것이었습니다—version_id가 versions 테이블에 존재하지 않는 레코드입니다.
조사 단계
-
고아 행 식별
SELECT vd.version_id FROM stg_version_downloads vd LEFT JOIN stg_versions v ON vd.version_id = v.id WHERE v.id IS NULL LIMIT 100; -
문제 규모 파악
SELECT COUNT(*) AS orphan_count FROM stg_version_downloads vd LEFT JOIN stg_versions v ON vd.version_id = v.id WHERE v.id IS NULL; -
근본 원인 분석
- 고아는 다운로드 스냅샷 이후에 yanked되거나 삭제된 크레이트에서 종종 발생합니다.
- 3개월 기간에는 현재
versions테이블에 존재하지 않는 버전에 대한 다운로드 기록이 포함될 수 있습니다.
-
해결 전략
- 역사적 완전성을 위해 고아 행을 유지하되, 하위 분석에서는 플래그를 지정합니다.
- 선택적으로, yanked/삭제된 버전의 메타데이터를 저장하는 별도의 “historical versions” 테이블을 유지할 수 있습니다.
이 검사는 자동화된 dbt 테스트의 일부가 되어, 향후 로드 시 새로운 고아 레코드가 나타나면 이를 감지하도록 합니다.
결론
By combining a lightweight ELT pipeline (Python + uv + DuckDB + dbt) with the Model Context Protocol, you can transform the Rust crates.io dataset into an AI‑explorable knowledge base.
- Resource‑efficient: The architecture respects strict resource constraints.
- Historical depth: Preserves a full view of downloads and dependencies over time.
- Analytical power: Enables investigations such as orphan‑version detection and broader ecosystem analyses.