MCP 서버 개발 프로토콜
🚀 MCP 서버를 구축하고 전 세계와 공유하십시오. 훌륭한 MCP 서버를 만들었다면 Caret MCP 마켓플레이스에 제출하여 수천 명의 개발자가 검색하고 원클릭으로 설치할 수 있도록 하십시오.
MCP 서버란 무엇인가요?
MCP(Model Context Protocol) 서버는 AI 비서인 Cline의 기능을 확장하여 다음을 수행할 수 있도록 합니다.
- 외부 API 및 서비스 액세스
- 실시간 데이터 검색
- 애플리케이션 및 로컬 시스템 제어
- 텍스트 프롬프트만으로는 달성할 수 없는 작업 수행
MCP가 없으면 AI 비서는 강력하지만 고립됩니다. MCP를 사용하면 사실상 모든 디지털 시스템과 상호 작용할 수 있는 능력을 얻습니다.
개발 프로토콜
효과적인 MCP 서버 개발의 핵심은 구조화된 프로토콜을 따르는 것입니다. 이 프로토콜은 MCP 작업 디렉토리의 루트(/Users/your-name/Documents/Caret/MCP)에 있는 .clinerules
파일을 통해 구현됩니다.
.clinerules
파일 사용
.clinerules
파일은 Cline이 배치된 디렉토리에서 작업할 때 자동으로 읽는 특수 구성입니다. 이러한 파일은 다음을 수행합니다.
- Cline의 동작 구성 및 모범 사례 적용
- Cline을 특수 MCP 개발 모드로 전환
- 서버 구축을 위한 단계별 프로토콜 제공
- 시기상조 완료 방지와 같은 안전 조치 구현
- 계획, 구현 및 테스트 단계를 안내
다음은 .clinerules
파일에 배치해야 하는 완전한 MCP 서버 개발 프로토콜입니다.
# MCP 서버 개발 프로토콜
⚠️ 중요: 테스트하기 전에 attempt_completion을 사용하지 마십시오 ⚠️
## 1단계: 계획 (계획 모드)
- 이 도구가 해결하는 문제는 무엇입니까?
- 어떤 API/서비스를 사용할 것입니까?
- 인증 요구 사항은 무엇입니까?
□ 표준 API 키
□ OAuth (별도의 설정 스크립트 필요)
□ 기타 자격 증명
## 2단계: 구현 (실행 모드)
1. 부트스트랩
- 웹 서비스, JavaScript 통합 또는 Node.js 환경의 경우:
```bash
npx @modelcontextprotocol/create-server my-server
cd my-server
npm install
```
- 데이터 과학, ML 워크플로 또는 Python 환경의 경우:
```bash
pip install mcp
# 또는 uv 사용 (권장)
uv add "mcp[cli]"
```
2. 핵심 구현
- MCP SDK 사용
- 포괄적인 로깅 구현
- TypeScript (웹/JS 프로젝트용):
```typescript
console.error("[설정] 서버 초기화 중...")
console.error("[API] 엔드포인트 요청:", endpoint)
console.error("[오류] 다음으로 실패:", error)
```
- Python (데이터 과학/ML 프로젝트용):
```python
import logging
logging.error('[설정] 서버 초기화 중...')
logging.error(f'[API] 엔드포인트 요청: {endpoint}')
logging.error(f'[오류] 다음으로 실패: {str(error)}')
```
- 유형 정의 추가
- 컨텍스트와 함께 오류 처리
- 필요한 경우 속도 제한 구현
3. 구성
- 필요한 경우 사용자로부터 자격 증명 가져오기
- MCP 설정에 추가:
- TypeScript 프로젝트용:
```json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["path/to/build/index.js"],
"env": {
"API_KEY": "key"
},
"disabled": false,
"autoApprove": []
}
}
}
```
- Python 프로젝트용:
```bash
# 명령줄로 직접
mcp install server.py -v API_KEY=key
# 또는 settings.json에서
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["server.py"],
"env": {
"API_KEY": "key"
},
"disabled": false,
"autoApprove": []
}
}
}
```
## 3단계: 테스트 (차단 ⛔️)
<thinking>
attempt_completion을 사용하기 전에 다음을 확인해야 합니다.
□ 모든 도구를 테스트했습니까?
□ 각 테스트에 대해 사용자로부터 성공을 확인했습니까?
□ 테스트 결과를 문서화했습니까?
어떤 답변이라도 "아니요"인 경우 attempt_completion을 사용해서는 안 됩니다.
</thinking>
1. 각 도구 테스트 (필수)
□ 유효한 입력으로 각 도구 테스트
□ 출력 형식이 올바른지 확인
⚠️ 모든 도구가 테스트될 때까지 진행하지 마십시오.
## 4단계: 완료
❗ 중지 및 확인:
□ 모든 도구가 유효한 입력으로 테스트되었습니다.
□ 각 도구의 출력 형식이 올바릅니다.
모든 도구가 테스트된 후에만 attempt_completion을 사용할 수 있습니다.
## 주요 요구 사항
- ✓ MCP SDK를 사용해야 합니다.
- ✓ 포괄적인 로깅이 있어야 합니다.
- ✓ 각 도구를 개별적으로 테스트해야 합니다.
- ✓ 오류를 정상적으로 처리해야 합니다.
- ⛔️ 완료 전에 테스트를 건너뛰지 마십시오.
이 .clinerules
파일이 작업 디렉토리에 있으면 Cline은 다음을 수행합니다.
- 구현 전에 서버를 설계하기 위해 계획 모드로 시작합니다.
- 실행 모드에서 적절한 구현 패턴을 적용합니다.
- 완료를 허용하기 전에 모든 도구 테스트를 요구합니다.
- 전체 개발 수명 주기를 안내합니다.
시작하기
MCP 서버를 생성하는 데는 몇 가지 간단한 단계만 필요합니다.
1. .clinerules
파일 생성 (🚨 중요)
먼저 위 프로토콜을 사용하여 MCP 작업 디렉토리의 루트에 .clinerules
파일을 추가합니다. 이 파일은 이 폴더에서 작업할 때 Cline이 MCP 개발 프로토콜을 사용하도록 구성합니다.
2. 명확한 설명으로 채팅 시작
구축하려는 내용을 명확하게 설명하여 Caret 채팅을 시작합니다. 다음 사항에 대해 구체적으로 설명하십시오.
- MCP 서버의 목적
- 통합하려는 API 또는 서비스
- 필요한 특정 도구 또는 기능
예시:
AlphaAdvantage 금융 API를 위한 MCP 서버를 구축하고 싶습니다.
실시간 주식 데이터를 가져오고, 기술 분석을 수행하고,
회사 재무 정보를 검색할 수 있어야 합니다.
3. 프로토콜을 통해 작업
Cline은 자동으로 계획 모드에서 시작하여 계획 프로세스를 안내합니다.
- 문제 범위 논의
- API 문서 검토
- 인증 방법 계획
- 도구 인터페이스 설계
준비가 되면 채팅 하단의 토글을 사용하여 실행 모드로 전환하여 구현을 시작합니다.
4. API 문서 조기에 제공
Cline이 MCP 서버를 구축하는 데 도움이 되는 가장 효과적인 방법 중 하나는 공식 API 문서를 시작할 때 바로 공유하는 것입니다.
서비스에 대한 API 문서는 다음과 같습니다.
[여기에 API 문서 붙여넣기]
포괄적인 API 세부 정보(엔드포인트, 인증, 데이터 구조)를 제공하면 Cline이 효과적인 MCP 서버를 구현하는 능력이 크게 향상됩니다.
두 가지 모드 이해
계획 모드
이 협업 단계에서는 Cline과 함께 MCP 서버를 설계합니다.
- 문제 범위 정의
- 적절한 API 선택
- 인증 방법 계획
- 도구 인터페이스 설계
- 데이터 형식 결정
실행 모드
계획이 완료되면 Cline이 서버 구현을 돕습니다.
- 프로젝트 구조 설정
- 구현 코드 작성
- 설정 구성
- 각 구성 요소 철저히 테스트
- 문서 최종화
사례 연구: AlphaAdvantage 주식 분석 서버
주식 데이터 분석 및 보고 기능을 제공하는 AlphaAdvantage MCP 서버의 개발 프로세스를 살펴보겠습니다.
계획 단계

