Getting Started

Install the Swift SDK and run your first agent in under five minutes.

Installation

Add the package to your Package.swift dependencies:

Package.swiftSwift
dependencies: [
    .package(
        url: "https://github.com/kunal732/strands-agents-swift.git",
        branch: "master"
    )
]

Then add StrandsAgents to your target. All providers, observability, and voice streaming are included -- no separate imports needed:

Package.swiftSwift
.target(
    name: "MyApp",
    dependencies: [
        .product(name: "StrandsAgents", package: "strands-agents-swift"),
    ]
)

Quick Start

The simplest possible agent: no tools, just a model and a prompt.

main.swiftSwift
import StrandsAgents

let provider = try BedrockProvider(config: BedrockConfig(
    modelId: "us.anthropic.claude-sonnet-4-20250514-v1:0"
))

let agent = Agent(model: provider)
let result = try await agent.run("What is the capital of France?")
print(result.message.textContent ?? "")  // "Paris"

Adding Tools

Write a normal Swift function, wrap it with Tool() and a description. The tool name and parameter schema are inferred automatically:

main.swiftSwift
func wordCount(text: String) -> Int {
    text.split(whereSeparator: \.isWhitespace).count
}
let wordCountTool = Tool(wordCount, "Count the number of words in a block of text.")

func getWeather(city: String) -> String {
    return "22°C, partly cloudy in \(city)"
}
let getWeatherTool = Tool(getWeather, "Look up the current weather for a city.")

let agent = Agent(model: provider, tools: [wordCountTool, getWeatherTool])
let result = try await agent.run("How many words are in 'Hello world'? Also, what's the weather in Tokyo?")
print(result.message.textContent ?? "")
💡

Your functions stay regular Swift functions -- you can still call them directly without going through the agent.

Streaming responses

Use agent.stream() to display tokens as they arrive, instead of waiting for the full response:

main.swiftSwift
for try await event in agent.stream("Write a haiku about Swift.") {
    switch event {
    case .textDelta(let token):
        print(token, terminator: "")  // print each token as it arrives
    case .result(let final):
        print("\n\nDone in \(final.metrics.totalLatencyMs)ms")
    default:
        break
    }
}

Next Steps