Agent SDK로 커스텀 도구 정의하기

Agent SDK로 커스텀 도구 정의하기

Anthropic Agent SDK에서 프로세스 내 MCP 서버(인프로세스 서버)를 만들어 애플리케이션 로직을 에이전트에 도구로 노출시키는 방법을 다루는 가이드예요. Python 데코레이터(@mcp_server.tool())와 TypeScript 체이닝(mcp_server.tool(...)) 두 방식으로 같은 패턴을 구현해요. MCP를 쓰지 않고 LLM이 호출할 수 있는 직접 도구(python @tool / TS defineTool 등)와 대비되는 인프로세스 서버 방식이에요.

출처: 공식문서

본문

Python — 인프로세스 MCP 서버

Python에서는 FastMCP@mcp_server.tool 데코레이터로 서버를 만들고, 이를 Agentmcp_servers 파라미터에 연결해요.

from typing import Annotated, Any
import random
import mcp.types as types
from mcp.server.fastmcp import FastMCP
from enum import Enum

from anthropic import Agent

class Unit(Enum):
    CELSIUS = "celsius"
    FAHRENHEIT = "fahrenheit"

mcp_server = FastMCP("weather")

@mcp_server.tool()
async def get_weather(
    city: Annotated[str, types.Field(description="확인할 도시")] = "Seoul",
    unit: Annotated[Unit, types.Field(description="온도 단위")] = Unit.CELSIUS,
) -> dict[str, Any]:
    """주어진 도시의 현재 날씨를 반환합니다."""
    return {
        "city": city,
        "temperature": round(random.uniform(-10, 40), 1),
        "unit": unit.value,
        "conditions": random.choice(["맑음", "흐림", "비", "눈"]),
    }

agent = Agent(
    type="generic",
    id="weather-agent",
    systemPrompt="사용자가 날씨를 물으면 weather 도구를 호출하세요.",
    mcp_servers=[mcp_server],
)

result = await agent.run("서울 날씨 알려줘 (화씨로)")
print(result)

FastMCP("weather")가 서버를 만들고, @mcp_server.tool() 데코레이터가 함수를 호출 가능한 도구로 등록해요. Annotated[..., types.Field(description=...)]로 도구 입력 스키마에 필드 설명을 더하고, Enum 타입은 자동으로 허용 값 목록으로 변환돼요. mcp_servers=[mcp_server]로 이 서버를 에이전트에 연결해 도구로 노출시켜요.

TypeScript — 프로세스 내 MCP 서버

TypeScript에서는 mcpServer와 체이닝된 .tool() 호출로 서버를 만들고, Agent 생성자에 mcpServers 배열로 전달해요.

import { Agent } from "@anthropic-ai/sdk";
import { mcpServer } from "@anthropic-ai/sdk/server";
import { z } from "zod";

const weatherServer = mcpServer("weather");

weatherServer.tool(
  "get_weather",
  "주어진 도시의 현재 날씨를 반환합니다.",
  {
    city: z.string().default("Seoul").describe("확인할 도시"),
    unit: z.enum(["celsius", "fahrenheit"]).default("celsius").describe("온도 단위"),
  },
  async (params) => {
    const unit = params.unit ?? "celsius";
    return {
      content: [{ type: "text", text: `날씨: ${params.city}, 25도 ${unit}` }],
    };
  }
);

const agent = new Agent({
  type: "generic",
  id: "weather-agent",
  systemPrompt: "사용자가 날씨를 물으면 weather 도구를 호출하세요.",
  mcpServers: [weatherServer],
});

const result = await agent.run("서울 날씨 알려줘 (화씨로)");
console.log(result);

mcpServer("weather")로 서버 인스턴스를 만들고 .tool(name, description, inputSchema, handler)로 도구를 등록해요. 스키마는 zod로 정의하고, params가 실행 시 입력 값이에요. mcpServers 배열로 에이전트에 넘기면 도구로 병합돼요.

도구로서 노출되기 위한 요구 사항

프로세스 내 서버에서 정의한 도구가 에이전트에 노출되려면:

  • Python: @mcp_server.tool()로 장식된 함수 — 서명이 명확해야 하고, Annotated 필드 설명과 Enum/기본값으로 입력 스키마가 풍부해야 도구 호출 품질이 좋아져요.
  • TypeScript: .tool() 체인 호출 — 이름·설명·zod 입력 스키마·핸들러가 모두 필요해요.
  • 도구 설명이 구체적일수록 모델이 언제 호출할지 잘 판단해요. 모호하면 에이전트가 도구를 놓치거나 남용해요.

기본값이 있는 매개변수는 선택 입력이 되고, 설명이 없는 매개변수는 자유 형식 입력이 돼요. 인프로세스 서버는 별도 프로세스·인증·네트워크 없이 같은 프로세스 안에서 실행되므로 배포와 보안 설계가 단순해져요.

더 알아보기