ai 에이전트 만들기 claude-agent-sdk mcp personal-ai-assistant

🎯 드디어 피날레! 나만의 AI 비서를 만들어볼까요?
여러분, 9편의 긴 여정을 함께 해줘서 정말 고마워요! 오늘은 시리즈 마지막 편이에요. EP1부터 하나씩 모아온 퍼즐 조각을 전부 맞춰서, 진짜로 동작하는 나만의 AI 비서를 만들어볼 거예요.
진짜로? 9편 동안 배운 거 전부 써서 쓸 만한 걸 만들 수 있는 거야?
물론이지! EP1에서 처음 만난 Agentic AI, 이제 우리가 직접 만들 수 있어. 한 번에 다 만드는 게 아니라, 5단계로 점진적으로 진화시킬 거예요. 마치 레고 블록 쌓듯이!
2026년 가장 뜨거운 트렌드 중 하나가 바로 개인 AI 비서예요. AI 에이전트 만들기가 이렇게 쉬워진 건 Claude Agent SDK와 FastMCP 덕분이에요. 우리도 직접 만들 수 있어요. 오늘 그 전체 과정을 함께 걸어볼게요.

위 다이어그램이 오늘의 전체 로드맵이에요. AI 에이전트 만들기 5단계 — Stage 1부터 Stage 5까지, 한 단계씩 기능을 추가하면서 비서를 진화시켜 나갈 거예요.
🔧 Stage 1 — MCP 도구 만들기 (EP7 복습)
비서한테 능력을 줘야 하니까, 먼저 도구부터 만드는 거지?
맞아! EP7에서 배운 MCP 기억나지? FastMCP의 @mcp.tool() 데코레이터로 6개 도구를 만들 거예요. 메모 3개, 일정 2개, 날씨 1개!
비서에게 줄 도구를 MCP 서버로 만드는 게 첫 번째 단계예요. AI 에이전트 만들기의 핵심은 도구부터 시작하는 것이에요. FastMCP를 사용하면 Python 함수에 데코레이터만 붙이면 끝이에요.
# tools_server.py (Stage 1)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("personal-assistant")
@mcp.tool()
def save_memo(
title: str, content: str
) -> str:
"""Save a memo with title/content."""
memos = _load_json(MEMOS_FILE)
memo = {
"title": title,
"content": content,
"created":
datetime.now().isoformat(),
}
memos.append(memo)
_save_json(MEMOS_FILE, memos)
return f"Memo saved: '{title}'"
@mcp.tool()
def get_schedule(date: str) -> str:
"""Get all events for a date."""
schedule = _load_json(SCHEDULE_FILE)
events = [
e for e in schedule
if e["date"] == date
]
if not events:
return f"No events on {date}"
lines = []
for e in events:
lines.append(
f"- {e['time']}: {e['event']}"
)
return (
f"Schedule for {date}:\n"
+ "\n".join(lines)
)
save_memo는 메모를 JSON 파일에 저장하고, get_schedule은 특정 날짜의 일정을 조회해요. 이 외에도 search_memos, list_memos, add_schedule, get_weather까지 총 6개 도구를 만들어요. 전체 코드는 GitHub에서 확인할 수 있어요.
함수 하나 = 도구 하나. 깔끔하네. 그런데 이걸 어떻게 에이전트랑 연결해?
🔌 Stage 2 — 기본 비서 연결하기 (EP5+EP8 복습)
EP5에서 에이전트 루프를 직접 50줄 넘게 작성했잖아? SDK를 쓰면 query() 한 줄로 끝이에요! EP8에서 배운 SDK가 모든 루프를 자동 처리해줘요.
# simple_assistant.py (Stage 2)
import asyncio
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
MCPServerStdio,
ResultMessage,
)
async def main():
options = ClaudeAgentOptions(
allowed_tools=[
# Built-in tools
"WebSearch", "Read", "Write",
# MCP tools
"mcp__assistant__save_memo",
"mcp__assistant__search_memos",
"mcp__assistant__list_memos",
"mcp__assistant__add_schedule",
"mcp__assistant__get_schedule",
"mcp__assistant__get_weather",
],
mcp_servers={
"assistant": MCPServerStdio(
command="python",
args=["tools_server.py"],
)
},
max_turns=10,
)
async for msg in query(
prompt="Save a memo titled "
"'Meeting' with content "
"'Team sync at 3pm'.",
options=options,
):
if isinstance(msg, ResultMessage):
if msg.subtype == "success":
print(msg.result)
asyncio.run(main())
핵심은 MCPServerStdio예요. SDK가 tools_server.py를 자식 프로세스로 자동 실행해줘서, 터미널을 2개 열 필요가 없어요. MCP 도구 6개 + 내장 도구 3개, 총 9개 도구를 가진 비서가 완성됐어요! AI 에이전트 만들기, 생각보다 간단하죠?
동작은 하는데… 성격도 없고, 위험한 파일에 마음대로 쓸 수도 있잖아. 좀 불안한데?
🛡️ Stage 3 — 똑똑한 비서: Hooks와 시스템 프롬프트
그래서 Stage 3에서 두 가지를 추가해요. 하나는 EP6에서 배운 시스템 프롬프트로 성격을 입히는 것, 다른 하나는 오늘 처음 배우는 새로운 개념 — Hooks예요!
에이전트가 도구를 사용할 때 발생하는 이벤트를 가로채는 콜백 함수예요. PreToolUse(실행 전)로 위험한 동작을 차단하고, PostToolUse(실행 후)로 모든 활동을 기록할 수 있어요. 에이전트의 보안 시스템이라고 생각하면 돼요.
가로챈다? 도구 호출을 중간에서 잡는다는 거야?
맞아! 비유하면 이래요. PreToolUse는 현관문의 자물쇠예요 — 들어오기 전에 확인해서 허용하거나 차단해요. PostToolUse는 감시 카메라예요 — 이미 일어난 일을 기록해서 나중에 확인할 수 있어요.

