Skip to content

Vended Tools

Vended tools are pre-built tools included directly in the Strands Harness SDK for common agent tasks like file operations, shell commands, HTTP requests, and persistent notes.

They ship as part of the SDK package and are updated alongside it. See Versioning & Maintenance for how changes are communicated and what level of backwards compatibility they maintain.

Each tool is imported from its own subpath under @strands-agents/sdk/vended-tools, with no additional packages required:

import { Agent } from '@strands-agents/sdk'
import { bash } from '@strands-agents/sdk/vended-tools/bash'
import { fileEditor } from '@strands-agents/sdk/vended-tools/file-editor'
import { httpRequest } from '@strands-agents/sdk/vended-tools/http-request'
import { notebook, makeNotebook } from '@strands-agents/sdk/vended-tools/notebook'
const agent = new Agent({
tools: [bash, fileEditor, httpRequest, notebook],
})
ToolDescriptionSupported in
EditMake in-place changes to a text filePython
File Editor (deprecated)View, create, and edit filesPython, TypeScript (Node.js)
ReadRead a file as numbered text or a media blockPython
HTTP RequestMake HTTP requests to external APIsPython, TypeScript (Node.js 22+, browsers)
NotebookManage persistent text notebooksPython, TypeScript (Node.js, browsers)
BashExecute shell commands with persistent sessionsPython, TypeScript (Node.js, Unix/Linux/macOS)
MCP RouterConnect to Model Context Protocol servers on a developer-set allowlistPython, TypeScript (Node.js)
SleepPause execution for a bounded, cancellable durationPython, TypeScript (Node.js, browsers)
Handoff to UserPause the agent loop and surface a message to the userPython, TypeScript (Node.js, browsers)
StopGracefully end the agent loop when the task is completePython, TypeScript (Node.js, browsers)
Web FetchFetch a URL and return cleaned markdown for a model to readPython, TypeScript (Node.js)
A2A ClientDiscover and send messages to remote A2A-protocol agentsPython, TypeScript (Node.js, browsers)
Python REPLExecute Python code through the agent’s sandboxPython, TypeScript (Node.js, Unix/Linux/macOS)
SubagentDelegate a self-contained task to a child agentPython, TypeScript (Node.js, browsers)
SwarmSpin up a team of agents that collaborate via the swarm patternPython, TypeScript (Node.js, browsers)
GraphRun a team of sub-agents as a directed acyclic graph designed by the modelPython

Lets your agent make surgical, in-place changes to a text file by replacing an exact, unique string (old_str must appear in the file exactly once).

The edit tool pairs with the read and write vended tools and supersedes file_editor. Available in Python today.

Example:

from strands import Agent
from strands.vended_tools import edit
agent = Agent(tools=[edit])
agent("In /tmp/hello.txt, replace 'world' with 'Strands'.")

Lets your agent read and modify files on disk: useful for coding agents, config management, or any workflow where the agent inspects output and makes targeted edits.

Example:

import { Agent } from '@strands-agents/sdk'
import { fileEditor } from '@strands-agents/sdk/vended-tools/file-editor'
const agent = new Agent({
tools: [fileEditor],
})
// Create, view, and edit files
await agent.invoke('Create a file /tmp/config.json with {"debug": false}')
await agent.invoke('Replace "debug": false with "debug": true in /tmp/config.json')
await agent.invoke('View lines 1-10 of /tmp/config.json')

Full API reference


Reads a file through the agent’s sandbox. Text files return cat -n style numbered lines so the model can cite path:line, with offset and limit for paging through large files. Images (png/jpg/jpeg/gif/webp) and binary documents (pdf/doc/docx/xls/xlsx) return as media content blocks when the model accepts media; otherwise make_read(media=False) returns a short text placeholder describing the file.

Supported in: Python.

Example:

from strands import Agent
from strands.vended_tools import read
agent = Agent(tools=[read])
agent("Read /etc/hosts and summarize what it maps.")

Lets your agent call external APIs and fetch web content. Supports all HTTP methods, custom headers, and request bodies. Default timeout is 30 seconds.

Supported in: Python; Node.js 22+, modern browsers (TypeScript).

The Python tool delegates all networking to an httpx.AsyncClient. Use the make_http_request factory to supply a pre-configured client with authentication, timeouts, redirects, proxies, or other transport-level configuration.

Example:

import { Agent } from '@strands-agents/sdk'
import { httpRequest } from '@strands-agents/sdk/vended-tools/http-request'
const agent = new Agent({
tools: [httpRequest],
})
// Make API requests
await agent.invoke('Get data from https://api.example.com/users')
await agent.invoke('Post {"name": "John"} to https://api.example.com/users')

Full API reference: TypeScript, Python


A scratchpad the agent can read and write across invocations. The most effective use is giving the agent a notebook at the start of a task and instructing it to plan its work there. It can break the task into steps, check things off as it goes, and always have a clear picture of what’s left. Notebook state is part of the agent’s state, so it persists automatically with Session Management.

Supported in: Node.js, modern browsers (TypeScript); all platforms (Python).

Example - Task Management:

import { Agent } from '@strands-agents/sdk'
import { notebook } from '@strands-agents/sdk/vended-tools/notebook'
const agent = new Agent({
tools: [notebook],
systemPrompt:
'Before starting any multi-step task, create a notebook with a checklist of steps. ' +
'Check off each step as you complete it.',
})
// The agent uses the notebook to plan and track its work
await agent.invoke('Write a project plan for building a personal budget tracker app')

Example - State Persistence:

import { Agent, SessionManager, FileStorage } from '@strands-agents/sdk'
import { notebook } from '@strands-agents/sdk/vended-tools/notebook'
const session = new SessionManager({
sessionId: 'my-session',
storage: { snapshot: new FileStorage('./sessions') },
})
const agent = new Agent({ tools: [notebook], sessionManager: session })
// Notebooks are automatically persisted as part of the session
await agent.invoke('Create a notebook called "ideas" with "# Project Ideas"')
await agent.invoke('Add "- Build a web scraper" to the ideas notebook')
// ...
// Later, a new agent with the same session restores notebooks automatically
const restoredAgent = new Agent({ tools: [notebook], sessionManager: session })
await restoredAgent.invoke('Read the ideas notebook')

Example - Custom configuration:

import { Agent } from '@strands-agents/sdk'
import { makeNotebook } from '@strands-agents/sdk/vended-tools/notebook'
const notes = makeNotebook({
name: 'notes',
maxNotebookSizeBytes: 64 * 1024, // 64 KiB
})
const agent = new Agent({ tools: [notes] })

📖 Full API Reference


Lets your agent run shell commands and act on the output. The two SDKs expose different tools here:

  • TypeScript bash spawns a persistent bash process on the host. Shell state (variables, working directory, exported functions) persists across invocations within the same session, so the agent can build up context incrementally. Sessions can be restarted to clear state.
  • Python shell (and TypeScript’s makeShell) routes each command through the agent’s Sandbox and is stateless: every call runs in a fresh shell, so variables and the working directory do not carry over. The sandbox decides the interpreter (sh locally and in Docker, the remote login shell over SSH), so use portable POSIX syntax.

Supported in: Node.js on Unix/Linux/macOS (TypeScript), all platforms (Python).

Example - File Operations:

import { Agent } from '@strands-agents/sdk'
import { bash } from '@strands-agents/sdk/vended-tools/bash'
const agent = new Agent({
tools: [bash],
})
// List files and create a new file
await agent.invoke('List all files in the current directory')
await agent.invoke('Create a new file called notes.txt with "Hello World"')

Example - Session Persistence (TypeScript):

import { Agent } from '@strands-agents/sdk'
import { bash } from '@strands-agents/sdk/vended-tools/bash'
const agent = new Agent({
tools: [bash],
})
// Variables persist across invocations within the same session
await agent.invoke('Run: export MY_VAR="hello"')
await agent.invoke('Run: echo $MY_VAR') // Will show "hello"
// Restart session to clear state
await agent.invoke('Restart the bash session')
await agent.invoke('Run: echo $MY_VAR') // Variable will be empty

Full API reference: shell, bash (TypeScript only)


Pauses the agent for a bounded number of seconds. Cancelling the enclosing invocation aborts the sleep immediately rather than waiting for the full duration, so a long timer never ties up a session the caller has moved on from.

Supported in: Node.js, modern browsers (TypeScript); all platforms (Python).

The maximum duration is configurable at construction (default: 60 seconds) and cannot be raised by the model. Negative, NaN, infinite, non-numeric, and boolean durations are rejected at the tool boundary.

Example:

import { Agent } from '@strands-agents/sdk'
import { sleep } from '@strands-agents/sdk/vended-tools/sleep'
const agent = new Agent({
tools: [sleep],
})
await agent.invoke('Pause for two seconds, then continue.')

Custom maximum:

import { Agent } from '@strands-agents/sdk'
import { makeSleep } from '@strands-agents/sdk/vended-tools/sleep'
const shortSleep = makeSleep({ maxDuration: 5 })
const agent = new Agent({ tools: [shortSleep] })

Full API reference


Lets the model pause the agent loop and surface a message to the user for human-in-the-loop input. Use this when the agent needs explicit confirmation, additional information, or user approval before proceeding.

Supported in: Node.js, modern browsers (TypeScript); all platforms (Python).

The loop halts with a stop_reason / stopReason of "interrupt" and the message is available on the interrupt’s reason field in AgentResult.interrupts. Resume the agent by passing back an interruptResponse content block with the interrupt ID and the user’s reply; the tool then returns that reply as its result and the model continues. To recognize a handoff interrupt, match its name against the exported HANDOFF_INTERRUPT_NAME constant.

Example:

import { Agent, InterruptResponseContent } from '@strands-agents/sdk'
import {
handoffToUser,
HANDOFF_INTERRUPT_NAME,
} from '@strands-agents/sdk/vended-tools/handoff-to-user'
const agent = new Agent({
tools: [handoffToUser],
systemPrompt:
'Before deleting any files, call handoff_to_user to confirm with the user.',
})
let result = await agent.invoke('Delete all .tmp files in /workspace.')
const interrupt = result.interrupts?.find((i) => i.name === HANDOFF_INTERRUPT_NAME)
if (interrupt) {
console.log(interrupt.reason)
result = await agent.invoke([
new InterruptResponseContent({ interruptId: interrupt.id, response: 'confirmed' }),
])
}

📖 Full API Reference


Lets the model gracefully end the agent loop with an optional final message. The default loop already terminates when the model returns without any tool call; the stop tool is useful when you want an explicit “I am done” affordance, when a workflow enforces that termination is a deliberate model decision, or when a sub-agent needs to signal completion back to a coordinator via the loop’s last assistant message.

Supported in: Node.js, modern browsers (TypeScript); all platforms (Python).

This is a cooperative stop, not an abort. Any other tools the model requested in the same turn still run to completion; the loop halts after that batch without calling the model again. The final message defaults to a 4096-character cap; pass max_message_length / maxMessageLength to make_stop / makeStop when a longer summary is legitimate.

The two SDKs shim onto different loop-termination primitives, which produces a small difference in the final AgentResult’s stop reason. TypeScript halts via AfterToolsEvent.endTurn and returns stopReason: "endTurn". Python halts via agent.cancel(message=..., after_current_tools=True) and returns stop_reason: "cancelled". In both cases the stop text is appended as the last assistant message.

Example:

import { Agent } from '@strands-agents/sdk'
import { stop } from '@strands-agents/sdk/experimental/vended-tools/stop'
const agent = new Agent({
tools: [stop],
systemPrompt: 'Complete the task. Call stop with a short summary when you are done.',
})
await agent.invoke('Summarize the changes in ./CHANGELOG.md')

Full API reference


Fetches an HTTP(S) URL and returns its content. Two modes are available, configured at construction time via make_web_fetch / makeWebFetch:

  • agentic (default): HTML is converted to markdown and passed to an analyst agent that answers a prompt, so the full page never enters the main agent’s context. Use when targeted answers are needed about potentially large pages.
  • markdown: HTML is converted to clean markdown with scripts, styles, and noise stripped. Use when the agent needs full pages for reasoning.

The max_bytes / maxBytes parameter caps the HTTP response size (default 5 MiB); max_content_chars / maxContentChars caps the extracted content delivered to the model or analyst (default 50,000 characters). For mode='agentic' / mode: 'agentic', the factory also accepts a model for the analyst; agent.aux_modelagent.auxModel is used when none is supplied.

The Python tool delegates all networking to an httpx.AsyncClient. Use the make_web_fetch factory to supply a pre-configured client with custom timeouts, redirects, proxies, or caching.

Supported in: Node.js (TypeScript); Python (all platforms).

Example:

import { Agent } from '@strands-agents/sdk'
import { webFetch } from '@strands-agents/sdk/vended-tools/web-fetch'
const agent = new Agent({ tools: [webFetch] })
await agent.invoke('Summarize https://example.com/blog/post')

Reading the full page as markdown:

import { Agent } from '@strands-agents/sdk'
import { makeWebFetch } from '@strands-agents/sdk/vended-tools/web-fetch'
const webFetch = makeWebFetch({ mode: 'markdown' })
const agent = new Agent({ tools: [webFetch] })
await agent.invoke('Read https://example.com/docs and explain the architecture')

