MCP 서버는 외부 세계를 AI에게 아무렇게나 열어 주지 않는다. 서버는 자신이 제공할 수 있는 것을 몇 가지 형태로 정리해 호스트와 클라이언트에 알려 준다. 그 대표 단위가 Tools, Resources, Prompts다.
비유하면 이렇다.
Tools는 버튼이다. 누르면 일이 실행된다.
Resources는 자료실이다. 열어 보고 참고한다.
Prompts는 업무 양식이다. 정해진 방식으로 일을 시작하게 한다.
이 셋을 구분하지 못하면 MCP 서버를 고를 때도, 직접 만들 때도 금방 복잡해진다. 모든 것을 Tool로 만들면 AI가 너무 많은 버튼 앞에서 헷갈린다. 반대로 실행해야 할 일을 Resource로만 제공하면 AI는 읽기만 하고 실제 업무를 끝내지 못한다. 반복 업무의 시작 방식을 매번 채팅창에 새로 써야 한다면, 팀마다 일하는 방식도 쉽게 흔들린다.
AI 생성 이미지
Tools: 실행할 수 있는 행동
Tool은 AI가 호출할 수 있는 함수에 가깝다. MCP 공식 사양에서도 Tool은 모델이 발견하고 호출할 수 있는 기능으로 설명된다. 클라이언트는 tools/list로 사용 가능한 Tool 목록을 확인하고, 실제 실행은 tools/call로 요청한다.1
여기서 "AI가 호출한다"는 말은 AI가 서버에 직접 마음대로 접속한다는 뜻이 아니다. 모델이 대화 맥락을 보고 "이 Tool을 쓰면 되겠다"고 판단하면, 호스트 안의 MCP 클라이언트가 정해진 프로토콜에 따라 서버에 호출을 보낸다. 사용자가 쓰는 앱은 그 사이에서 입력값을 보여 주거나, 민감한 작업에 대해 확인을 받거나, 실행 결과를 다시 대화에 반영한다.
Tool에 어울리는 것은 대체로 동사로 표현된다.
create_file: 파일을 만든다.create_ticket: 고객지원 티켓을 등록한다.query_database: 데이터베이스를 조회한다.send_slack_message: Slack 메시지를 보낸다.calculate_invoice_total: 청구 금액을 계산한다.
예를 들어 이슈 관리 시스템을 연결한다고 하자. 사용자가 "어제 들어온 결제 오류 문의를 티켓으로 만들어 줘"라고 말하면 AI는 단순히 문장을 생성하는 데서 끝나면 안 된다. 실제 티켓 시스템에 항목을 만들어야 한다. 이때 필요한 것이 Tool이다.
간단한 Tool 정의는 다음처럼 생각할 수 있다.
{
"name": "create_ticket",
"description": "고객 문의 내용을 바탕으로 지원 티켓을 생성한다.",
"inputSchema": {
"type": "object",
"properties": {
"title": { "type": "string" },
"body": { "type": "string" },
"priority": { "type": "string", "enum": ["low", "normal", "high"] }
},
"required": ["title", "body"]
}
}여기서 중요한 것은 description과 inputSchema다. 설명은 사람만 읽는 문서가 아니다. 모델도 이 설명을 보고 언제 이 Tool을 써야 할지 판단한다. 입력 스키마는 모델이 어떤 값을 넣어야 하는지 알려 주는 계약서다. 최근 사양에서는 결과를 구조화하기 위한 outputSchema도 선택적으로 정의할 수 있지만, 처음에는 "무엇을 하는 Tool인지"와 "어떤 입력을 받는지"를 명확히 하는 것이 더 중요하다.1
Tool은 강력하다. 그래서 위험하다. 파일 생성, 메시지 발송, 데이터 수정, 결제 처리처럼 외부 시스템에 영향을 주는 작업은 반드시 권한 확인, 입력 검증, 실행 로그, 필요시 사용자 확인을 붙여야 한다. 데이터베이스 조회나 계산처럼 상태를 바꾸지 않는 Tool도 안심할 수만은 없다. 조회 결과에 개인정보가 포함될 수 있고, 입력 조건을 잘못 열어 두면 대량 데이터가 빠져나갈 수도 있기 때문이다.
공식 사양도 Tool 입력 검증, 접근 제어, 호출 제한, 출력 정제, 민감 작업에 대한 사용자 확인을 중요한 안전장치로 다룬다.1
Resources: 읽을 수 있는 맥락
Resource는 AI가 참고할 수 있는 데이터다. 파일, 문서, 로그, 데이터베이스 스키마, 레코드, 설정값처럼 "읽는 것"에 적합하다. MCP에서 Resource는 URI로 식별되며, 클라이언트는 resources/list로 목록을 보고 resources/read로 내용을 읽을 수 있다.2
Resource에 어울리는 것은 대체로 명사로 표현된다.
file:///workspace/README.mddocs://company/refund-policylog://payments/2026-07-19db://customers/12345git://repo/main/src/app.ts
예를 들어 사내 환불 정책 문서를 AI에게 참고시키고 싶다면, 이것은 Tool보다 Resource에 가깝다. AI가 정책을 "실행"하는 것이 아니라 "읽고" 답변에 반영하기 때문이다.
Resource 정의는 다음처럼 이해하면 된다.
{
"uri": "docs://company/refund-policy",
"name": "refund-policy",
"title": "환불 정책 문서",
"description": "고객 환불 가능 조건과 예외 사항을 정리한 문서",
"mimeType": "text/markdown"
}Resource의 핵심은 맥락 제공이다. 모델은 환불 정책 문서를 읽고 고객 문의에 맞는 답변을 만들 수 있다. 하지만 이 문서를 읽었다고 해서 자동으로 환불 처리가 실행되지는 않는다. 환불을 실제로 처리하려면 별도의 Tool, 예를 들어 approve_refund 같은 실행 기능이 필요하다.
또 하나 기억할 점은 Resource가 Tool보다 사용 방식이 더 "앱 중심"이라는 것이다. Tool은 모델이 대화 맥락에 따라 자동으로 고르는 흐름에 가깝지만, Resource는 호스트 애플리케이션이 어떤 자료를 언제 대화 맥락에 넣을지 결정하는 경우가 많다. 사용자가 파일 트리에서 문서를 고를 수도 있고, 앱이 검색 결과를 붙여 줄 수도 있고, 특정 상황에서 자동으로 관련 문서를 포함할 수도 있다. 프로토콜은 이런 화면 구성을 강제하지 않고, Resource를 표준 방식으로 나열하고 읽을 수 있게 해 준다.2
Resource는 읽기 전용이라고 생각하기 쉽지만, 그렇다고 보안이 가벼워지는 것은 아니다. 로그에는 개인정보가 있을 수 있고, 문서에는 내부 정책이나 API 키가 섞여 있을 수 있다. "실행하지 않으니 괜찮다"가 아니라 "읽히면 유출될 수 있다"가 맞다. 그래서 Resource URI 검증, 민감 자료 접근 제어, 권한 확인이 필요하다.2
Prompts: 반복 업무를 시작하는 템플릿
Prompt는 서버가 제공하는 재사용 가능한 지시문 템플릿이다. MCP 공식 사양에서 Prompt는 사용자가 명시적으로 선택해 쓰는 구조화된 메시지와 지시문으로 설명된다. 클라이언트는 prompts/list로 목록을 보고, prompts/get으로 특정 Prompt 내용을 가져온다.3
Prompt는 Tool처럼 실행 버튼이 아니다. Resource처럼 단순 자료도 아니다. 반복되는 업무를 정해진 형식으로 시작하게 하는 업무 양식에 가깝다.
예를 들어 팀에서 매번 같은 방식으로 장애 보고서를 작성한다면 다음과 같은 Prompt를 만들 수 있다.
{
"name": "incident_report",
"title": "장애 보고서 작성",
"description": "장애 로그와 타임라인을 바탕으로 사내 표준 장애 보고서를 작성한다.",
"arguments": [
{ "name": "service_name", "description": "장애가 발생한 서비스 이름", "required": true },
{ "name": "log_uri", "description": "참고할 로그 Resource URI", "required": true }
]
}위 예시는 목록에서 보이는 Prompt의 껍데기에 가깝다. 실제로 prompts/get을 호출하면, 서버는 사용자의 입력값을 반영해 모델에게 전달할 메시지 묶음을 돌려준다. 그 메시지 안에는 "원인, 영향 범위, 조치 내역, 재발 방지책 순서로 작성하라" 같은 지시문이 들어갈 수 있고, 필요하면 Resource를 함께 참조하게 만들 수도 있다.3
사용자는 이 Prompt를 선택하고 service_name과 log_uri를 넣는다. 그러면 AI는 정해진 양식에 따라 원인, 영향 범위, 조치 내역, 재발 방지책을 정리한다. 여기서 로그는 Resource로 읽고, 필요하다면 후속 조치 티켓 생성은 Tool로 실행할 수 있다.
Prompt가 유용한 곳은 반복 업무다.
회의록을 팀 표준 형식으로 요약하기
고객 문의 답변 초안을 정해진 톤으로 작성하기
코드 리뷰 체크리스트에 따라 변경 사항 검토하기
신규 입사자 온보딩 안내문 만들기
장애 보고서를 사내 양식에 맞춰 작성하기
노코드 파워유저에게 Prompt는 특히 중요하다. 서버를 직접 개발하지 않아도, 잘 만들어진 Prompt를 고르면 팀의 일하는 방식을 AI 앱 안으로 가져올 수 있기 때문이다.
같은 기능을 Tool로 만들까, Resource로 만들까
실무에서는 경계가 애매한 경우가 많다. 특히 "조회" 기능이 그렇다. 데이터베이스 조회는 Tool일 수도 있고 Resource일 수도 있다.
예를 들어 db://customers/12345처럼 특정 고객 레코드를 읽는 것은 Resource에 가깝다. 반면 "최근 30일간 결제 실패율을 조건별로 집계해 줘"처럼 매번 조건을 받아 쿼리를 실행해야 한다면 query_database Tool이 더 자연스럽다. 둘 다 읽기 작업처럼 보이지만, 앞의 경우는 이미 정해진 자료를 읽는 흐름이고, 뒤의 경우는 입력값을 받아 계산이나 조회 동작을 수행하는 흐름에 가깝다.
판단 기준은 다음 네 가지다.
첫째, 상태를 바꾸는가. 파일 생성, 티켓 등록, 메시지 발송, DB 수정처럼 외부 상태가 바뀌면 Tool이다. 사용자 확인과 로그가 필요하다.
둘째, 주로 읽기 위한 자료인가. 정책 문서, 로그 파일, 코드 파일, 레코드, 스키마처럼 참고가 목적이면 Resource가 적합하다.
셋째, 누가 선택해야 하는가. 모델이 상황에 맞춰 자동으로 고를 기능이면 Tool에 가깝다. 호스트 앱이나 사용자가 참고 자료로 붙이는 흐름이면 Resource에 가깝다. 사용자가 명시적으로 업무 양식을 고르는 흐름이면 Prompt가 맞다. 공식 사양의 표현으로 옮기면 Tool은 모델 중심, Resource는 애플리케이션 중심, Prompt는 사용자 중심에 가깝다.123
넷째, 내용이 큰가. 큰 문서나 긴 로그를 Tool 결과로 매번 반환하게 만들면 컨텍스트가 낭비된다. 이런 데이터는 Resource로 노출하고, 필요한 부분만 읽도록 설계하는 편이 낫다.
간단히 정리하면 이렇다.
| 구분 | 핵심 질문 | 예시 |
|---|---|---|
| Tool | "무엇을 실행할까?" | 파일 생성, 티켓 등록, API 호출, DB 조회 실행 |
| Resource | "무엇을 참고할까?" | 문서, 로그, 코드, DB 레코드, 정책 자료 |
| Prompt | "어떤 방식으로 작업을 시작할까?" | 회의록 요약 양식, 장애 보고서 템플릿, 코드 리뷰 절차 |
너무 많이 열어 주면 똑똑해지는 것이 아니다
MCP 서버를 처음 만들면 모든 기능을 노출하고 싶어진다. "AI가 알아서 고르겠지"라고 생각하기 쉽다. 하지만 기능이 많아질수록 선택 오류가 늘어난다.
예를 들어 비슷한 Tool이 여러 개 있다고 하자.
send_messagesend_slack_messagepost_channel_messagenotify_team
사람에게도 헷갈린다. 모델에게도 헷갈린다. 설명이 모호하면 AI는 잘못된 Tool을 고를 수 있다. 개인 DM으로 보내야 할 내용을 공개 채널에 올리거나, 테스트 티켓을 운영 프로젝트에 등록할 수도 있다.
보안 위험도 커진다. 노출된 Tool 하나하나가 공격면이 된다. 특히 다음 기능은 신중하게 열어야 한다.
파일 삭제 또는 덮어쓰기
외부 메시지 발송
데이터베이스 수정
결제, 환불, 권한 변경
임의 명령 실행
대량 데이터 조회
좋은 MCP 서버는 기능이 많은 서버가 아니다. 필요한 기능을 정확한 이름과 설명, 제한된 권한으로 제공하는 서버다. 가능하면 읽기는 Resource로, 실행은 최소한의 Tool로, 반복 절차는 Prompt로 나누자.
서버를 고를 때도 같은 기준을 적용하면 된다. 이 서버가 무엇을 Tool로 열어 두었는지, 어떤 Resource를 읽게 하는지, 팀 업무에 맞는 Prompt를 제공하는지 확인하자. 그리고 민감한 Tool이 사용자 확인 없이 실행되는 구조라면 조심해야 한다. Resource라고 해도 민감 문서나 로그를 넓게 읽게 하는 서버라면 마찬가지로 주의해야 한다.
세 가지를 함께 쓰는 흐름
마지막으로 실제 업무 흐름으로 묶어 보자.
사용자가 "어제 결제 장애 내용을 정리하고 후속 조치 티켓을 만들어 줘"라고 요청한다.
AI 앱은
log://payments/2026-07-18Resource를 읽어 장애 로그를 대화 맥락에 넣는다.사용자는
incident_reportPrompt를 선택해 팀 표준 양식으로 보고서를 작성하게 한다.AI는 보고서에서 나온 후속 작업을 바탕으로
create_ticketTool 사용을 제안한다.티켓 생성 전 호스트는 제목, 본문, 우선순위를 사용자에게 보여 주고 확인을 받는다.
확인이 끝나면 MCP 클라이언트가
tools/call로 Tool 실행을 요청하고, 결과를 대화에 반영한다.
이 흐름에서 Resource는 근거를 제공했고, Prompt는 형식을 잡았고, Tool은 실제 일을 끝냈다. 셋의 역할이 분리되어 있기 때문에 사용자는 무엇을 읽었고, 어떤 양식으로 작성했고, 어떤 행동이 실행되었는지 추적할 수 있다.
MCP를 잘 쓴다는 것은 AI에게 모든 권한을 넘기는 일이 아니다. 읽을 것, 실행할 것, 반복할 절차를 구분해 연결하는 일이다. 이 구분이 되어야 기존 MCP 서버를 고를 때도 판단이 서고, 나중에 직접 서버를 만들 때도 안전한 설계를 할 수 있다.
참고
1Tools - Model Context Protocol
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.