본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 02. 02:04

아무도 당신의 MCP 서버를 설치하지 않습니다. 설치하는 사람들조차 사용하지 않습니다.

요약

MCP(Model Context Protocol) 서버 개발 시 겪는 설치 마찰과 사용자 이탈 문제를 분석합니다. 기술적 연결 성공보다 사용자가 실제 도구 호출(Tool call)로 이어지게 만드는 '두 번째 설치'의 중요성을 강조합니다.

핵심 포인트

  • 설치 경로는 단순 마케팅이 아닌 엔지니어링의 영역임
  • 연결 성공 후 실제 도구 호출로 이어지는 전환율이 매우 낮음
  • 사용자가 서버의 기능을 인지하게 만드는 '두 번째 설치'가 핵심
  • 클라이언트 환경을 통제할 수 없는 MCP의 구조적 한계 인지 필요

원문은 the Remoet blog에 게시되었습니다.

당신은 MCP (Model Context Protocol) 서버를 작성했습니다. 30개의 도구(tools)가 있고, 제대로 작동합니다. 몇몇 디렉토리에 게시했고, 아마 트윗도 하나 남겼을 것입니다. 하지만 아무도 이를 설치하지 않습니다.

여기 아무도 말해주지 않는 사실이 있으며, 이는 설치 문제보다 더 심각합니다. 설치를 하는 사람들 중에서도 거의 아무도 그것을 사용하지 않습니다. 그들은 연결하고, 다시 자신의 도구로 돌아와, 빈 프롬프트(prompt) 박스를 응시하다가 떠나버립니다. 당신은 하나의 채택(adoption) 문제를 겪은 것이 아닙니다. 두 가지 문제를 겪은 것이며, 두 번째 문제는 아무도 해결하려 하지 않는 문제입니다.

우리는 Remoet의 MCP 서버를 5번의 반복(iterations)을 거쳐 출시하며, 사람들이 "소문을 듣는 단계"에서 "에이전트(agent)가 유용한 호출(call)을 수행하는 단계"까지 가는 과정을 지켜보았습니다. 대부분은 도달하지 못했습니다. 손실의 일부는 설치 자체에서 발생하며, 이는 진정으로 어려운 일이고 이 글의 주요 주제이기도 합니다. 하지만 우리를 놀라게 했던, 우리가 아무런 대비도 하지 않았던 이탈은 연결이 성공한 직후에 발생합니다. 기술적인 설치는 당신의 서버를 연결해 줍니다. 두 번째 설치는 사용자의 머릿속에 그 기능을 심어줍니다. 거의 모든 이들이 첫 번째 설치는 구현하지만, 두 번째 설치는 무시합니다.

설치 마찰(Install friction)이 곧 제품이다

대부분의 사람들은 배포(distribution)를 엔지니어링이 끝난 후에 시작되는 마케팅 문제로 취급합니다. 그렇지 않습니다. 당신의 서버에 대해 듣는 것부터 유용한 도구 호출(tool call)을 얻어내는 것 사이의 모든 단계는 엔지니어링이며, 만약 어느 한 단계라도 적대적(hostile)이라면 사용자는 이탈합니다. 설치 경로(install path)는 하나의 제품입니다. 당신은 그것을 설계하고, 구축하고, 사람들이 그 경로를 통과하는 것을 지켜보며, 그들이 넘어지는 지점을 수정해야 합니다. 우리는 우리의 문제가 "더 많은 디렉토리에 등록되어야 한다"는 것이라고 가정했습니다. 그렇지 않았습니다. 누군가 우리를 찾아냈을 때조차, 우리가 측정조차 하지 않았던 대여섯 단계의 경로에서 사용자들이 유출되고 있었습니다.

우리의 퍼널 (Funnel) 데이터가 그 형태를 보여주고 있습니다. 솔직히 말씀드리면 에이전트 경로 (Agent path)는 새로운 것이라 절대적인 수치는 작습니다. 하지만 그 형태가 바로 교훈입니다. 여러분을 겁나게 해야 할 지점은 시작이 아니라 끝입니다. 우리의 연결 (Connect) 화면에 도달한 사람들 중, 단 한 번의 도구 호출 (Tool call)이라도 발생시킨 사람은 절반도 되지 않았습니다. 일부는 작동 여부를 알 수 없었습니다. 대부분은 문제없이 연결되었지만, 그저 서버에 할 말이 없었습니다. 그들은 접속했지만, 그 이후에는 아무 일도 일어나지 않았습니다. 이것은 더 많은 디렉토리나 더 나은 트윗으로 메울 수 있는 누출 (Leak)이 아닙니다. 이것은 두 번째 설치 (Second install)의 문제이며, 우리는 그것을 위해 아무것도 구축하지 않았습니다.

이것이 진정으로 어려운 이유