계획 단계에서 우리는 다음을 수행했습니다.
- 문제 정의: 사용자는 AI 비서를 통해 직접 금융 데이터, 주식 분석 및 시장 통찰력에 액세스해야 합니다.
- API 선택: 금융 시장 데이터를 위한 AlphaAdvantage API
- 표준 API 키 인증
- 분당 5회 요청 제한(무료 티어)
- 다양한 금융 데이터 유형에 대한 다양한 엔드포인트
- 필요한 도구 설계:
- 주식 개요 정보(현재 가격, 회사 세부 정보)
- 지표를 사용한 기술 분석(RSI, MACD 등)
- 기본 분석(재무 제표, 비율)
- 수익 보고서 데이터
- 뉴스 및 감성 분석
- 데이터 서식 계획:
- 깔끔하고 잘 서식 지정된 마크다운 출력
- 구조화된 데이터용 테이블
- 추세에 대한 시각적 지표(↑/↓)
- 재무 숫자의 적절한 서식
구현

프로젝트를 부트스트랩하는 것으로 시작했습니다.
npx @modelcontextprotocol/create-server alphaadvantage-mcp
cd alphaadvantage-mcp
npm install axios node-cache
다음으로 프로젝트를 다음과 같이 구성했습니다.
src/
├── api/
│ └── alphaAdvantageClient.ts # 속도 제한 및 캐싱이 있는 API 클라이언트
├── formatters/
│ └── markdownFormatter.ts # 깔끔한 마크다운을 위한 출력 포맷터
└── index.ts # 메인 MCP 서버 구현
API 클라이언트 구현
API 클라이언트 구현에는 다음이 포함되었습니다.
- 속도 제한: 분당 5회 요청 제한 적용
- 캐싱: 전략적 캐싱으로 API 호출 감소
- 오류 처리: 강력한 오류 감지 및 보고
- 유형화된 인터페이스: 모든 데이터에 대한 명확한 TypeScript 유형
주요 구현 세부 정보:
/**
* 무료 티어(분당 5회 호출)를 기반으로 속도 제한 관리
*/
private async enforceRateLimit() {
if (this.requestsThisMinute >= 5) {
console.error("[속도 제한] 속도 제한에 도달했습니다. 다음 분을 기다리는 중...");
return new Promise<void>((resolve) => {
const remainingMs = 60 * 1000 - (Date.now() % (60 * 1000));
setTimeout(resolve, remainingMs + 100); // 100ms 버퍼 추가
});
}
this.requestsThisMinute++;
return Promise.resolve();
}
마크다운 서식
재무 데이터를 아름답게 표시하기 위해 포맷터를 구현했습니다.
/**
* 회사 개요를 마크다운으로 서식 지정
*/
export function formatStockOverview(overviewData: any, quoteData: any): string {
// 데이터 추출
const overview = overviewData
const quote = quoteData["Global Quote"]
// 가격 변동 계산
const currentPrice = parseFloat(quote["05. price"] || "0")
const priceChange = parseFloat(quote["09. change"] || "0")
const changePercent = parseFloat(quote["10. change percent"]?.replace("%", "") || "0")
// 마크다운 서식 지정
let markdown = `# ${overview.Symbol} (${overview.Name}) - ${formatCurrency(currentPrice)} ${addTrendIndicator(priceChange)}${changePercent > 0 ? "+" : ""}${changePercent.toFixed(2)}%\n\n`
// 더 많은 세부 정보 추가...
return markdown
}
도구 구현
명확한 인터페이스로 5가지 도구를 정의했습니다.
server.setRequestHandler(ListToolsRequestSchema, async () => {
console.error("[설정] 사용 가능한 도구 나열")
return {
tools: [
{
name: "get_stock_overview",
description: "주식 기호에 대한 기본 회사 정보 및 현재 시세 가져오기",
inputSchema: {
type: "object",
properties: {
symbol: {
type: "string",
description: "주식 기호 (예: 'AAPL')",
},
market: {
type: "string",
description: "선택적 시장 (예: 'US')",
default: "US",
},
},
required: ["symbol"],
},
},
// 여기에 추가 도구 정의...
],
}
})
각 도구의 핸들러에는 다음이 포함되었습니다.
- 입력 유효성 검사
- 오류 처리가 포함된 API 클라이언트 호출
- 응답의 마크다운 서식
- 포괄적인 로깅
테스트 단계
이 중요한 단계에는 각 도구를 체계적으로 테스트하는 것이 포함되었습니다.
- 먼저 설정에서 MCP 서버를 구성했습니다.
{
"mcpServers": {
"alphaadvantage-mcp": {
"command": "node",
"args": ["/path/to/alphaadvantage-mcp/build/index.js"],
"env": {
"ALPHAVANTAGE_API_KEY": "YOUR_API_KEY"
},
"disabled": false,
"autoApprove": []
}
}
}
- 그런 다음 각 도구를 개별적으로 테스트했습니다.
-
get_stock_overview: AAPL 주식 개요 정보 검색
# AAPL (Apple Inc) - $241.84 ↑+1.91%
**섹터:** 기술
**산업:** 전자 컴퓨터
**시가총액:** 3.63T
**P/E 비율:** 38.26
... -
get_technical_analysis: 가격 변동 및 RSI 데이터 획득
# 기술 분석: AAPL
## 일일 가격 변동
현재 가격: $241.84 (↑$4.54, +1.91%)
### 최근 일일 가격
| 날짜 | 시가 | 고가 | 저가 | 종가 | 거래량 |
| ---------- | ------- | ------- | ------- | ------- | ------ |
| 2025-02-28 | $236.95 | $242.09 | $230.20 | $241.84 | 56.83M |
... -
get_earnings_report: MSFT 수익 기록 검색 및 서식 지정된 보고서
# 수익 보고서: MSFT (Microsoft Corporation)
**섹터:** 기술
**산업:** 서비스-사전 패키지 소프트웨어
**현재 EPS:** $12.43
## 최근 분기별 수익
| 분기 | 날짜 | EPS 추정치 | 실제 EPS | 서프라이즈 % |
| ---------- | ---------- | ------------ | ---------- | ---------- |
| 2024-12-31 | 2025-01-29 | $3.11 | $3.23 | ↑4.01% |
...
과제 및 해결책
개발 중에 몇 가지 과제에 직면했습니다.
- API 속도 제한:
- 과제: 무료 티어는 분당 5회 호출로 제한됨
- 해결책: 대기열 구현, 속도 제한 적용 및 포괄적인 캐싱 추가
- 데이터 서식:
- 과제: 원시 API 데이터는 사용자에게 친숙하지 않음
- 해결책: 재무 데이터의 일관된 표시를 위한 서식 유틸리티 생성
- 시간 초과 문제:
- 과제: 여러 API 호출을 수행하는 복잡한 도구는 시간 초과될 수 있음
- 해결책: 복잡한 도구를 더 작은 조각으로 분해하고 캐싱 최적화 제안
배운 점
AlphaAdvantage 구현을 통해 몇 가지 중요한 교훈을 얻었습니다.
- API 제한 계획: 처음부터 API 속도 제한을 이해하고 설계하십시오.
- 전략적 캐시: 성능 향상을 위해 가치 있는 캐싱 기회를 식별하십시오.
- 가독성을 위한 서식: 향상된 사용자 경험을 위해 좋은 데이터 서식에 투자하십시오.
- 모든 경로 테스트: 완료 전에 모든 도구를 개별적으로 테스트하십시오.
- API 복잡성 처리: 여러 호출이 필요한 API의 경우 더 간단한 범위로 도구를 설계하십시오.
핵심 구현 모범 사례
포괄적인 로깅
효과적인 로깅은 MCP 서버 디버깅에 필수적입니다.
// 시작 로깅
console.error("[설정] AlphaAdvantage MCP 서버 초기화 중...")
// API 요청 로깅
console.error(`[API] ${symbol}에 대한 주식 개요 가져오는 중`)
// 컨텍스트와 함께 오류 처리
console.error(`[오류] 도구 실행 실패: ${error.message}`)
// 캐시 작업
console.error(`[캐시] 다음 캐시된 데이터 사용: ${cacheKey}`)
강력한 유형 지정
유형 정의는 오류를 방지하고 유지 관리성을 향상시킵니다.
export interface AlphaAdvantageConfig {
apiKey: string
cacheTTL?: Partial<typeof DEFAULT_CACHE_TTL>
baseURL?: string
}
/**
* 주식 기호가 제공되었고 유효해 보이는지 확인
*/
function validateSymbol(symbol: unknown): asserts symbol is string {
if (typeof symbol !== "string" || symbol.trim() === "") {
throw new McpError(ErrorCode.InvalidParams, "유효한 주식 기호가 필요합니다.")
}
// 기본 기호 유효성 검사 (문자, 숫자, 점)
const symbolRegex = /^[A-Za-z0-9.]+$/
if (!symbolRegex.test(symbol)) {
throw new McpError(ErrorCode.InvalidParams, `잘못된 주식 기호: ${symbol}`)
}
}
지능형 캐싱
API 호출을 줄이고 성능을 향상시킵니다.
// 기본 캐시 TTL (초)
const DEFAULT_CACHE_TTL = {
STOCK_OVERVIEW: 60 * 60, // 1시간
TECHNICAL_ANALYSIS: 60 * 30, // 30분
FUNDAMENTAL_ANALYSIS: 60 * 60 * 24, // 24시간
EARNINGS_REPORT: 60 * 60 * 24, // 24시간
NEWS: 60 * 15, // 15분
}
// 먼저 캐시 확인
const cachedData = this.cache.get<T>(cacheKey)
if (cachedData) {
console.error(`[캐시] 다음 캐시된 데이터 사용: ${cacheKey}`)
return cachedData
}
// 성공적인 응답 캐시
this.cache.set(cacheKey, response.data, cacheTTL)
정상적인 오류 처리
좋은 사용자 경험을 유지하는 강력한 오류 처리를 구현합니다.
try {
switch (request.params.name) {
case "get_stock_overview": {
// 구현...
}
// 다른 경우...
default:
throw new McpError(ErrorCode.MethodNotFound, `알 수 없는 도구: ${request.params.name}`)
}
} catch (error) {
console.error(`[오류] 도구 실행 실패: ${error instanceof Error ? error.message : String(error)}`)
if (error instanceof McpError) {
throw error
}
return {
content: [
{
type: "text",
text: `오류: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
}
}
MCP 리소스
리소스를 사용하면 MCP 서버가 코드를 실행하지 않고도 Cline에 데이터를 노출할 수 있습니다. Cline이 대화 중에 참조할 수 있는 파일, API 응답 또는 데이터베이스 레코드와 같은 컨텍스트를 제공하는 데 완벽합니다.
MCP 서버에 리소스 추가
- 서버가 노출할 리소스를 정의합니다.
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "file:///project/readme.md",
name: "프로젝트 README",
mimeType: "text/markdown",
},
],
}
})
- 콘텐츠를 전달하기 위한 읽기 핸들러를 구현합니다.
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
if (request.params.uri === "file:///project/readme.md") {
const content = await fs.promises.readFile("/path/to/readme.md", "utf-8")
return {
contents: [
{
uri: request.params.uri,
mimeType: "text/markdown",
text: content,
},
],
}
}
throw new Error("리소스를 찾을 수 없습니다.")
})
리소스를 사용하면 MCP 서버가 더 컨텍스트 인식적이 되어 복사/붙여넣기 없이 Cline이 특정 정보에 액세스할 수 있습니다. 자세한 내용은 공식 문서를 참조하십시오.
일반적인 과제 및 해결책
API 인증 복잡성
과제: API는 종종 다른 인증 방법을 가집니다.
해결책:
- API 키의 경우 MCP 구성에서 환경 변수 사용
- OAuth의 경우 새로 고침 토큰을 얻기 위한 별도의 스크립트 생성
- 민감한 토큰을 안전하게 저장
// 환경에서 API 키를 사용하여 인증
const API_KEY = process.env.ALPHAVANTAGE_API_KEY
if (!API_KEY) {
console.error("[오류] ALPHAVANTAGE_API_KEY 환경 변수가 누락되었습니다.")
process.exit(1)
}
// API 클라이언트 초기화
const apiClient = new AlphaAdvantageClient({
apiKey: API_KEY,
})
누락되거나 제한된 API 기능
과제: API가 필요한 모든 기능을 제공하지 않을 수 있습니다.
해결책:
- 사용 가능한 엔드포인트를 사용하여 대체 구현
- 필요한 경우 시뮬레이션된 기능 생성
- 필요에 맞게 API 데이터 변환
API 속도 제한
과제: 대부분의 API에는 실패를 유발할 수 있는 속도 제한이 있습니다.
해결책:
- 적절한 속도 제한 구현
- 지능형 캐싱 추가
- 정상적인 성능 저하 제공
- 속도 제한에 대한 투명한 오류 추가
if (this.requestsThisMinute >= 5) {
console.error("[속도 제한] 속도 제한에 도달했습니다. 다음 분을 기다리는 중...")
return new Promise<void>((resolve) => {
const remainingMs = 60 * 1000 - (Date.now() % (60 * 1000))
setTimeout(resolve, remainingMs + 100) // 100ms 버퍼 추가
})
}