Tighter response cap with a dedicated analyst model:

import { Agent } from '@strands-agents/sdk'
import { makeWebFetch } from '@strands-agents/sdk/vended-tools/web-fetch'
import { BedrockModel } from '@strands-agents/sdk/models/bedrock'
const webFetch = makeWebFetch({
mode: 'agentic',
maxBytes: 1 * 1024 * 1024,
maxContentChars: 25_000,
model: new BedrockModel({ modelId: 'us.amazon.nova-micro-v1:0' }),
})
const agent = new Agent({ tools: [webFetch] })

📖 Full API Reference


Lets your agent connect to Model Context Protocol servers at runtime, list the tools they expose, invoke one, and disconnect. The factory takes a developer-set allowlist of server configurations; the model can only initiate connections to servers on that list.

The tool exposes five commands: connect (opens a named connection to an allowlisted server using a connection_id), list_connections (returns all open connection IDs for the current agent), list_tools (returns the tools the server exposes), call_tool (invokes a tool by name), and disconnect (closes a connection).

Connections are scoped per agent and persist across invocations on the same agent instance. A connection is closed when the model calls disconnect explicitly, or when the agent is garbage collected. The connection remains open otherwise.

Supported in: Node.js (TypeScript); all platforms (Python).

Example:

import { Agent } from '@strands-agents/sdk'
import { makeMcpRouter } from '@strands-agents/sdk/vended-tools/mcp-router'
const mcpRouter = makeMcpRouter({
servers: {
files: {
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
},
'my-api': { url: 'https://mcp.example.com/mcp' },
},
maxConnections: 5,
})
const agent = new Agent({ tools: [mcpRouter] })
await agent.invoke(
"Connect to 'files', list its tools, " +
'call the read_file tool on /tmp/hello.txt, then disconnect.'
)

Lets your agent discover and communicate with remote A2A (Agent-to-Agent) protocol agents. Two operations are available:

  • discover — fetches the agent card from a remote A2A endpoint and returns its capabilities, name, description, and skills.
  • send_message — sends a text message to a remote A2A agent and returns the response.

The tool is stateless: a fresh A2AAgent is created on every call using the per-endpoint configuration. Use make_a2a_client / makeA2AClient to control which endpoints the model may contact, with per-endpoint authentication, and to tune size limits.

Supported in: Python, TypeScript (Node.js, browsers).

Example:

import { Agent } from '@strands-agents/sdk'
import {
ClientFactory,
DefaultAgentCardResolver,
JsonRpcTransportFactory,
RestTransportFactory,
createAuthenticatingFetchWithRetry,
} from '@a2a-js/sdk/client'
import { makeA2AClient } from '@strands-agents/sdk/vended-tools/a2a-client'
const authFetch = createAuthenticatingFetchWithRetry(fetch, {
headers: async () => ({ Authorization: 'Bearer your-token' }),
shouldRetryWithHeaders: async () => undefined,
})
const a2aClient = makeA2AClient({
allowedEndpoints: [
// No auth needed
'https://agent.example.com',
// Custom ClientFactory for authenticated requests
[
'https://researcher.example.com',
new ClientFactory({
transports: [
new JsonRpcTransportFactory({ fetchImpl: authFetch }),
new RestTransportFactory({ fetchImpl: authFetch }),
],
cardResolver: new DefaultAgentCardResolver({ fetchImpl: authFetch }),
}),
],
],
})
const agent = new Agent({ tools: [a2aClient] })
await agent.invoke('What has the research agent found recently?')

Full API reference: TypeScript


Runs model-generated Python through the agent’s sandbox by calling sandbox.execute_code(code, "python3") (sandbox.executeCode(code, 'python3') in TypeScript). It returns output (stdout), error (stderr, including tracebacks), and exit_code. Each call runs in a fresh interpreter, so variables, imports, and definitions do not persist across calls. Files written to the sandbox filesystem do persist, so the model can checkpoint intermediate results to disk and load them in a later call.

Supported in: Node.js on Unix/Linux/macOS (TypeScript), Python.

import { Agent } from '@strands-agents/sdk'
import { pythonRepl } from '@strands-agents/sdk/vended-tools/python-repl'
const agent = new Agent({ tools: [pythonRepl] })
await agent.invoke(
'Use python_repl to compute the first 10 Fibonacci numbers and print them.'
)

Bound sandbox or custom interpreter:

import { Agent } from '@strands-agents/sdk'
import { DockerSandbox } from '@strands-agents/sdk/sandbox/docker'
import { makePythonRepl } from '@strands-agents/sdk/vended-tools/python-repl'
const pythonRepl = makePythonRepl(new DockerSandbox({ container: 'my-container' }), {
language: 'python3.12',
})
const agent = new Agent({ tools: [pythonRepl] })

Full API reference


Delegates a self-contained task to a child agent that runs in its own context and returns a final report. Use it when a subtask would otherwise flood the parent’s context with intermediate work and you only need the conclusion. The model writes the task each time it calls the tool; the child cannot ask follow-up questions, so the task must include all the context it needs.

The make_subagentmakeSubagent factory uses axis policies to control what the model can configure on each child. The configurable axes are instructions, tools, model, and context. The parent also passes a task to the child.

By default, the child sees only the task (context=Fixed("none")context: new Fixed('none')), but you can share the parent’s conversation by setting context to a Choice over "none", "all" (full history including tool calls), and "no_tools" (text turns only). When a non-"none" option is available, the model can also pass last_messages to limit how many parent messages to share.

Supported in: Python, TypeScript (Node.js, browsers).

Quickstart example:

import { Agent } from '@strands-agents/sdk'
import { subagent } from '@strands-agents/sdk/vended-tools/subagent'
const agent = new Agent({
systemPrompt: 'You are a manager.',
tools: [subagent],
})
await agent.invoke('Research the latest TypeScript 5.x features and summarize them.')

Example — full control with make_subagentmakeSubagent:

import { Agent } from '@strands-agents/sdk'
import { Choice, Option, Preset } from '@strands-agents/sdk/multiagent'
import { makeSubagent } from '@strands-agents/sdk/vended-tools/subagent'
const subagent = makeSubagent({
presets: {
researcher: new Preset({
instructions: 'You research topics thoroughly.',
description: 'deep research on a topic',
}),
reviewer: new Preset({
instructions: 'You review code for correctness and style.',
description: 'code review',
}),
},
model: new Choice([
new Option('fast', 'global.anthropic.claude-sonnet-4-6', 'quick tasks'),
new Option('deep', 'global.anthropic.claude-opus-4-6-v1', 'hard problems'),
]),
context: new Choice(['none', 'all', 'no_tools']),
tools: new Choice(['read', 'shell', 'write'], true),
maxDepth: 3,
})
const agent = new Agent({ tools: [subagent] })
await agent.invoke('Review the changes in src/main.ts for correctness.')

Full API reference: TypeScript

Lets your agent design and run a team of sub-agents as a Graph. The model supplies a task, a list of nodes (each with a unique name and its own instructions), and edges that order them. Nodes with no upstream nodes start in parallel, and each node receives its upstream outputs.

Nodes inherit the caller’s model and tools, including MCP tools, except graph tools. Child interrupts pause the tool call and resume with the user’s response. An interrupted graph is saved in the parent agent’s interrupt state, so it can resume after the parent is restored from a snapshot or session. By default, a call times out after 900 seconds and each node after 300 seconds. A running graph cannot be cancelled from the parent agent.

Example:

from strands import Agent
from strands.vended_tools import graph, http_request
agent = Agent(tools=[graph, http_request])
agent("Research three competing vector databases in parallel, then write a comparison table.")

Use make_graph to set limits (max_nodes, max_edges, max_node_executions, execution_timeout, node_timeout), build each node agent yourself with builder, or control what the model configures on each node with axis policies over instructions, tools, and model.

Custom configuration:

from strands import Agent
from strands.multiagent import Choice, Preset
from strands.vended_tools import file_editor, http_request, make_graph
team = make_graph(
presets={
"researcher": Preset(
instructions="Gather facts from the web and cite every source.",
tools=["http_request"],
description="Finds and summarizes sources.",
),
"writer": Preset(
instructions="Turn upstream findings into clear prose.",
tools=["file_editor"],
description="Drafts the final document.",
),
},
tools=Choice(["http_request", "file_editor"], multiple=True),
max_nodes=6,
max_edges=10,
execution_timeout=600,
node_timeout=120,
)
agent = Agent(tools=[team, http_request, file_editor])

Lets your agent spin up a team of specialised sub-agents that collaborate autonomously via handoffs to solve a complex task. This is a meta-agent tool where the model defines each agent’s name and role; the tool resolves those specs through an authority-mode system, builds the agents, runs the swarm, and returns a consolidated result.

