CH 12 · MCP 생태계에 연결하기
본장 목표
dsh의 내장 도구(파일 읽기, 명령 실행, 웹 검색)만으로도 일상적인 사용에는 충분하지만, 바깥 세상에는 흘어져 있는 도구가 너무 많습니다 — GitHub, 데이터베이스, 메모리, 브라우저, 각종 SaaS — 이들이 저절로 Agent에 들어오지는 않습니다. 이번 장에서는 MCP 생태계를 연결합니다. 먼저 MCP가 무엇인지, 왜 dsh가 "플러그인"으로 연결하는지 설명하고, 이어서 Firecrawl MCP 서버를 직접 실습으로 붙여 모델이 마치 내장 도구처럼 그것의 도구들을 호출할 수 있도록 합니다.
먼저 이해하기: MCP란 무엇인가
**MCP (Model Context Protocol)**는 "AI 애플리케이션이 외부 도구 서버에 어떻게 연결되는가"라는 일반적인 문제를 푸는 개방형 프로토콜입니다. MCP를 도구 세상의 USB-C라고 생각하시면 됩니다. 표준 인터페이스가 있고, 어떤 장치든 꽂을 수 있습니다.
MCP 생태계에는 이미 많은 MCP 서버가 준비되어 있습니다.
| MCP 서버 | 하는 일 |
|---|---|
| 파일 시스템 (File system) | 하위 디렉터리를 읽기/쓰기 (로컬 디렉터리를 Agent에 노출) |
| GitHub | 이슈 생성, PR 올리기, 리포지토리 조회 |
| 데이터베이스 (Database) | 각종 데이터베이스 조회 |
| 메모리 (Memory) | 장기 기억 접근 (CH 14에서 다시 만납니다) |
| 브라우저 (Browser) | 브라우저 제어, 페이지 스크레이핑 |
MCP를 dsh에 꽂는 방식은 dsh의 스타일 그대로입니다 — 플러그인 하나: @deepseek-ai/dsh-mcp-client. 이 공식 플러그인의 역할은 순수합니다. 선언한 모든 MCP 서버에 연결하고, 그 서버들이 제공하는 도구들을 ctx.tools에 등록합니다 (CH 11에서 다룬 도구 레지스트리). 모델의 눈에는 내장 도구와 다를 바가 없습니다. 이는 다시 한 번 CH 08의 "모든 것은 플러그인"을 확인시켜 줍니다 — MCP 통합도 예외가 아닙니다.
사전에 알아 두어야 할 점이 몇 가지 있습니다.
- 도구 이름은 두 단계로 구성됩니다: 먼저 MCP 서버(예: Firecrawl)가 있고, 그 아래에 도구들이 여러 개 붙습니다(
firecrawl_scrape페이지 스크레이핑,firecrawl_search페이지 검색,firecrawl_map사이트 맵 나열 등). 연결 후에는 각 도구가mcp__<서버 이름>__<도구 이름>형태로 나타납니다 — 서버 이름이firecrawl이면 scrape 도구는mcp__firecrawl__firecrawl_scrape입니다. 이는 Claude Code와 Codex의 명명 형식과 같습니다. 서버가 달라 이름이 겹쳐도 (각각 고유 접두사를 가지므로) 충돌하지 않습니다. - 기본으로는 어떤 서버도 활성화되지 않습니다: 플러그인이 설치되어 있는지 여부와, 어떤 서버에 연결할지는 전적으로 사용자의 선언에 달려 있습니다. 설정이 없으면 아무것도 연결하지 않습니다. 선언이 되어 있으면 dsh가 시작할 때 서버가 연결되고 도구들이 도구 목록에 등록됩니다. 어떤 라운드에서 어떤 도구를 부를지는 모델이 현재 작업에 맞춰 스스로 정합니다 — 매번 모든 도구를 호출하지는 않습니다.
- 현재는 "도구"만 브리지됩니다: MCP 프로토콜에는 "도구(Tool, 호출 가능한 동작)" 외에 두 가지 능력이 더 있습니다 — "리소스(Resource, 읽기 전용 데이터와 파일)"와 "프롬프트 템플릿(Prompt)". dsh의 브리지 플러그인은 현재 "도구"만 가져오며, 리소스와 프롬프트 템플릿은 아직 사용할 수 없습니다.
- 많은 서버는 인증을 요구합니다: GitHub, Firecrawl처럼 실제 서비스에 연결하는 MCP 서버는 보통 API Key나 토큰을 요구합니다. 키는 설정의
headers필드(HTTP 방식)로 전달하며, 설정 파일에 직접 하드코딩하지 마십시오 — 자세한 사항은 아래 설정 절에서 다룹니다.
직접 해보기: 첫 MCP 서버 — Firecrawl 연결
아래에서는 Firecrawl (Firecrawl 웹사이트)을 예로 들어 진행합니다. Firecrawl은 실재 웹 스크레이핑 MCP 서비스이며, 일련의 웹 도구를 제공합니다. firecrawl_scrape (단일 페이지 스크레이핑), firecrawl_search (웹 검색), firecrawl_map (사이트 맵 나열), firecrawl_crawl (사이트 전체 크롤링), firecrawl_extract (구조화된 필드 추출) 등이 있습니다.
1단계: MCP 클라이언트 플러그인이 자리잡았는지 확인
먼저 dsh-mcp-client가 있는지 확인합니다. 명령줄은 필요 없습니다. Web UI의 플러그인 목록에서 직접 확인합니다. Settings → Plugins을 열고 mcp를 검색합니다. 아래 그림은 제 검색 결과로, 검색창에 mcp를 입력한 후 플러그인 목록이 비어 있습니다("일치하는 플러그인이 없습니다"). 즉, 설치되지 않은 상태입니다.

