
MCP 서버를 uvx로 실행 중인 분들은 꼭 du -sh ~/.cache/uv를 실행해 보세요
요약
Claude Code에서 MCP 서버를 uvx로 실행할 때 발생하는 스토리지 용량 급증 문제를 다룹니다. uv 특정 버전의 버그로 인해 동일한 버전의 환경이 중복 생성되어 캐시가 비대해지는 현상과 해결 방법을 설명합니다.
핵심 포인트
- uv 0.8.18 미만 버전에서 MCP 서버 실행 시 캐시 버그 발생 가능
- uv 업데이트를 통해 중복 환경 생성 문제 해결 가능
- ~/.cache/uv 디렉토리의 용량이 비정상적으로 크다면 uv 버전 확인 필요
- MCP 서버 사용 시 로컬 스토리지 관리의 중요성
안녕하세요!
주식회사 Canly에서 SRE를 맡고 있는 혼마입니다. 정말이에요!
이번에는 AI 코딩 툴을 사용하다가 생각지도 못한 곳에서 스토리지 용량을 잡아먹고 있었던 이야기에 대해 다뤄보겠습니다.
서론
사내에서는 몇 가지 Claude Code 플러그인이 작동하고 있는데, 동료로부터 "로컬 스토리지를 압박하고 있는 것이 있다"라는 상담을 받은 것이 계기가 되었습니다.
가벼운 마음으로 측정을 시작했는데, ~/.cache/uv가 70GB까지 불어나 있는 것을 확인했습니다. 게다가 그 절반 이상이 플러그인에서 실행 중인 MCP 서버 2개 분량이었습니다.
이 기사에서는 무엇이 어떻게 쌓여 있었는지, 범인을 어떻게 찾아냈는지, 그리고 삭제 명령어를 선택함에 따라 결과가 얼마나 달라졌는지에 대해 쓰겠습니다.
결론부터 말씀드리면, 이것은 uv 0.8.18 (2025-09-17)에서 수정된 기지(Known)의 버그였습니다. 제 검증 환경이 uv 0.8.0 (2025년 7월 빌드) 상태였기 때문에, 수정되기 2개월 전에 해당 문제를 겪고 있었던 것입니다.
따라서 같은 증상이 나타나는 분은 먼저 uv --version을 확인해 주세요. 0.8.18보다 낮다면 uv를 업데이트하는 것만으로 해결됩니다.
그럼에도 이 글을 남겨두는 이유는, "70GB가 되어 있다는 사실을 몇 달 동안 깨닫지 못했다", "삭제 명령어 선택에 따라 결과가 차원이 다르게 변했다"라는 점은 버전에 상관없이 도움이 될 것이라고 생각하기 때문입니다.
이하는 모두 uv 0.8.0 / macOS에서의 결과입니다. 동작은 uv 버전뿐만 아니라 각자의 Claude Code 설정(등록된 MCP 서버의 수와 내용)에도 좌우됩니다.
처음 본 숫자
저희는 사내 SRE를 위해 sre-plugin이라는 Claude Code 플러그인을 운용하고 있습니다. 이 플러그인의 .mcp.json에서는 AWS 공식 MCP 서버를 2개 실행하고 있습니다.
{
"mcpServers": {
"aws-dataprocessing": {
...
플러그인 본체는 Markdown 중심이라 약 1.6MB 정도입니다. Claude Code의 플러그인 캐시(~/.claude/plugins/cache/)에도 오래된 버전이 10세대 정도 쌓여 있었지만, 합쳐도 16MB였습니다. 이 정도는 신경 쓸 수준이 아닙니다.
문제는 uvx가 사용하는 uv의 캐시였습니다.
$ du -sh ~/.cache/uv
70G /Users/xxxxx/.cache/uv
내역을 살펴보니 거의 전부 archive-v0에 집중되어 있었습니다.
$ du -sh ~/.cache/uv/*
69G /Users/xxxxx/.cache/uv/archive-v0
508M /Users/xxxxx/.cache/uv/sdists-v9
...
범인 특정하기 — 533개의 환경
archive-v0 중에서 aws-dataprocessing-mcp-server가 들어있는 환경을 세어보겠습니다.
find ~/.cache/uv/archive-v0 \#
-path "*/site-packages/awslabs_aws_dataprocessing_mcp_server-*.dist-info" \#
| sed -E 's#(.*/archive-v0/[^/]+)/.*#\1#' | sort -u | wc -l
결과는 533개, 합계 38.6GB였습니다. 캐시 전체의 약 56%였습니다. 또 다른 billing-cost-management-mcp-server도 같은 방식으로 세었을 때 225개가 있었습니다.
여기서 의문이 생긴 점은, 이 숫자가 버전 수로 설명되지 않는다는 것입니다. 캐시에 남아 있던 MCP 서버 본체의 버전은 0.1.27 ~ 0.1.34의 7종류뿐이었습니다. 7개 버전에 대해 533개의 환경이 있다는 것은, 즉 동일한 버전에 대해 환경이 수십 개씩 만들어져 있다는 뜻입니다.
생성 일시의 분포를 보니 답이 보였습니다.
38 2026-07-01
21 2026-06-04
20 2026-08-04
...
하루에 1~38개. 이는 Claude Code의 세션을 실행한 횟수와 거의 일치하는 분포였습니다.
왜 세션마다 늘어나는가
정리하자면, 세 가지 요소가 맞물려 있는 것으로 보였습니다.
1. MCP 서버는 세션마다 실행된다
stdio 방식의 MCP 서버는 세션 시작 시 실행되어 세션 종료 시까지 유지되는 라이프사이클(Lifecycle)을 가집니다. 이는 MCP의 표준 동작이며, Claude Code 고유의 문제는 아닙니다. .mcp.json에 작성한 명령은 세션을 열 때마다 실행됩니다.
2. @latest는 버전을 고정하지 않는다
uvx awslabs.aws-dataprocessing-mcp-server@latest는 실행할 때마다 "최신 버전이 무엇인가"를 확인하는 과정부터 시작합니다.
3. 동일한 버전이라도 세션마다 환경이 생성된다
그리고 이것이 이번에 가장 까다로운 부분이었습니다.
캐시를 비운 후, 약 1일(세션 실행 6회) 동안 어떻게 변했는지 측정해 보았습니다.
| 구분 | prune 직후 | 약 1일 후 |
|---|---|---|
| 캐시 전체 | 4.0GB | 5.3GB |
| MCP 서버 환경 수 | 0개 | 17개 (dataprocessing 11 / billing 6) |
환경 생성 시각을 보면, 세션을 실행할 때마다 3개씩(한 번은 의아하게도 2개) 늘어나고 있었습니다. '3'이라는 숫자는 앞서 언급한 실행 서버 수와 일치합니다 (aws-dataprocessing가 2개 엔트리, billing-cost-management가 1개 엔트리).
또한 이때 캐시에 들어있는 MCP 서버의 버전은 0.1.34 단 한 종류뿐이었습니다. 의존성 패키지(Dependency package)도 비교해 보겠습니다.
| 비교 대상 환경 | 의존성 패키지 구성 |
|---|---|
| 동일 세션 내 (동일 시각) | 완전히 일치 |
| ... |
같은 날의 세션끼리는 의존성 패키지 구성까지 완전히 일치했습니다. 즉, "의존성 해결(Dependency resolution) 결과가 바뀌어서 별도의 환경이 된 것"은 아니었습니다. boto3의 일일 업데이트는 실제로 존재하지만, 복제 현상 자체를 설명하기에는 부족했습니다.
원인 규명 1: 런처를 바꿔서 시도했으나 실패함
처음에는 런처를 바꿔가며 시도해 보았습니다. 원인이 여기는 아닐 것 같았지만, 변수 분리를 위해 먼저 확인해 두었습니다. 평소에는 cmux를 통해 Claude Code를 실행하므로, 비교를 위해 macOS 표준 터미널에서도 시도했습니다. 종료 방법(/exit과 창/페인 닫기)도 다르게 하여 총 4가지 조건을 설정했습니다.
표의 "환경 수 증가분"은 세션을 1회 실행하고 종료했을 때, 앞서 사용한 find 명령어로 셀 수 있는 MCP 서버 환경이 몇 개 늘어났는지를 나타냅니다.
| 런처 | 종료 방법 | 종료 후 프로세스 | 환경 수 증가분 |
|---|---|---|---|
| cmux | /exit | 0 | +3 |
| cmux | 페인 닫기 | 0 | +3 |
| macOS 표준 터미널 | /exit | 0 | +3 |
| macOS 표준 터미널 | 창 닫기 | 0 | +3 |
결과적으로 모두 +3이었습니다. 런처도 종료 방법도 무관했습니다.
원인 규명 2: A/B/A 테스트로 원인 특정하기
환경 설정을 의심하는 것은 그만두고, 가장 의심스러운 @latest를 기계적으로 교체하며 비교하기로 했습니다. 실행하는 3개의 서버 모두 버전을 고정하고 동일한 절차를 반복합니다.
- "args": ["awslabs.aws-dataprocessing-mcp-server@latest"]
+ "args": ["awslabs.aws-dataprocessing-mcp-server==0.1.34"]
| 시도 | 설정 | 환경 수 증가분 |
|---|---|---|
| 1~4 (위의 런처 비교와 동일한 4가지 조건) | @latest | +3 |
| 5 | 버전 고정 | +0 |
| 6 | 버전 고정 | +0 |
| 7 | @latest로 복구 | +3 |
고정하면 멈추고, 다시 돌리면 늘어납니다. 증식의 원인은 @latest 지정이었습니다.
라고 생각했는데, 이미 알려진 수정된 버그였습니다
여기까지 파악한 후 uv의 issue를 찾아보니, 완전히 동일한 문제가 보고되어 있었습니다…!
uv tool run @latest doesn't reuse cache from specific version run #15824
원인은 메인테이너(maintainer)의 코멘트에 적혀 있었습니다.
That's not quite what's happening -- it's more that
@latest
is internally treated as equivalent to --refresh
, and when --refresh
is provided to tool run
, we always recreate the environment.
즉, @latest는 내부적으로 --refresh와 동등하게 취급되며, tool run에 --refresh가 전달되면 환경을 반드시 다시 생성한다는 구현이었습니다. "버전이 확정되지 않아서 캐시를 가져올 수 없는 것이리라"라고 추측했었는데, 틀렸습니다.
수정 사항은 Allow cached environment reuse with @latest #15827 로 반영되었으며, uv 0.8.18 (2025-09-17) 이후부터는 @latest를 사용하더라도 캐시가 재사용됩니다. 제 환경이 0.8.0인 상태라 해당 버그를 겪고 있었던 것이라는 결말이었습니다 🤦 {oh..
참고로, --resume으로 세션을 복원했을 때도 마찬가지로 +3이 되었습니다. 새로운 세션만의 문제가 아니었습니다.
【임시 대응】 삭제 명령어
임시 대응책은 쌓여있는 캐시를 삭제하는 것입니다. 삭제 방법도 몇 가지 시도해 보았습니다.
uv cache clean <패키지명>
— 5.5MiB
원인이 되는 패키지를 특정할 수 있으니, 이름을 지정해서 지우면 될 것이라고 생각했습니다.
$ uv cache clean awslabs-aws-dataprocessing-mcp-server
Removed 330 files (5.5MiB)
5.5MiB. 38.6GB를 지우고 싶었으므로, 약 7,000배의 평...
실제로 0.12.2 버전까지 올려서 테스트해 본 결과, @latest를 사용하더라도 첫 실행 시에만 1개가 생성되고, 2회차부터는 더 이상 늘어나지 않았습니다. 세션(Session)을 시작할 때도 마찬가지입니다.
다만, 완전히 0이 되지는 않습니다
수정 사항으로 인해 멈추는 것은 "같은 버전으로 해결됨에도 불구하고 매번 다시 만드는" 낭비되는 부분뿐입니다. @latest를 사용하는 이상, 실제로 새로운 버전이 릴리스되면 새로운 환경이 만들어지고 오래된 것은 캐시(Cache)에 남게 됩니다.
게다가 이번 패키지는 boto3 / botocore에 의존하고 있습니다. AWS SDK는 거의 매일 릴리스되므로, 의존성 해결(Dependency resolution) 결과가 달라지면 그것도 별도의 환경으로 쌓이게 됩니다 (앞선 비교표에서 보듯, 날짜가 다른 환경끼리는 boto3 버전만 달랐습니다).
"세션마다 +3"이라는 폭발적인 증가는 멈추지만, 그대로 두면 계속 쌓인다는 사실은 변함이 없으므로, 가끔 uv cache prune을 실행하는 운영 방식은 유지하는 것이 무난합니다.
uv를 업데이트할 수 없는 경우
사정상 업데이트를 할 수 없다면, @latest를 포기하고 버전을 고정하는 회피 방법이 있습니다.
"args": ["awslabs.aws-dataprocessing-mcp-server==0.1.34"]
위의 A/B/A 테스트에서 보았듯이, 이렇게 하면 증식은 멈춥니다. 다만 보안 패치나 기능 추가에 대한 추적이 수동이 되므로, 정기적으로 버전을 올리는 운영과 병행해야 합니다. uv를 업데이트할 수 있다면 그 방법이 더 깔끔합니다.
참고로, 플러그인 형태로 배포하는 경우에는 "업데이트된 버전이 사용자에게 전달되는가"도 신경 써야 합니다. 필자의 환경에서는 자동 업데이트 여부가 마켓플레이스(Marketplace) 단위이자 사용자별 로컬 설정(~/.claude/plugins/known_marketplaces.json)이었기 때문에, 비활성화된 사용자는 /plugin marketplace update를 실행하기 전까지는 이전 버전에 머물게 됩니다.
요약
- Claude Code 플러그인의 MCP 서버를
uvx <package>@latest로 실행하고 있었다면,~/.cache/uv가 70GB까지 늘어날 수 있음 - 세션을 시작할 때마다 환경이 3개씩, 총 약 228MB가 생성됨 (같은 날 생성된 것끼리는 의존성 구성까지 일치). - 런처(cmux / 표준 터미널)나 종료 방법과는 무관하며,
--resume을 사용해도 늘어남. - 원인은
@latest- 내부적으로--refresh처리가 되어 환경이 매번 다시 만들어졌음. - 이는 uv 0.8.18에서 수정됨. 먼저
uv --version을 확인하고, 버전이 낮다면 업데이트하는 것이 최우선 대응임. 업데이트할 수 없다면 버전 고정으로 회피 가능. - 쌓인 데이터의 청소는
uv cache prune을 사용.uv cache clean <패키지명>은 5.5MiB밖에 지워지지 않았음. - 수정 후에도 버전이 바뀔 때마다 환경은 늘어남. 증가 속도는 차원이 다르게 줄어들지만, 정기적인
prune은 역시 해두는 것이 좋음.
제목에도 썼듯이, uvx로 MCP 서버를 구동하고 계신 분들은 한 번 du -sh ~/.cache/uv를 실행해 보세요. 생각보다 많이 커져 있을지도 모릅니다.
참고
- uv tool run @latest doesn't reuse cache from specific version run #15824 — 이번 원인. 메인테이너의 설명 포함
- Allow cached environment reuse with @latest #15827 — 수정 PR
- uv 0.8.18 release notes — 수정 사항이 포함된 버전
Discussion

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