Use the factory to control safety limits, lock down instructions or tools with axis policies, or supply named presets the model can select from.

Supported in: Python, TypeScript (Node.js, browsers).

Example:

import { Agent } from '@strands-agents/sdk'
import { swarm } from '@strands-agents/sdk/vended-tools/swarm'
const agent = new Agent({ tools: [swarm] })
await agent.invoke(
'Research the pros and cons of microservices vs monoliths and write a summary'
)

Custom configuration with makeSwarm. maxAgents caps agents per call; the other limits pass through to Swarm: maxSteps caps total agent executions, and timeout and nodeTimeout are in milliseconds.

import { Agent } from '@strands-agents/sdk'
import { Choice, Fixed, Inherit, Preset } from '@strands-agents/sdk/multiagent'
import { makeSwarm } from '@strands-agents/sdk/vended-tools/swarm'
import { httpRequest } from '@strands-agents/sdk/vended-tools/http-request'
import { webFetch } from '@strands-agents/sdk/vended-tools/web-fetch'
const swarm = makeSwarm({
presets: {
researcher: new Preset({
instructions: 'You search for and synthesise information.',
tools: ['http_request', 'web_fetch'],
description: 'Gathers raw information from the web.',
}),
writer: new Preset({
instructions: 'You write clear, engaging prose.',
description: 'Turns research into polished text.',
}),
},
defaultPreset: 'researcher',
instructions: new Choice([
'You are a researcher.',
'You are a writer.',
'You are an editor.',
]),
tools: new Inherit(),
model: new Fixed('us.amazon.nova-pro-v1:0'),
maxAgents: 5,
maxSteps: 15,
timeout: 300_000,
nodeTimeout: 120_000,
repetitiveHandoffDetectionWindow: 6,
repetitiveHandoffMinUniqueAgents: 3,
})
const agent = new Agent({ tools: [swarm, httpRequest, webFetch] })
await agent.invoke('Write a blog post about AI agents')

Full API reference: TypeScript


Some vended tools let the model configure child agents at runtime. Axis policies control how much freedom the model has over each parameter. Import them from strands.multiagent@strands-agents/sdk/multiagent.

PolicyEffectModel sees a parameter?
Inherit()new Inherit()Child inherits the parent’s valueNo
Fixed(value)new Fixed(value)Developer pins the valueNo
Open()new Open()Model writes a free-form valueYes (string)
Choice([...], multiple=True)new Choice([...], true)Model picks from a setYes (enum)

Use Option inside a Choice to map model-facing names to runtime values. Bundle axis defaults into a Preset that the model selects via agent_type. When the model omits both agent_type and instructions, the child uses default_presetdefaultPreset, or the first preset if none is set.

Tools that accept axis policies use a default builder to turn resolved specs into child agents. By default, it produces child agents that inherit the parent’s tools, model, and interventions, so a child’s tool calls go through the same approval and authorization checks as the parent’s. Each child gets context_manager="auto"contextManager: 'auto' (unless its model is stateful) in place of the parent’s context-management tools, and accesses the parent’s long-term memory through inherited memory tools.

To replace the default builder, pass any callable that takes an AgentSpec and returns an Agent. A custom builder decides everything the child inherits, including interventions.


Combine vended tools in one agent to cover a multi-step workflow:

import { Agent } from '@strands-agents/sdk'
import { bash } from '@strands-agents/sdk/vended-tools/bash'
import { fileEditor } from '@strands-agents/sdk/vended-tools/file-editor'
import { notebook } from '@strands-agents/sdk/vended-tools/notebook'
const agent = new Agent({
tools: [bash, fileEditor, notebook],
systemPrompt: [
'You are a software development assistant.',
'When given a feature to implement:',
'1. Use the notebook tool to create a plan with a checklist of steps',
'2. Work through each step, checking them off as you go',
'3. Use the bash tool to run tests and verify your changes',
].join('\n'),
})
// Agent plans the work, implements it, and tracks progress
await agent.invoke(
'Add input validation to the createUser function in src/users.ts. ' +
'It should reject empty names and invalid email formats.'
)

Vended tools ship as part of the SDK and are updated alongside it. Report bugs and feature requests in the GitHub repository.

Tool names are stable and will not change. In minor versions, a tool’s description, spec, or parameters may be updated to improve effectiveness. These changes are noted in SDK release notes. Pin your SDK version and test after upgrades if your workflows depend on specific tool behavior.