목록에서 찾을 수 없다면, 명령줄로 돌아가 web 프로필의 의존성으로 설치합니다.
dsh plugin --profile web add @deepseek-ai/dsh-mcp-client참고: 이 명령은 단지 프로필에 패키지로 들어갈 뿐이고 (dsh plugin list --profile web에 의존성으로 표시됨), 스스로는 시작되지 않습니다 — 플러그인이 실제로 로드되도록 하려면 3단계에서 cordis.patch.yml에 삽입하고 서버를 설정해야 합니다. 실제 시험에서 나온 함정이 하나 있습니다. 플러그인만 삽입하고 서버 설정이 비어 있으면, dsh는 시작 시 곧바로 Cannot read properties of undefined (reading 'serverName') 오류를 보고합니다. serverName이 필수 필드이기 때문입니다.
설정과 dsh 재기동을 거친 뒤 Settings → Plugins로 다시 가면 mcp-client가 보이고 상태는 "enabled"입니다 (아래 그림은 설치 후 모습으로, 검색창에는 여전히 mcp가 입력되어 있고, 플러그인 목록 1건, 상태는 enabled).

2단계: Firecrawl API Key 받기
Firecrawl은 인증이 필요합니다. Firecrawl 웹사이트에 로그인해 등록하고 API Key를 만듭니다. 공식 사용 방식은 Bearer 토큰으로 https://mcp.firecrawl.dev/v2/mcp에 보내는 것입니다. 무료 등급은 매월 1000 크레딧입니다.
아래 그림은 키를 만든 페이지입니다. 왼쪽에 남은 크레딧이 보이고, 가운데 기본 키(fc- 접두사, 중간 마스킹)가 있으며, 우상단에 + Create 버튼이 있습니다.

키를 받은 뒤, 우선 시스템 환경 변수로 설정합니다 (3단계 설정에서 참조할 것입니다). 한 가지 분명히 해 두겠습니다. 환경 변수는 텍스트 파일에 적는 것이 아닙니다. Windows 시스템 UI에서 일괄 관리되는 "목록"이고, 설정 화면은 이 목록에 항목을 추가합니다. Windows에서는 GUI로 진행하며, 명령은 필요 없습니다.
Win키를 누르고 "환경 변수"를 입력해 시스템 환경 변수 편집을 엽니다.- 우하단의 환경 변수 (Environment Variables) 버튼을 클릭합니다.

- 사용자 변수 섹션에서 새로 만들기를 클릭합니다. 변수 이름에
FIRECRAWL_API_KEY, 변수 값에fc-your-full-key를 입력합니다.