MCP 설치가 어려운 이유는 구조적입니다: 당신은 설치가 일어나는 표면 (Surface)을 소유하지 않습니다. 당신의 서버는 당신의 인프라 (Infrastructure)에 존재합니다. 하지만 설치는 다른 누군가의 클라이언트 (Client) 내부에서, 당신이 한 번도 본 적 없는 설정 파일 (Config file)에, 당신이 점검할 수 없는 머신 (Machine) 위에서 일어납니다. 당신은 자신이 서 있지 않은 방에 대한 지침을 전달하고 있는 셈입니다. 바로 이 지점에서 문제가 발생합니다.

N×M 문제. N개의 클라이언트 (Claude Desktop, Claude Code, Claude Web, Cursor, Windsurf, VS Code, OpenClaw, 그리고 매달 추가되는 더 많은 클라이언트들)와 M개의 서버가 있습니다. 각 클라이언트는 약간씩 다른 설정 형태 (Config shape), 다른 위치의 다른 파일, 그리고 인증 (Auth)이 작동하는 방식에 대한 서로 다른 개념을 원합니다. 당신은 M개 중 하나이며, N개 모두를 위해 자신을 올바르게 문서화하라는 요구를 받고 있습니다.

다음은 세 가지 서로 다른 클라이언트를 위한 동일한 서버(저희의 서버)의 예시입니다. Claude Code는 터미널 명령어를 원합니다:

claude mcp add remoet https://api.remoet.dev/mcp --scope user --transport http --header "Authorization: Bearer YOUR_KEY"

Cursor는 ~/.cursor/mcp.json에 있는 JSON을 원합니다:

{ "mcpServers": { "remoet": { "type": "http", "url": "https://api.remoet.dev/mcp", "headers": { "Authorization": "Bearer YOUR_KEY" } } } }

Codex는 ~/.codex/config.toml에 있는 TOML을 원합니다:

[mcp_servers.remoet]
url = "https://api.remoet.dev/mcp"
http_headers = { "Authorization" = "Bearer YOUR_KEY" }

동일한 서버입니다. 세 가지 형식, 세 가지 위치. 그리고 JSON 형식 내부로 들어가면 상황은 더 악화됩니다. URL을 담는 필드 이름이 Cursor에서는 url, Windsurf에서는 serverUrl, Gemini CLI에서는 httpUrl이며, 래퍼 객체(wrapper object)는 대부분 mcpServers이지만 VS Code에서는 servers이기 때문입니다. 필드 이름을 하나라도 틀리면 사용자는 어느 줄에서 오류가 발생했는지에 대한 힌트도 없이 조용히 실패(silent failure)를 경험하게 됩니다. 우리는 이 중 9개를 유지 관리하고 있습니다. 대부분의 서버는 그중 하나만 문서화하고 나머지 8개에서는 모든 사용자를 놓치고 있습니다.

The Remoet onboarding panel: a pre-filled masked API key above nine per-client config tabs

키는 이미 발행되어 필드 안에서 마스킹된 채 기다리고 있습니다. 그 아래에는 9개의 클라이언트 탭이 있습니다. 설정의 형태(config shape), 파일 경로, 심지어 필드 이름조차 각각 다릅니다. 우리는 사용자가 신경 쓰지 않도록 이 변환 작업을 단 한 번 수행합니다.

인증의 분기점 (The auth fork). API 키, OAuth, 또는 인증 없음. 각 클라이언트는 이를 다르게 처리하며

설치 경로를 README 섹션이 아닌 실제 페이지로 만드세요. JSON 스니펫이 포함된

그 결정적인(CRITICAL) 한 줄은 인간을 위한 것이 아닙니다. 모델이 호출 시점에(call time) 그것을 읽고 더 잘 동작하도록 하기 위해 존재하는 것입니다. 모든 설명을 마치 에이전트(agent)가 유일한 독자라는 듯이 작성하세요. 실제로 대부분의 경우 그렇기 때문입니다.

그리고 조용히 중요했던 한 가지는 바로 Claude Web과 같은 비기술적 클라이언트(non-technical clients)를 위한 OAuth였습니다. 이를 통해 사용자들이 "API 키"라는 단어를 한 번도 접하지 않고도 연결할 수 있게 했습니다. 이전에는 API 키 방식만을 사용했기에 사용자들을 모두 놓치고 있었습니다.

두 번째 설치

당신이 다섯 가지 요소를 모두 제대로 수행했다고 가정해 봅시다. 사용자가 연결하고, 초록색 체크 표시를 확인한 뒤, 다시 자신의 도구로 돌아갑니다. 이제 무엇을 해야 할까요?

아무것도 없습니다. 그것이 문제입니다.

사용자는 항상 보던 것과 똑같은 빈 프롬프트 박스를 응시하고 있습니다. 다만 이제 그 뒤에는 에이전트가 언급하지 않을 새로운 기능(capability)이 숨겨져 있을 뿐입니다. 모델은 "방금 작업 서버를 연결했습니다. 제가 몇몇 기업을 찾아드릴까요?"라고 공지하지 않습니다. 모델에게는 '첫 실행(first-run)'이라는 개념이 없습니다. 모델은 당신의 서버가 새로 추가되었다는 사실을 알지 못합니다. 아무것도 제안하지 않을 것입니다. 사용자 입장에서는 눈에 띄게 변한 것이 아무것도 없습니다. 그들은 모든 설치 작업을 마쳤지만 아무런 보상을 얻지 못했습니다. 왜냐하면 연결은 활성화되어 있지만, 사용자가 당신의 도구가 수행하는 정확한 작업을 모델이 도구를 사용하기로 결정할 만큼 근접한 단어로 요청하기 전까지는 완전히 비활성(inert) 상태이기 때문입니다.

이것이 바로 '두 번째 설치'이며, 거의 아무도 출시하지 않는 단계입니다. 이것이 잔혹한 이유는 정확히 사용자가 보상을 기대하는 순간에 발생하기 때문입니다. 그들은 당신의 지침을 따랐고, 눈에 보이는 설치를 마쳤지만, 돌아온 보상은 빈 채팅창이었습니다. 기능은 연결되었습니다. 다만 사용자의 머릿속에 아직 설치되지 않았을 뿐이며, 그 설치의 책임은 당신에게 있습니다.

당신이 원하는 방식으로는 이를 해결할 수 없습니다. 당신은 채팅창의 소유자가 아닙니다. 타인의 도구에 환영 메시지나 "이것부터 시도해 보세요"라는 카드(card)를 주입할 수 없습니다. MCP는 클라이언트에게 당신의 도구를 전달할 뿐, 대화의 첫 번째 턴(first turn)을 전달하는 것이 아닙니다. 그 턴은 사용자의 것이며, 지금 당장 그들은 할 말이 아무것도 없습니다.

그래서 모두가 똑같이 조잡한 방식으로 이 문제를 해결합니다. 설치 과정 어딘가에서 사용자에게 스타터 프롬프트 (starter prompt)를 복사하게 하고, 도구에 접속하자마자 그것을 다시 붙여넣으라고 말하는 것이죠. 그렇게 붙여넣은 프롬프트가 전체적인 첫 실행 경험 (first-run experience)이 됩니다. 그것이 장벽 너머에서 당신이 휘두를 수 있는 유일한 레버 (lever)입니다. 우리의 온보딩 (onboarding)도 정확히 이 방식을 따릅니다. 페이지에서 바로 붙여넣을 수 있는 프롬프트를 생성하며, 그 핵심 내용은 다음과 같습니다:

get_profile을 사용하여 내 프로필을 읽어줘. 만약 비어 있다면, 나의 기술 스택 (tech stack), 경력, 그리고 어떤 종류의 역할을 원하는지 나에게 물어봐 줘. 내가 말하는 내용으로 내 프로필을 업데이트해 줘. 그런 다음 내 스택과 일치하는 기업을 검색하고 가장 적합한 곳에 별표(star)를 표시해 줘.

모든 절(clause)은 제 자리를 찾아가며 작성되었습니다. 도구의 정확한 이름(get_profile)을 명시함으로써 모델이 존재 여부를 추측하는 대신 해당 도구를 호출하도록 합니다. 빈 상태 (empty state)에 따라 분기 처리하여, 신규 사용자는 온보딩을 받고 기존 사용자는 다시 질문 공세를 받지 않게 합니다. 그리고 사용자가 실제로 원했던 작업으로 체인 (chain)을 연결합니다. 이것은 조잡한 해킹 (hack)이자 유일하게 작동하는 방법이며, 두 가지 측면에서 보상을 제공합니다. 사용자는 기능이 작동하는 것을 목격하고, 예시를 통해 다음에 무엇을 물어봐야 할지 배우게 됩니다. 이것은 설정 블록 (config block)만큼이나 중요한 지지 구조 (load-bearing)이지만, 거의 아무도 그렇게 취급하지 않습니다.

The

기본값은 에이전트 (agent)를 연결하고 프로필을 설정하는 하나의 프롬프트입니다. 수동 클라이언트별 설정은 공개 사항일 뿐, 주요 경로가 아닙니다. 두 번째 설치, 배송 완료.

하지만 스타터 프롬프트는 첫 번째 턴 (first turn)만을 점유합니다. 이를 넘어선 단계가 있으며, 이는 이 분야 전체에서 가장 과소평가된 기술입니다. 단순히 사용자에게 '지금 당장' 사용할 프롬프트를 건네주는 것에 그치지 마세요. 에이전트의 규칙 파일, 즉 에이전트가 매 세션 시작 시 읽는 CLAUDE.md.cursorrules에 들어갈 한 줄을 건네주어야 합니다. 우리의 파일에는 다음과 같이 적혀 있습니다:

내가 구직, 기업 조사, 지원, 거절, 오퍼(offers), 또는 내 기술 스택(tech stack)의 변경에 대해 언급할 때, Remoet MCP 서버를 사용하세요. 이 규칙을 프로젝트 로컬(project-local)이 아닌 전역/사용자 수준(global/user-level) 규칙 파일에 저장하여 모든 세션에서 유지되도록 하세요.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0