티스토리 뷰

단계의 목표
마지막 단계이다. MCP 서버를 만들어서 클로드 데스크탑(Claude Desktop)에 등록하여 도구를 사용한다.
- MCP 서버가 어떻게 시작하고, 클로드 데스크탑과 어떻게 통신하는지를 알아본다.
- MCP 서버의 시작
- 클로드 데스크탑과 MCP 서버간의 초기 통신
- 클로드 데스크탑의 도구 호출
- MCP 서버가 제공하는 도구(Tools)를 상세히 알아보기
- 결과물 시연
클로드 데스크탑 → MCP 서버 개념 이해
클로드 데스크탑에 등록
MacOS 기준으로 클로드 데스크탑 실행 후 Cmd+, 명령으로 Settigs 창 열고, Developer → Edit Config 선택

선택시 나타나는 claude_desktop_config.json 파일에 원하는 MCP Server 설정 등록.
나의 경우에는 ~/Library/"Application Support"/Claude/claude_desktop_config.json 였다.
설정 상세
- todo-printer: 클로드 데스크탑에게 알려주는 MCP 서버의 이름
- command: 실행할 명령어 경로. 가상환경 python3 를 실행한다. 가상환경 관련하여서는 설명을 생략한다.
- args: 명령어에 전달할 인수들
{
"globalShortcut": "Alt+Space",
"mcpServers": {
"todo-printer": {
"command": "/path/to/receipt-printer/.venv/bin/python3",
"args": [
"/path/to/receipt-printer/mcp_wrapper.py"
]
}
}
}
클로드 데스크탑 재시작
설정 이후에는 클로드 데스크탑을 재시작해주어야 설정이 반영된다. 설정한 MCP 서버기 실행되고 초기 작업이 이루어진다.
위 설정을 예를 들어 초기화 프로세스를 간략히 설명하면 다음과 같다.
1. MCP 서버 시작
클로드 데스크탑은 MCP 서버의 경로, 실행권한 등을 검토한 다음 자신이 부모 프로세스가 되어, 자식 프로세스로서 MCP 서버를 시작한다. 시작 명령은 이렇게 될 것이다.
/path/to/receipt-printer/.venv/bin/python3 /path/to/receipt-printer/mcp_wrapper.py
둘 사이의 통신은 stdin/stdout 이 된다. 즉, 클로드 데스크탑이 stdout(표준출력)으로 내보내는 출력은 MCP 서버가 stdin(표준 입력)으로 읽게 되며, 그 반대로도 통신을 한다.
Claude Desktop MCP Server
↓ ↑
stdout/stdin ←→ stdin/stdout
2. 연결하기 - handshake
초기에 핸드셰이크(악수하기)를 하며 클로드 데스크탑이 MCP 서버 정보를 얻는다. 어떤 도구가 있는지, 어떻게 도구를 사용할 수 있는지를 알아내는 것이다. 알아내야 쓸 수 있는 것이니 당연한 과정이다. 최신의 내용과는 다를 수 있으니 개념만 참고하자(실제 코드에서 핵심 개념만 추려내었다).
Claude → MCP Server: 초기화 요청
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
}
},
"clientInfo": {
"name": "claude-desktop",
"version": "1.0"
}
}
}
MCP Server → Claude: 초기화 응답
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "todo-printer",
"version": "1.0"
}
}
}
Claude → MCP Server: 도구 정보 요청
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
MCP Server → Claude: 도구 정보
- 예시에서는 print_memo, list_printer, get_printer_status 도구가 있다고 알려준다.
- 클로드 데스크탑은 name, description, inputSchema 등의 정보를 바탕을 도구를 선택하게 된다.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "print_memo",
"description": "'>'로 시작하거나 '출력'을 요청한 텍스트에 대해 사용합니다.",
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "출력할 텍스트",
"maxLength": 500
},
"printer_name": {
"type": "string",
"default": "BIXOLON_SRP_330II"
}
},
"required": ["text"]
}
},
{
"name": "list_printers",
"description": "사용 가능한 프린터 목록을 조회합니다"
},
{
"name": "get_printer_status",
"description": "특정 프린터의 상태를 확인합니다"
}
]
}
}
MCP Server → Claude: 서버의 가능한 기능 정보
{
"capabilities": {
"tools": {
"listChanged": true // 도구 목록 동적 변경 지원
},
"resources": { // 파일/리소스 접근 가능
"subscribe": true,
"listChanged": true
},
"prompts": { // 프롬프트 템플릿 제공
"listChanged": true
}
}
}
실제 통신하기
이제 모든 준비가 되었다.
사용자가 클로드 데스크탑에서 프롬프트를 입력하면 클로드 데스크탑은 자신이 가지고 있는 도구에 대한 정보와, 사용자의 프롬프트를 참고하여 판단한 다음, 필요하다 생각하면 프린트를 요청한다. 나의 경우에는 >로 시작하거나 출력 을 명시적으로 요청하는 경우 클로드 데스트탑이 인지하고 프린트 요청을 하였다. 좀더 정확히는 print_memo 도구를 사용했다.
Claude → MCP Server: 도구 호출
클로드 데스크탑은 도구의 이름, 필요한 파라미터를 채워서 요청을 보낸다.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "print_memo",
"arguments": {
"text": "우유 사오기",
"printer_name": "BIXOLON_SRP_330II"
}
}
}
MCP Server → Claude: 실행 결과 응답
MCP 서버는 클로드 데스크탑에 응답을 보내게 되는데 여기에도 필요하다면 클로드 데스크탑이 참고할 정보를 넣을 수 있겠다. 예를 들면, 오늘 출력한 개수 정보나 응답을 받고는 아무것도 하지말라고 요청한다거나 할 수 있겠다.
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "메모가 성공적으로 출력되었습니다."
}
]
}
}
코드 보기
코드는 mcp_wrapper.py 파일을 참고하면 된다.
도구 정보
도구 정보를 들여다보자.
- 도구의 name, description, inputSchema 정보들은 클로드 데스크탑에 도구에 대한 정보를 줄 뿐 아니라, 도구를 사용할지 여부를 판단하는데도 중요한 정보를 제공한다.
- 예를 들어 텍스트를 절대로 수정하지 마세요 라는 요청은 클로드 데스크탑이 출력 요청한 텍스트에 더하여 추가적인 정보를 담아 출력을 하는 경우가 한번씩 발생하여 추가한 것이다. 일종의 프롬프트 엔지니어링이다.
def __init__(self):
# ThreadPoolExecutor로 동기 함수들을 비동기로 실행
self.executor = ThreadPoolExecutor(max_workers=2)
self.tools = {
"print_memo": {
"name": "print_memo",
"description": "'>' 로 시작하거나 '출력'을 요청한 텍스트에 대해 사용합니다. 텍스트를 절대로 수정하지 마세요.",
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "출력할 텍스트 (500자 이내, 예: '우유 사오기', '회의 준비사항')",
"maxLength": 500
},
"printer_name": {
"type": "string",
"description": "프린터 이름",
"default": "BIXOLON_SRP_330II"
},
"preview": {
"type": "boolean",
"description": "미리보기 모드 (실제로 출력하지 않음)",
"default": False
}
},
"required": ["text"]
}
},
"list_printers": {
"name": "list_printers",
"description": "사용 가능한 프린터 목록을 조회합니다",
"inputSchema": {
"type": "object",
"properties": {}
}
},
"get_printer_status": {
"name": "get_printer_status",
"description": "특정 프린터의 상태를 확인합니다",
"inputSchema": {
"type": "object",
"properties": {
"printer_name": {
"type": "string",
"description": "상태를 확인할 프린터 이름",
"default": "BIXOLON_SRP_330II"
}
},
"required": ["printer_name"]
}
},
}
작동 프로세스
MCP 서버는 stdin(표준입력)으로 들어오는 값이 있는지 대기하다가 값이 들어오면 처리를 한다.
- JSON 정보로 받아서 요청 처리 시작
- 요청의 method를 확인하여 분기. method는 initialize, tools/list, tools/call
- initialize, tools/list는 초기 핸드셰이크에서의 요청이고 tools/call의 경우 도구의 이름을 확인하여 그에 맞게 처리한다. 실제로 프린터로의 작업은 printer.py 파일의 함수들이 기능을 할 것이다.
작동 프로세스에 대해서는 여기까지 개념만을 설명하고 마무리한다. 이제는 챗GPT, 클로드와 같은 AI들이 있어서 이 정도의 개념만을 가지고 코드 분석을 요청하면 알기쉽게 하나씩 설명해준다.
결과물
출력 요청
클로드 코드에 다음과 같이 출력을 요청한다.
- > 를 붙여서 메모하면 출력해준다.
- 출력 해달라는 말을 명시적으로 할 수도 있다.
- 하나의 프롬프트에 여러 개의 출력을 요청할 수도 있다.
- 마지막의 경우가 가장 인상적인데 > 나 출력 요청을 명시적으로 하지 않았는데도 메모를 둘로 나누어서 출력해준다.
- 클로드가 앞선 요청들의 맥락상 출력을 요청한 것으로 이해하고, 또한 별개의 두 메모라고 인식한 것이다.
- 항상 이렇게 출력되는 것은 아니다(non-deterministic). 이를 좀더 강제하려면 description 등에 프롬프트 엔지니어링을 해주어야 할 것이다. 혹은 가까운 미래에 공짜 점심으로 AI가 의도를 더욱 잘 알아듣게 될 수도 있겠다.

출력 결과
이렇게 출력하여 테이블에 올려두었다가 하나씩 해결하며 오른쪽의 빈 용기에 넣어둔다.

'develop-and-AI' 카테고리의 다른 글
| 옵시디언 - Git Sync (0) | 2025.07.15 |
|---|---|
| 영수증 프린터로 할 일 관리 - MCP 서버 코드(개선) (0) | 2025.07.15 |
| 영수증 프린터로 할 일 관리 - 프린터 코드 (0) | 2025.07.11 |
| 영수증 프린터로 할 일 관리 - 프린터 준비 (0) | 2025.07.11 |
| 영수증 프린터로 할 일 관리 - 시작 (0) | 2025.07.11 |
- Total
- Today
- Yesterday
- API
- agile
- strange
- gocore
- backend
- 독서후기
- 잡학툰
- MCP
- 독서
- websocket
- middleware
- bun
- go
- ChatGPT
- clean agile
- 클린 애자일
- github
- Echo
- 오블완
- 인텔리제이
- 체호프
- solid
- postgres
- 영화
- notion
- OpenAI
- 티스토리챌린지
- golang
- Gin
- intellij
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |