Follow Discord
Sweep 25 Sep 2026 · 19:33Z Build v2.1.283 504 read Stable v2.1.274 Latest v2.1.283 Next v2.1.283 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Give Claude custom tools changedagent-sdk/custom-tools

Upstream edited this page at 28 Sep 2026 00:41 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 01:07 UTC.

Upstream edited
Recorded here
Lines+9added
Lines−8removed
From line 119 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits8to this page, all time

The whole hunk

from line 119, old and new numbered
/
lines
from line 119
119119See the [`tool()`](/docs/en/agent-sdk/typescript#tool) TypeScript reference or the [`@tool`](/docs/en/agent-sdk/python#tool) Python reference for full parameter details, including JSON Schema input formats and return value structure.
120120 
121121<Tip>
122 To make a parameter optional: in TypeScript, add `.default()` to the Zod field. In Python, the dict schema treats every key as required, so leave the parameter out of the schema, mention it in the description string, and read it with `args.get()` in the handler. The [`get_precipitation_chance` tool below](#add-more-tools) shows both patterns.
122 To make a parameter optional: in TypeScript, add `.optional()` to the Zod field and apply the default in the handler. In Python, the dict schema treats every key as required, so leave the parameter out of the schema, mention it in the description string, and read it with `args.get()` in the handler. The [`get_precipitation_chance` tool below](#add-more-tools) shows both patterns.
123123</Tip>
124124 
125125### Call a custom tool
from line 234
234234 .int()
235235 .min(1)
236236 .max(24)
237 .default(12) // .default() makes the parameter optional
237 .optional() // .optional() lets Claude omit the parameter
238238 .describe("How many hours of forecast to return")
239239 },
240240 async (args) => {
241 const hours = args.hours ?? 12; // Apply the default in the handler
241242 const response = await fetch(
242243 `https://api.open-meteo.com/v1/forecast?latitude=${args.latitude}&longitude=${args.longitude}&hourly=precipitation_probability&forecast_days=1`
243244 );
244245 const data: any = await response.json();
245 const chances = data.hourly.precipitation_probability.slice(0, args.hours);
246 const chances = data.hourly.precipitation_probability.slice(0, hours);
246247 
247248 return {
248 content: [{ type: "text", text: `Next ${args.hours} hours: ${chances.join("%, ")}%` }]
249 content: [{ type: "text", text: `Next ${hours} hours: ${chances.join("%, ")}%` }]
249250 };
250251 }
251252 );
from line 444
443444 
444445### Images
445446 
446An image block carries the image bytes inline, encoded as base64. There is no URL field. To return an image that lives at a URL, fetch it in the handler, read the response bytes, and base64-encode them before returning. The result is processed as visual input.
447An image block carries the image bytes inline, encoded as base64. There is no URL field. To return an image that lives at a URL, fetch it in the handler, read the response bytes, and base64-encode them before returning. A PNG, JPEG, GIF, or WebP image reaches Claude as visual input; an image of any other type is saved to disk and Claude receives its file path as text instead.
447448 
448449| Field | Type | Notes |
449450| :--------- | :-------- | :------------------------------------------------------------------------- |
from line 511
510511 
511512### Resources
512513 
513A resource block embeds a piece of content identified by a URI. The URI is a label for Claude to reference; the actual content rides in the block's `text` or `blob` field. Use this when your tool produces something that makes sense to address by name later, such as a generated file or a record from an external system.
514A resource block embeds a piece of content identified by a URI. The actual content rides in the block's `text` or `blob` field. Use this when your tool produces a generated file or a record from an external system.
514515 
515516| Field | Type | Notes |
516517| :------------------ | :----------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
from line 521
520521| `resource.blob` | `string` | The content base64-encoded, if it's binary. TypeScript only: the Python SDK drops binary resources from the tool result and logs a warning |
521522| `resource.mimeType` | `string` | Optional |
522523 
523This example shows a resource block returned from inside a tool handler. The URI `file:///tmp/report.md` is a label that Claude can reference later; the SDK does not read from that path.
524This example shows a resource block returned from inside a tool handler. The SDK doesn't read from the example's URI, `file:///tmp/report.md`.
524525 
525526<CodeGroup>
526527 ```typescript TypeScript theme={null}
from line 545
544545 {
545546 "type": "resource",
546547 "resource": {
547 "uri": "file:///tmp/report.md", # Label for Claude to reference, not a path the SDK reads
548 "uri": "file:///tmp/report.md", # Not a path the SDK reads
548549 "mimeType": "text/markdown",
549550 "text": "# Report\n...", # The actual content, inline
550551 },
Feedback