15| 원하는 작업 | 수행 방법 |15| 원하는 작업 | 수행 방법 |
16| :- | :- |16| :- | :- |
17| 도구 정의 | 이름, 설명, 스키마 및 핸들러를 사용하여 [`@tool`](/docs/ko/agent-sdk/python#tool) (Python) 또는 [`tool()`](/docs/ko/agent-sdk/typescript#tool) (TypeScript)을 사용합니다. [사용자 정의 도구 만들기](#create-a-custom-tool)를 참조하세요. |17| 도구 정의 | 이름, 설명, 스키마 및 핸들러를 사용하여 [`@tool`](/docs/ko/agent-sdk/python#tool) (Python) 또는 [`tool()`](/docs/ko/agent-sdk/typescript#tool) (TypeScript)을 사용합니다. [사용자 정의 도구 만들기](#create-a-custom-tool)를 참조하세요. |
18| 매개변수를 선택 사항으로 만들기 | 스키마에서 선택 사항으로 선언하고 핸들러에서 기본값을 적용합니다. [매개변수를 선택 사항으로 만들기](#make-a-parameter-optional)를 참조하세요. |
18| Claude에 도구 등록 | `create_sdk_mcp_server` / `createSdkMcpServer`로 래핑하고 `query()`의 `mcpServers`에 전달합니다. [사용자 정의 도구 호출](#call-a-custom-tool)을 참조하세요. |19| Claude에 도구 등록 | `create_sdk_mcp_server` / `createSdkMcpServer`로 래핑하고 `query()`의 `mcpServers`에 전달합니다. [사용자 정의 도구 호출](#call-a-custom-tool)을 참조하세요. |
19| 도구 사전 승인 | 허용된 도구에 추가합니다. [허용된 도구 구성](#configure-allowed-tools)을 참조하세요. |20| 도구 사전 승인 | 허용된 도구에 추가합니다. [허용된 도구 구성](#configure-allowed-tools)을 참조하세요. |
20| Claude의 컨텍스트에서 기본 제공 도구 제거 | 원하는 기본 제공 도구만 나열하는 `tools` 배열을 전달합니다. [허용된 도구 구성](#configure-allowed-tools)을 참조하세요. |21| Claude의 컨텍스트에서 기본 제공 도구 제거 | 원하는 기본 제공 도구만 나열하는 `tools` 배열을 전달합니다. [허용된 도구 구성](#configure-allowed-tools)을 참조하세요. |
32 33
33* **이름:** Claude가 도구를 호출할 때 사용하는 고유 식별자입니다.34* **이름:** Claude가 도구를 호출할 때 사용하는 고유 식별자입니다.
34* **설명:** 도구가 수행하는 작업입니다. Claude는 이를 읽고 도구를 호출할 시기를 결정합니다.35* **설명:** 도구가 수행하는 작업입니다. Claude는 이를 읽고 도구를 호출할 시기를 결정합니다.
35* **입력 스키마:** Claude가 제공해야 하는 인수입니다. TypeScript에서는 항상 [Zod 스키마](https://zod.dev/)이며, 핸들러의 `args`는 자동으로 입력됩니다. Python에서는 `{"latitude": float}`와 같이 이름을 타입에 매핑하는 딕셔너리이며, SDK가 JSON 스키마로 변환합니다. Python 데코레이터는 열거형, 범위, 선택적 필드 또는 중첩된 객체가 필요할 때 전체 [JSON 스키마](https://json-schema.org/understanding-json-schema/about) 딕셔너리도 허용합니다.36* **입력 스키마:** 도구가 받는 인수이며, 언어별로 다음과 같이 선언합니다:
37 * **TypeScript**: [Zod 스키마](https://zod.dev/)입니다. 핸들러의 `args`는 이 스키마에서 타입을 가져옵니다. 필드에 `.describe()`를 호출하면 Claude가 보는 설명을 필드에 부여할 수 있습니다.
38 * **Python**: `{"latitude": float}`와 같이 이름을 타입에 매핑하는 딕셔너리이며, SDK가 이를 JSON 스키마로 변환합니다. `{"latitude": Annotated[float, "Latitude coordinate"]}`와 같이 타입을 `Annotated`로 감싸면 Claude가 보는 설명을 필드에 부여할 수 있습니다. 열거형, 범위, 선택적 필드 또는 중첩된 객체가 필요할 때는 데코레이터에 전체 [JSON 스키마](https://json-schema.org/understanding-json-schema/about) 딕셔너리를 직접 전달할 수도 있습니다.
36* **핸들러:** Claude가 도구를 호출할 때 실행되는 비동기 함수입니다. 검증된 인수를 받으며 다음을 포함하는 객체를 반환해야 합니다:39* **핸들러:** Claude가 도구를 호출할 때 실행되는 비동기 함수입니다. 검증된 인수를 받으며 다음을 포함하는 객체를 반환해야 합니다:
37 * `content` (필수): 각각 `"text"`, `"image"`, `"audio"`, `"resource"` 또는 `"resource_link"`의 `type`을 가진 결과 블록의 배열입니다. 텍스트가 아닌 블록은 [이미지 및 리소스 반환](#return-images-and-resources)을 참조하세요.40 * `content` (필수): 각각 `"text"`, `"image"`, `"audio"`, `"resource"` 또는 `"resource_link"`의 `type`을 가진 결과 블록의 배열입니다. 텍스트가 아닌 블록은 [이미지 및 리소스 반환](#return-images-and-resources)을 참조하세요.
38 * `structuredContent` (선택사항): 결과를 기계 판독 가능한 데이터로 보유하는 JSON 객체이며, `content`와 함께 반환됩니다. [구조화된 데이터 반환](#return-structured-data)을 참조하세요.41 * `structuredContent` (선택사항): 결과를 기계 판독 가능한 데이터로 보유하는 JSON 객체이며, `content`와 함께 반환됩니다. [구조화된 데이터 반환](#return-structured-data)을 참조하세요.
40 43
41도구를 정의한 후 [`createSdkMcpServer`](/docs/ko/agent-sdk/typescript#createsdkmcpserver) (TypeScript) 또는 [`create_sdk_mcp_server`](/docs/ko/agent-sdk/python#create_sdk_mcp_server) (Python)를 사용하여 서버에 래핑합니다. 서버는 별도의 프로세스가 아닌 애플리케이션 내에서 인프로세스로 실행됩니다.44도구를 정의한 후 [`createSdkMcpServer`](/docs/ko/agent-sdk/typescript#createsdkmcpserver) (TypeScript) 또는 [`create_sdk_mcp_server`](/docs/ko/agent-sdk/python#create_sdk_mcp_server) (Python)를 사용하여 서버에 래핑합니다. 서버는 별도의 프로세스가 아닌 애플리케이션 내에서 인프로세스로 실행됩니다.
42 45
46이 페이지에서 HTTP 요청을 수행하는 Python 예제는 [httpx](https://www.python-httpx.org/)를 사용합니다. 프로젝트에서 사용하는 패키지 관리자로 추가하세요:
47
48<Tabs>
49 <Tab title="Python (uv)">
50 ```bash theme={null}
51 uv add httpx
52 ```
53 </Tab>
54
55 <Tab title="Python (pip)">
56 ```bash theme={null}
57 pip install httpx
58 ```
59 </Tab>
60</Tabs>
61
43<h3 id="weather-tool-example">62<h3 id="weather-tool-example">
44 날씨 도구 예제63 날씨 도구 예제
45</h3>64</h3>
46 65
47이 예제는 `get_temperature` 도구를 정의하고 MCP 서버에 래핑합니다. 도구만 설정합니다. `query`에 전달하고 실행하려면 아래의 [사용자 정의 도구 호출](#call-a-custom-tool)을 참조하세요.66이 예제는 `get_temperature` 도구를 정의하고 MCP 서버에 래핑하며, 서버를 `query`에 전달하지는 않습니다. 도구를 실행하려면 아래의 [사용자 정의 도구 호출](#call-a-custom-tool)을 참조하세요.
48 67
49<CodeGroup>68<CodeGroup>
50 ```python Python theme={null}69 ```python Python theme={null}
51 from typing import Any70 from typing import Annotated, Any
52 import httpx71 import httpx
53 from claude_agent_sdk import tool, create_sdk_mcp_server72 from claude_agent_sdk import tool, create_sdk_mcp_server
54 73
57 @tool(76 @tool(
58 "get_temperature",77 "get_temperature",
59 "Get the current temperature at a location",78 "Get the current temperature at a location",
60 {"latitude": float, "longitude": float},79 {
80 "latitude": Annotated[float, "Latitude coordinate"],
81 "longitude": Annotated[float, "Longitude coordinate"],
82 },
61 )83 )
62 async def get_temperature(args: dict[str, Any]) -> dict[str, Any]:84 async def get_temperature(args: dict[str, Any]) -> dict[str, Any]:
63 async with httpx.AsyncClient() as client:85 async with httpx.AsyncClient() as client:
128 150
129전체 매개변수 세부 정보(JSON 스키마 입력 형식 및 반환 값 구조 포함)는 [`tool()`](/docs/ko/agent-sdk/typescript#tool) TypeScript 참조 또는 [`@tool`](/docs/ko/agent-sdk/python#tool) Python 참조를 참조하세요.151전체 매개변수 세부 정보(JSON 스키마 입력 형식 및 반환 값 구조 포함)는 [`tool()`](/docs/ko/agent-sdk/typescript#tool) TypeScript 참조 또는 [`@tool`](/docs/ko/agent-sdk/python#tool) Python 참조를 참조하세요.
130 152
131<Tip>153<h3 id="make-a-parameter-optional">
132 매개변수를 선택사항으로 만들려면: TypeScript에서 Zod 필드에 `.optional()`을 추가하고 핸들러에서 기본값을 적용합니다. Python에서는 딕셔너리 스키마가 모든 키를 필수로 취급하므로 스키마에서 매개변수를 생략하고, 설명 문자열에서 언급하고, 핸들러에서 `args.get()`으로 읽습니다. 아래의 [`get_precipitation_chance` 도구](#add-more-tools)는 두 패턴을 모두 보여줍니다.154 매개변수를 선택사항으로 만들기
133</Tip>155</h3>
156
157매개변수를 선택사항으로 만들려면 스키마에서 선택사항으로 선언하고 핸들러에서 기본값을 적용합니다:
158
159* **TypeScript**: Zod 필드에 `.optional()`을 추가합니다.
160* **Python**: 딕셔너리 스키마는 모든 키를 필수로 요구합니다. JSON 스키마 형식을 사용하고, 매개변수를 `required`에서 제외한 뒤 `args.get()`으로 읽습니다. 선택적 키가 있는 타입 지정 스키마는 [TypedDict 클래스](/docs/ko/agent-sdk/python#input-schema-options)를 참조하세요.
161
162[아래의 `get_precipitation_chance` 도구](#add-more-tools)는 두 패턴을 모두 보여줍니다.
134 163
135<h3 id="call-a-custom-tool">164<h3 id="call-a-custom-tool">
136 사용자 정의 도구 호출165 사용자 정의 도구 호출
182 ```211 ```
183</CodeGroup>212</CodeGroup>
184 213
185이 스니펫을 [날씨 도구 예제](#weather-tool-example)의 도구 및 서버 정의와 함께 한 파일에 결합한 후 Python의 경우 `python weather.py`로, TypeScript의 경우 `npx tsx weather.ts`로 실행합니다. Claude는 `get_temperature`를 호출하고 스크립트는 샌프란시스코의 현재 온도를 포함한 한 줄 답변을 출력합니다.214이 스니펫을 [날씨 도구 예제](#weather-tool-example)의 도구 및 서버 정의와 함께 `weather.py` 또는 `weather.ts` 한 파일에 결합한 후 터미널에서 실행합니다:
215
216<Tabs>
217 <Tab title="TypeScript">
218 ```bash theme={null}
219 npx tsx weather.ts
220 ```
221 </Tab>
222
223 <Tab title="Python (uv)">
224 ```bash theme={null}
225 uv run weather.py
226 ```
227 </Tab>
228
229 <Tab title="Python (pip)">
230 SDK를 설치한 가상 환경을 활성화한 후 다음을 실행합니다:
231
232 ```bash theme={null}
233 python weather.py
234 ```
235 </Tab>
236</Tabs>
237
238Claude는 `get_temperature`를 호출하고 스크립트는 샌프란시스코의 현재 온도를 포함한 한 줄 답변을 출력합니다.
186 239
187<h3 id="add-more-tools">240<h3 id="add-more-tools">
188 더 많은 도구 추가241 더 많은 도구 추가
197 # Define a second tool for the same server250 # Define a second tool for the same server
198 @tool(251 @tool(
199 "get_precipitation_chance",252 "get_precipitation_chance",
200 "Get the hourly precipitation probability for a location. "253 "Get the hourly precipitation probability for a location",
201 "Optionally pass 'hours' (1-24) to control how many hours to return.",254 {
202 {"latitude": float, "longitude": float},255 "type": "object",
256 "properties": {
257 "latitude": {"type": "number"},
258 "longitude": {"type": "number"},
259 "hours": {
260 "type": "integer",
261 "minimum": 1,
262 "maximum": 24,
263 "description": "How many hours of forecast to return",
264 },
265 },
266 # 'hours' is left out of required, so Claude can omit it
267 "required": ["latitude", "longitude"],
268 },
203 )269 )
204 async def get_precipitation_chance(args: dict[str, Any]) -> dict[str, Any]:270 async def get_precipitation_chance(args: dict[str, Any]) -> dict[str, Any]:
205 # 'hours' isn't in the schema - read it with .get() to make it optional271 # 'hours' isn't in required - read it with .get() to fall back to a default
206 hours = args.get("hours", 12)272 hours = args.get("hours", 12)
207 async with httpx.AsyncClient() as client:273 async with httpx.AsyncClient() as client:
208 response = await client.get(274 response = await client.get(