
7개의 서비스, 0개의 업로드 솔루션: MCP 파일 전송이 실패하는 이유
요약
현재 MCP(Model Context Protocol) 사양에는 파일 전송 기능이 없어, 실제 서비스에서 파일 업로드를 구현하는 데 한계가 있음을 지적합니다. 텍스트와 이미지 위주의 프로토콜 한계를 극복하기 위해 객체 스토리지의 URL을 참조하는 우회 방식을 제안합니다.
핵심 포인트
- MCP 표준 사양에는 파일 전송을 위한 전용 슬롯이 없음
- 7개 서비스 테스트 결과, 표준 MCP 방식의 파일 업로드 지원은 0개
- 현재는 텍스트와 base64-image 전용으로 프로토콜이 유지됨
- 해결책으로 객체 스토리지의 사전 서명된 URL을 사용하는 참조 방식 제안
저는 MCP 클라이언트를 통해 freee 비용 처리 시스템에 영수증 하나를 첨부하는 데 하루를 허비했습니다. 전혀 작동하지 않았습니다. 그래서 범위를 넓혔습니다. 저희 팀이 실제 운영 환경에서 사용하는 7개의 서비스에 대해 각각 한 번씩 업로드 테스트를 진행했습니다.
결과: 표준 MCP 방식으로 파일 업로드를 지원하는 서비스는 7개 중 0개였습니다. 4개는 아예 거부했고, 3개는 MCP 서버가 자신의 로컬 디스크에서 파일을 읽고 있기 때문에
둘 다 제안 사항입니다. 어느 것도 2026-07-28 릴리스 후보(release candidate)에 포함되어 있지 않습니다. 해당 릴리스 후보는 Apps, Tasks, 그리고 elicitation form/URL 모드를 배포하는데, 이들은 모두 '핵심 프로토콜 외부에서 작동하는' 작업 방식의 우회책입니다. 핵심 자체는 여전히 텍스트와 base64-image 전용으로 유지됩니다.
각 서비스가 실제로 작동하는 방식 (시도할 때)
freee (회계) — 절대 불가(hard no)
freee의 REST API는 multipart/form-data 영수증 첨부 파일을 받습니다. MCP의 JSON-RPC 계층은 이를 전송할 수 없습니다. MCP 서버는 클라이언트와 freee 사이에 위치하며, 상위로 통신하는 프로토콜 자체가 해당 바이트를 위한 슬롯을 가지고 있지 않습니다. 영수증 첨부가 필요한 지출 워크플로우는 엔드투엔드로 완료되지 못합니다. 이는
github-mcp-server Issue #738에서는 Claude Code가 PR(Pull Request)에 UI 스크린샷을 첨부할 수 있도록 이미지 업로드를 요청하고 있습니다. 해당 스레드는 'closed-pending-spec(사양 확정 대기 중 종료)' 상태입니다. 즉, GitHub 팀 또한 SEP-1306을 기다리고 있다는 의미입니다.
Gmail, Google Drive, Slack —
이것들은 실재하는 사례들입니다. 또한 이는 프로토콜이 파일 문제를 다른 누군가의 책임으로 떠넘기고 있음을 의미합니다. 현재 그 누군가는 모든 MCP 서버 작성자이며, 해결책들은 서로 호환되지 않습니다.
실제로 배포 가능한 우회 방법 (Workaround)
SEP-1306 또는 SEP-2356이 도입될 때까지, 엔드 투 엔드(end-to-end)로 진정으로 작동하는 유일한 방법은 참조 방식(reference-not-bytes) 패턴입니다:
- MCP 클라이언트(또는 사용자)가 파일을 객체 스토리지(Object Storage) — S3, GCS, 또는 서버가 소유한 사전 서명된 URL(presigned-URL) 엔드포인트 — 에 업로드합니다.
- MCP 도구 호출(tool call)은 결과로 생성된 URL 또는 스토리지 키를
TextContent문자열로 전달합니다. - MCP 서버는 스토리지에서 바이트(bytes)를 가져와 상위 API(freee, GitHub, Jira)에 전달하고, 새로운 첨부 파일 ID를 텍스트로 반환합니다.
바이트는 JSON-RPC를 절대 거치지 않습니다. 모델은 34만 토큰에 달하는 base64 블롭(blob)을 결코 보지 않습니다. 서버는 얇은 프록시(thin proxy) 역할을 수행하며, 노트북에서 실행되든 컨테이너에서 실행되든 동일하게 작동합니다.
우연하게도, 이 방식은 SEP-1306이 결국 공식화하게 될 형태이기도 합니다. 지금 이런 방식으로 구축해 두면, 사양(spec)이 확정되었을 때(만약 그렇다면) 마이그레이션 과정은 대략 다음과 같습니다: 직접 만든 업로드 엔드포인트를 사양에 정의된 엔드포인트로 교체하고, 나머지는 그대로 유지하는 것입니다. 또한 이는 제가 처음부터 시작했어야 했던 방식이기도 합니다. 프로토콜이 애초에 실어 나를 계획조차 없었던 바이트를 실어 나르도록 설득하는 데 첫날을 허비하는 대신 말입니다.
파일 워크플로우를 위해 MCP 도입을 결정하기 전 5초 체크리스트
- 상위 API가
multipart/form-data를 필요로 합니까? 그렇다면 MCP는 전송 계층(transport)이 아니라 _제어 평면(control plane)_입니다. 하단에 객체 스토리지를 연결하십시오. - MCP 서버가 컨테이너화되어 있습니까? 그렇다면
MCP는 훌륭한 제어 평면(control plane)입니다. 하지만 파일 전송(file transport) 수단은 아닙니다. 2026-07-28 릴리스 후보(release candidate)는 다음 릴리스 사이클에서도 이 점을 확인해 줍니다. 만약 파일 작업이 여러분의 에이전트(agent)의 핵심 경로(critical path) — 비용 처리, 티켓 첨부 파일, PR 스크린샷, Notion 업로드 등 — 에 있다면, 지금 당장 객체 스토리지(object storage)와 가벼운 서버 측 페처(server-side fetcher)가 필요합니다. 프로토콜의 향후 FileContent 도입은 로드맵 상의 의존성(roadmap dependency)이 아니라, 가능한 미래의 정리 작업(cleanup)으로 취급하십시오.
7개 서비스 테스트 결과는 명세(spec)를 직접 살펴보기 전까지는 벤더(vendor)의 문제처럼 보입니다. 하지만 명세를 보고 나면, 이는 7개의 다운스트림(downstream) 피해자를 발생시킨 명세의 문제로 읽힙니다. 여러분이 해결하려는 것이 무엇인지 아는 것이 중요합니다.
체계적인 버전을 원하신다면 — 제가 테스트한 모든 MCP 서버, 정확한 실패 모드(failure modes), OWASP MCP Top 10, 그리고 코드가 포함된 프로덕션 레퍼런스-낫-바이트(reference-not-bytes) 패턴까지 — 이에 대해 일본어로 책을 썼습니다: MCP Security in Practice (Impress).
참고 문헌
- SEP-1306: 파일 업로드를 위한 바이너리 모드 유도 (Binary Mode Elicitation for File Uploads)
- SEP-2356: 도구를 위한 파일 입력 지원 및 유도 (File input support for tools and elicitation (PR))
- 2026-07-28 MCP 명세 릴리스 후보 (2026-07-28 MCP Specification Release Candidate)
- mcp-atlassian Issue #618 — Docker 파일 시스템 문제 (Docker filesystem issue)
- github-mcp-server Issue #738 — PR 이미지 업로드 (PR image upload)
- MCP Discussion #1197 — 현재 프로토콜의 한계 (current protocol limitation)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기