위 다이어그램을 보면 흐름이 명확해요. 에이전트가 도구를 쓰려 하면 PreToolUse Hook이 먼저 실행되고, 허용하면 도구가 실행된 뒤 PostToolUse Hook이 기록해요.
# smart_assistant.py (Stage 3)
# Hook 1: Safety guard (PreToolUse)
async def safety_guard(
input_data, tool_use_id, context
):
"""Block writes to system paths."""
tool = input_data["tool_name"]
tool_input = input_data["tool_input"]
if tool in ("Write", "Edit"):
path = tool_input.get(
"file_path", ""
)
blocked = [
"/etc/", "/usr/",
"C:\\Windows",
"C:\\Program",
]
if any(
p in path for p in blocked
):
return {
"hookSpecificOutput": {
"hookEventName":
input_data[
"hook_event_name"
],
"permissionDecision":
"deny",
"permissionDecisionReason":
"System path blocked",
}
}
return {} # Allow
# Hook 2: Activity logger (PostToolUse)
async def activity_logger(
input_data, tool_use_id, context
):
"""Log all tool usage."""
tool = input_data["tool_name"]
print(f" [LOG] Tool used: {tool}")
return {}
safety_guard는 Write나 Edit 도구가 시스템 경로에 접근하려 하면 "deny"를 반환해서 차단해요. activity_logger는 모든 도구 사용을 콘솔에 기록해요.
이 Hooks를 등록하는 방법도 간단해요.
# Hooks registration in options
options = ClaudeAgentOptions(
system_prompt=(
"You are a friendly, helpful "
"personal AI assistant. "
"Your name is 'Buddy'."
),
hooks={
"PreToolUse": [
HookMatcher(
matcher="Write|Edit",
hooks=[safety_guard],
),
],
"PostToolUse": [
HookMatcher(
hooks=[activity_logger],
),
],
},
# ... tools and mcp_servers
)
HookMatcher의 matcher에 정규식 패턴을 넣으면, 해당 도구에만 Hook이 적용돼요. PostToolUse처럼 matcher를 생략하면 모든 도구에 적용돼요. 그리고 시스템 프롬프트로 “Buddy”라는 친근한 캐릭터 성격도 입혔어요!

👥 Stage 4 — 팀 비서: 멀티 에이전트 (EP9 복습)
혼자 다 하는 비서도 괜찮지만, 전문가 팀을 만들면 더 강력해져요! EP9에서 배운 오케스트레이터 패턴을 적용해볼 거예요.
EP9의 블로그 팀이 Researcher, Writer, Reviewer였으니까, 이번에는 비서 팀을 만드는 거네?
같은 패턴, 다른 전문가! 이번에는 Scheduler(일정), Researcher(검색), Assistant(메모/파일) 3명으로 팀을 구성해요.
# team_assistant.py (Stage 4)
agents = {
"scheduler": AgentDefinition(
description=(
"Manages calendar and "
"schedules."
),
prompt=(
"You are a precise "
"scheduling assistant."
),
tools=[
"mcp__assistant__"
"add_schedule",
"mcp__assistant__"
"get_schedule",
],
),
"researcher": AgentDefinition(
description=(
"Searches the web for "
"information."
),
prompt=(
"You are a thorough "
"research assistant."
),
tools=[
"WebSearch", "WebFetch",
],
),
"assistant": AgentDefinition(
description=(
"Handles memos, files, "
"and general tasks."
),
prompt=(
"You are a helpful "
"personal assistant."
),
tools=[
"Read", "Write",
"mcp__assistant__save_memo",
"mcp__assistant__"
"search_memos",
],
),
}
# Orchestrator
options = ClaudeAgentOptions(
system_prompt=(
"You are a team manager "
"coordinating 3 specialists."
),
allowed_tools=["Agent"],
agents=agents,
max_turns=15,
)
매니저 에이전트가 사용자 요청을 분석해서 적절한 전문가에게 위임해요. “치과 예약하고, 서울 카페 검색해서 메모로 저장해줘”라고 하면, Scheduler → Researcher → Assistant 순서로 체인이 걸려요! AI 에이전트 만들기를 이런 팀 구조로 발전시키면 훨씬 강력해져요.

위 아키텍처 다이어그램은 Stage 4까지의 전체 구조를 보여줘요. MCP 서버가 도구를 제공하고, SDK가 에이전트 루프를 돌리고, 오케스트레이터가 3명의 전문가를 조율해요.
💾 Stage 5 — 기억하는 비서: Sessions (EP4 복습+신규)
여기까지 꽤 괜찮은데, 한 가지 문제가 있어. 대화가 끝나면 다 잊어버리잖아?
EP4에서 컨텍스트와 메모리를 배웠지? 오늘은 그걸 SDK에서 구현하는 방법을 알려줄게 — 바로 Sessions예요!
여러 번의 query() 호출을 하나의 대화로 이어주는 기능이에요. session_id를 캡처하고 resume 파라미터로 전달하면, 이전 대화의 전체 컨텍스트가 복원돼요. 책갈피처럼 “어디까지 읽었는지” 기억하는 거예요.
# persistent_assistant.py (Stage 5)
async def main():
# Turn 1: Save something
session_id = None
async for msg in query(
prompt=(
"Save a memo titled "
"'Project Ideas' with "
"content 'Build a recipe "
"recommender using "
"MCP tools'."
),
options=build_options(),
):
if isinstance(
msg, ResultMessage
):
# Capture session_id!
session_id = msg.session_id
if msg.subtype == "success":
print(msg.result)
print(f"Session: {session_id}")
# Turn 2: Ask WITH memory
async for msg in query(
prompt=(
"What memo did I just save?"
),
options=ClaudeAgentOptions(
**{
**build_options()
.__dict__,
"resume": session_id,
}
),
):
if isinstance(
msg, ResultMessage
):
if msg.subtype == "success":
print(msg.result)
핵심은 딱 두 줄이에요. ResultMessage에서 session_id를 캡처하고, 다음 query()에서 resume=session_id로 전달하면 끝! AI 에이전트 만들기의 마지막 퍼즐이 맞춰졌어요.
WITH vs WITHOUT 비교
세션의 위력을 비교해볼게요.
| 시나리오 | 질문 | 응답 |
|---|---|---|
| WITHOUT session | “방금 뭐 저장했어?” | “이전 대화 기록이 없어서 알 수 없어요.” |
| WITH session | “방금 뭐 저장했어?” | “‘Project Ideas’ 메모를 저장했어요!” |
세션 없이 호출하면 매번 새로운 대화가 시작돼서 이전 내용을 전혀 기억하지 못해요. 세션을 이어가면 마치 같은 대화를 계속하는 것처럼 완벽하게 기억해요.
session_id를 직접 관리하기 번거롭다면 ClaudeSDKClient를 쓰면 돼요. async with ClaudeSDKClient() as c: 블록 안에서 await c.query()를 여러 번 호출하면, 세션이 자동으로 유지돼요!
📋 EP1~EP10 총정리
10편 동안 배운 모든 개념이 오늘 하나로 모였어요! 한눈에 정리해볼게요.

| 에피소드 | 핵심 개념 | EP10 활용 |
|---|---|---|
| EP1 | Agentic AI 첫 만남 | 직접 구현! “AI가 알아서 한다”의 실체 |
| EP2 | LLM (두뇌) | 비서의 모든 판단은 LLM이 처리 |
| EP3 | Tool Use (손) | MCP 도구 6개 + 내장 도구 3개 |
| EP4 | 컨텍스트 & 메모리 | Sessions로 대화 기억 구현 |
| EP5 | Agent Loop | SDK가 자동 처리 (query() 한 줄) |
| EP6 | 시스템 프롬프트 | “Buddy” 캐릭터 성격 부여 |
| EP7 | MCP 프로토콜 | FastMCP로 커스텀 도구 서버 구축 |
| EP8 | Claude Agent SDK | query(), Options, MCPServerStdio 활용 |
| EP9 | 멀티 에이전트 | 3-agent 오케스트레이터 팀 구성 |
| EP10 | 종합 실습 | 5단계 진화로 개인 AI 비서 완성! |
사용자 맞춤형 AI 에이전트예요. 메모 관리, 일정 관리, 웹 검색 등 다양한 도구를 활용해 개인 비서처럼 작동해요. 2026년 현재 OpenClaw(GitHub 스타 25만 돌파)을 비롯한 다양한 플랫폼이 이 패턴을 구현하고 있어요.
📚 참고 자료
- Claude Agent SDK 공식 문서 — SDK 전체 가이드
- SDK Hooks 문서 — PreToolUse, PostToolUse 상세 스펙
- SDK Sessions 문서 — 세션 관리 상세 가이드
- FastMCP GitHub — v3.1.0, 스타 23.6k, 일일 다운로드 100만 돌파
- EP10 전체 코드 (GitHub) — 5개 Python 파일 전체
- Building Effective Agents — Anthropic 공식 에이전트 설계 가이드
오늘 만든 5-stage 비서는 학습용이에요. 실제 프로덕션에서는 필요한 기능만 골라서 구성하는 게 좋아요. 멀티 에이전트는 API 호출이 늘어나니까요!
◀ 이전 편: 9편 — 팀워크하는 AI들: 멀티 에이전트 시스템

✅ 마무리 — 끝이 아니라 시작이에요!
10편의 여정이 끝났어요! 처음에는 “Agentic AI가 뭐야?”에서 시작해서, 이제 직접 5단계로 개인 AI 비서를 만들 수 있게 됐어요. 정말 대단해요, 여러분!
MCP로 도구 만들고, SDK로 연결하고, Hooks로 안전장치 걸고, 팀으로 확장하고, Sessions로 기억까지. 진짜 전부 다 썼네.
여기서 끝이 아니에요! 이 비서를 기반으로 확장할 수 있는 아이디어가 무궁무진해요. 이메일 도구를 추가하거나, 캘린더 API를 연동하거나, Discord 봇으로 배포할 수도 있어요. 여러분만의 AI 비서를 만들어보세요!
오늘 만든 5개 파일 전체 코드는 GitHub 리포지토리에서 확인할 수 있어요. AI 에이전트 만들기 여정이 끝났지만, 여러분의 AI 비서 개발은 이제 시작이에요! 클로디의 Agentic AI 교실, 함께해줘서 고마웠어요! 💙