- 확인을 끝까지 눌러 창을 닫습니다.
참고: 설정 후 새 터미널을 열어 dsh를 시작하십시오 — 이미 열려 있던 창은 새로 설정한 환경 변수를 자동으로 읽지 않습니다.
3단계: 프로필 설정에 Firecrawl 선언
MCP 서버 설정은 web 프로필의 패치 파일 (CH 08의 cordis.patch.yml)에 작성합니다.
- Windows:
C:\Users\<사용자 이름>\.dsh\profiles\web\cordis.patch.yml - macOS / Linux:
~/.dsh/profiles/web/cordis.patch.yml
insert 목록에 서버를 추가합니다. 공식 추천 방식인 streamable-http 방식 (원격 엔드포인트에 연결)을 사용합니다.
각 insert 항목에서
serverName은 필수입니다 (1단계의 시작 오류는 이것이 비어 있어서였습니다) — 도구 이름의 네임스페이스이며,mcp__<여기>__도구의 모양을 결정합니다.
Firecrawl의 공식 원격 엔드포인트는 https://mcp.firecrawl.dev/v2/mcp이며, Bearer 토큰으로 인증합니다.
- insert:
- id: mcp-firecrawl
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: firecrawl
transport: streamable-http
url: https://mcp.firecrawl.dev/v2/mcp
headers:
Authorization: !!js '`Bearer ${process.env.FIRECRAWL_API_KEY}`'키는 환경 변수(process.env.FIRECRAWL_API_KEY)를 통해 참조하며, 파일에 직접 적지 않습니다 (환경 변수 설정 방법은 2단계 참조) — 한 번 Git에 커밋되면 새어나갈 수 있습니다. 나중에 다른 MCP 서버를 꽂을 때도 이 형식으로 insert 항목만 하나 더 추가하면 됩니다.
자주 쓰이는 필드 설명은 다음과 같습니다.
| 필드 | 의미 |
|---|---|
serverName | 도구 이름의 네임스페이스 (mcp__<여기>__도구), 1–32자의 영숫자와 언더스코어, 스코프 내에서 유일해야 함 |
transport | stdio (로컬 프로그램) 또는 streamable-http (원격 서비스) |
command / args / env | stdio의 실행 파일, 인수, 추가 환경 변수 |
url / headers | HTTP 엔드포인트 주소와 추가 요청 헤더 (인증 토큰은 여기에) |
toolCallTimeoutMs | 도구 호출당 타임아웃 (기본 60초) |
reconnect | 끊겼을 때 자동 재연결 정책 (기본 활성화, 500ms 초기 백오프에서 2배 증가, 30초 상한, 연속 10회 실패 후 포기) |
편집해서 저장한 뒤 파일은 이런 모습입니다 — 새로 추가된 insert 구간이 강조 표시되어 있습니다.
4단계: 재기동하고 모델이 호출하게 하기
dsh를 다시 열고, 시작이 완료될 때까지 기다립니다. Firecrawl의 도구에는 그것을 볼 수 있는 전용 "도구 목록 페이지"가 없습니다. 확인하는 가장 직접적인 방법은 모델이 한 번 사용하게 하는 것입니다.
- 세션에서 이렇게 보냅니다:
Firecrawl을 사용해 deepseek.com의 메인 내용을 스크레이핑해 줘 - 모델의 응답과 트래젝토리를 지켜봅니다. 연결이 성공하면 모델이
mcp__firecrawl__firecrawl_scrape를 호출하고, 트래젝토리에 TOOL 행이 나타나며, 오른쪽 패널에url매개변수와 스크레이핑해 온 markdown 결과가 표시됩니다.


- 도구가 들어오지 않으면, 모델은 명시적으로 "이곳에는 그 스크레이핑 도구가 없다"고 말하거나, 단순히 내장 웹 검색으로 돌아갑니다. 둘 다 서버가 연결되지 않았다는 뜻이니, 앞 절로 돌아가 원인을 확인합니다.
번거로움을 줄이고 싶다면: 커뮤니티 플러그인 두 개 설치
공식 빌드에는 "도구 목록" 페이지도 "플러그인 탐색" 진입점도 없습니다. 커뮤니티에서 이 두 자리를 채웠고, 둘 다 명령 하나로 설치됩니다.
① 플러그인 마켓 dsh-market (987 stars): 설치 후 Settings에 새 "Plugin Market"이 생기고, 분류별로 둘러보거나 검색하거나 커뮤니티 플러그인을 원클릭으로 설치할 수 있습니다. 마켓을 통해 설치한 플러그인은 대부분 페이지를 새로 고치면 곧바로 적용되며, dsh 재시작이 필요 없습니다.
dsh plugin --profile web add dshmarket
② MCP 시각화 패널 DSH Skill & MCP Panel (108 stars): 설치 후 Settings에 새 "MCP Management"가 생깁니다. 각 서버의 상태와 도구 개수가 바로 보이며, 추가/삭제/편집과 시작/정지를 모두 UI에서 할 수 있어 cordis.patch.yml을 직접 편집할 필요가 없습니다. 명령을 칠 필요 없이, 마켓 ①에서 dsh-skill-mcp-panel을 직접 검색해 원클릭으로 설치하고 페이지를 새로 고치면 적용됩니다 (호스트 단계 일부 플러그인은 "재시작 필요"가 표시될 수 있는데, 안내를 따르면 됩니다).

이 두 플러그인이 정확히 이번 장 첫머리에서 언급한 "모든 것은 플러그인"의 각주입니다 — 공식 UI에 없는 기능을 커뮤니티 플러그인이 채우고, 한 번 설치되면 dsh의 일부가 됩니다.
플러그인의 설치와 관리에는 더 많은 내용이 있습니다 — 명령줄 설치, 번들 자동 마운트, 전역 vs 프로필. 이번 장에서는 MCP 시나리오에서 창문만 열었을 뿐이며, 뒤에서 한 장을 통째로 플러그인 설치를 다룬 뒤 플러그인 개발로 이어지고, 그 다음 시나리오 실습까지 곧장 연결됩니다.
자주 묻는 질문
| 문제 | 처리 방법 |
|---|---|
| 연결했는데 도구가 안 보이나요? | 먼저 로그에서 연결/디스커버리 오류를 확인하고, 서버 자체에 도달 가능한지 (브라우저나 curl로 엔드포인트를 직접 시험해) 확인하며, serverName이 다른 서버와 충돌하지 않는지 확인합니다. 인증이 필요한 서버라면 키가 제대로 전달되었는지 확인합니다 (401/403이 보통 이 경우) |
| Firecrawl 같은 서비스의 키는 어디에 두나요? | 설정의 headers로 전달하며 (HTTP 방식), 시작 전에 키를 환경 변수로 설정합니다 (2단계). cordis.patch.yml에 직접 적지 마십시오 — Git에 커밋되면 새어나갈 수 있습니다 |
| 서버가 죽으면 어떻게 되나요? | 플러그인이 자동 재연결합니다 (500ms 초기 백오프에서 2배 증가). 재연결 중에는 도구가 계속 목록에 표시되지만 호출은 실패하며, 연속 10회 실패 후에는 설정 다시 불러오기 또는 재시동 전까지 도구가 제거됩니다. 설정을 편집하면 서버 연결이 그 자리에서 다시 로드되며, 변하지 않은 이름은 그대로 유지됩니다 |
| 토큰을 너무 많이 소모하나요? | 모든 서버의 도구 설명과 입력 schema가 매 요청마다 들어옵니다. 실제로 쓰는 것만 연결하고, 잔뜩 모아 두지 마십시오 |
이번 장에서 배운 것
다음 항목들을 스스로 완수할 수 있으면 합격입니다.
- [ ] MCP가 무엇을 하는지, dsh가 어떻게 그것에 연결하는지 (플러그인 하나
dsh-mcp-client) 설명할 수 있다 - [ ] 도구 이름이 두 단계라는 것을 안다: 한 MCP 서버 아래에 도구가 여러 개 있고, 연결 후에는
mcp__서버 이름__도구 이름형태로 나타난다 - [ ] 인증이 필요한 MCP 서버 (Firecrawl 등)의 키가 어떻게 전달되는지, 왜 설정 파일에 직접 적지 않는지 안다
- [ ]
cordis.patch.yml에서 MCP 서버를 선언할 수 있다 (stdio 또는 streamable-http 중 최소 하나) - [ ] 모델이 실제로 MCP 도구를 호출하게 하고, 트래젝토리에서
mcp__접두사가 붙은 호출을 본다 - [ ] 서버가 연결에 실패하거나 죽었을 때, 어디에서 오류를 찾고 어떻게 문제를 해결하는지 안다
- [ ] 편의를 위해 두 개의 커뮤니티 플러그인을 설치할 수 있다는 것을 안다: dsh-market (Plugin Market) 및 DSH Skill & MCP Panel (MCP 시각화)

