MCPSwift

Um framework Swift para construir servidores do Model Context Protocol (MCP) com uma API simplificada.

Documentação

AgentKit

Um framework Swift para construir agentes de IA com suporte a Amazon Bedrock e Model Context Protocol (MCP). O AgentKit simplifica a criação de agentes de IA conversacionais que podem usar ferramentas e integrar-se a servidores MCP.

Visão Geral

O AgentKit fornece uma API de alto nível para construir agentes de IA que podem:

  • Ter conversas usando modelos Amazon Bedrock
  • Usar ferramentas locais para executar ações
  • Conectar-se a servidores MCP remotos para capacidades estendidas
  • Lidar com autenticação e configuração de forma transparente

Requisitos

  • macOS 15 ou posterior
  • Swift 6.2 ou posterior
  • Credenciais AWS configuradas

Instalação

Adicione o AgentKit ao seu pacote Swift:

dependencies: [
    .package(url: "https://github.com/sebsto/AgentKit", from: "1.0.0")
]

1. Agente Simples

Crie um agente conversacional básico com configuração mínima:

import AgentKit

// Simple one-liner - agent responds to stdout
try await Agent("Tell me about Swift 6")

// Two-step approach
let agent = try await Agent()
try await agent("Tell me about Swift 6")

// With custom authentication and region
try await Agent(
    "Tell me about Swift 6", 
    auth: .sso("my-profile"), 
    region: .eucentral1
)

// With callback for custom output handling
let agent = try await Agent()
try await agent("Tell me about Swift 6") { event in
    print(event, terminator: "")
}

// Streaming approach
let agent = try await Agent()
for try await event in agent.streamAsync("Tell me about Swift 6") {
    switch event {
    case .text(let text):
        print(text, terminator: "")
    default:
        break
    }
}

2. Ferramentas

Crie ferramentas que os agentes podem usar para executar ações específicas. As ferramentas são definidas usando a macro @Tool.

Importante: Os comentários Swift DocC nos parâmetros da função handle e nas propriedades da struct @SchemaDefinition são cruciais - eles se tornam as descrições das ferramentas que os modelos de IA usam para entender como invocar suas ferramentas corretamente.

Ferramenta de String Simples

import AgentKit

@Tool(
    name: "weather",
    description: "Get detailed weather information for a city."
)
struct WeatherTool {
    /// Get weather information for a specific city
    /// - Parameter input: The city name to get the weather for
    func handle(input city: String) async throws -> String {
        let weatherURL = "http://wttr.in/\(city)?format=j1"
        let url = URL(string: weatherURL)!
        let (data, _) = try await URLSession.shared.data(from: url)
        return String(decoding: data, as: UTF8.self)
    }
}

Ferramenta Estruturada Complexa

import AgentKit

@SchemaDefinition
struct CalculatorInput: Codable {
    /// The first operand of the operation
    let a: Double
    /// The second operand of the operation
    let b: Double
    /// The arithmetic operation: "add", "subtract", "multiply", "divide"
    let operation: String
}

@Tool(
    name: "calculator",
    description: "Performs basic arithmetic operations",
    schema: CalculatorInput.self
)
struct CalculatorTool {
    func handle(input: CalculatorInput) async throws -> Double {
        switch input.operation {
        case "add":
            return input.a + input.b
        case "subtract":
            return input.a - input.b
        case "multiply":
            return input.a * input.b
        case "divide":
            guard input.b != 0 else {
                throw MCPServerError.invalidParam("b", "Cannot divide by zero")
            }
            return input.a / input.b
        default:
            throw MCPServerError.invalidParam("operation", "Unknown operation: \(input.operation)")
        }
    }
}

Ferramenta de Câmbio de Moedas

import AgentKit

@SchemaDefinition
struct FXRatesInput: Codable {
    /// The source currency code (e.g., USD, EUR, GBP)
    let sourceCurrency: String
    /// The target currency code (e.g., USD, EUR, GBP)
    let targetCurrency: String
}

@Tool(
    name: "foreign_exchange_rates",
    description: "Get current foreign exchange rates between two currencies",
    schema: FXRatesInput.self
)
struct FXRateTool {
    func handle(input: FXRatesInput) async throws -> String {
        let fxURL = "https://hexarate.paikama.co/api/rates/latest/\(input.sourceCurrency)?target=\(input.targetCurrency)"
        let url = URL(string: fxURL)!
        let (data, _) = try await URLSession.shared.data(from: url)
        return String(decoding: data, as: UTF8.self)
    }
}

3. Agente + Ferramentas

Combine agentes com ferramentas locais para capacidades aprimoradas:

import AgentKit

// Create agent with multiple tools
let agent = try await Agent(tools: [
    WeatherTool(), 
    FXRateTool(), 
    CalculatorTool()
])

// Use the tools through natural conversation
try await agent("What is the weather in Paris today?")
try await agent("How much is 100 USD in EUR?")
try await agent("What is 15 * 23?")

4. Expondo Ferramentas como Servidor MCP

Compartilhe suas ferramentas com outros aplicativos criando servidores MCP:

Servidor STDIO

import AgentKit

@main
struct MyMCPServer {
    static func main() async throws {
        try await MCPServer.withMCPServer(
            name: "MyToolServer",
            version: "1.0.0",
            transport: .stdio,
            tools: [
                WeatherTool(),
                CalculatorTool(),
                FXRateTool()
            ]
        ) { server in
            try await server.run()
        }
    }
}

Servidor HTTP

import AgentKit

@main
struct MyHTTPServer {
    static func main() async throws {
        try await MCPServer.withMCPServer(
            name: "MyToolServer",
            version: "1.0.0",
            transport: .http(port: 8080),
            tools: [
                WeatherTool(),
                CalculatorTool(),
                FXRateTool()
            ]
        ) { server in
            try await server.run()
        }
    }
}

Servidor com Prompts

import AgentKit

let weatherPrompt = try! MCPPrompt.build { builder in
    builder.name = "current-weather"
    builder.description = "Get current weather for a city"
    builder.text("What is the weather today in {city}?")
    builder.parameter("city", description: "The name of the city")
}

@main
struct MyServerWithPrompts {
    static func main() async throws {
        try await MCPServer.withMCPServer(
            name: "MyToolServer",
            version: "1.0.0",
            transport: .stdio,
            tools: [WeatherTool()],
            prompts: [weatherPrompt]
        ) { server in
            try await server.run()
        }
    }
}

5. Agente + Servidores MCP

Conecte agentes a servidores MCP remotos para capacidades estendidas:

Usando Arquivo de Configuração

Crie um arquivo de configuração JSON (mcp-config.json):

{
    "mcpServers": {
        "weather-server": {
            "command": "./weather-server",
            "args": [],
            "disabled": false,
            "timeout": 60000
        },
        "calculator-server": {
            "url": "http://127.0.0.1:8080/mcp",
            "disabled": false,
            "timeout": 60000
        }
    }
}

Use o arquivo de configuração:

import AgentKit

let configFile = URL(fileURLWithPath: "./mcp-config.json")
let agent = try await Agent(mcpConfigFile: configFile)

print("Agent has \(agent.tools.count) tools available")
agent.tools.forEach { tool in
    print("- \(tool.toolName)")
}

try await agent("What is the weather in London and what is 25 * 4?")

Usando MCPServerConfiguration

import AgentKit

let config = MCPServerConfiguration()
config.addServer(
    name: "weather-server",
    command: "./weather-server",
    args: []
)
config.addServer(
    name: "calculator-server", 
    url: "http://127.0.0.1:8080/mcp"
)

let agent = try await Agent(mcpConfig: config)
try await agent("Get weather for Berlin and calculate 100 * 1.2")

Usando MCPClient Diretamente

import AgentKit

// Create individual MCP clients
let weatherClient = try await MCPClient(
    command: "./weather-server",
    args: [],
    name: "weather-server"
)

let calculatorClient = try await MCPClient(
    url: "http://127.0.0.1:8080/mcp",
    name: "calculator-server"
)

// Use clients with agent
let agent = try await Agent(mcpTools: [weatherClient, calculatorClient])
try await agent("What's the weather in Tokyo and what is 50 divided by 2?")

Ferramentas Locais e Remotas Mistas

import AgentKit

let agent = try await Agent(
    tools: [WeatherTool()],  // Local tools
    mcpConfigFile: URL(fileURLWithPath: "./remote-servers.json")  // Remote tools
)

try await agent("Compare weather in Paris with currency rates USD to EUR")

6. Autenticação

O AgentKit suporta vários métodos de autenticação AWS:

Cadeia de Credenciais Padrão

let agent = try await Agent(auth: .default)

AWS SSO

let agent = try await Agent(auth: .sso("my-sso-profile"))
// or with default profile
let agent = try await Agent(auth: .sso(nil))

Perfil Nomeado

let agent = try await Agent(auth: .profile("my-aws-profile"))

Credenciais Temporárias

let agent = try await Agent(auth: .tempCredentials("/path/to/credentials.json"))

O arquivo de credenciais temporárias deve conter:

{
    "accessKeyId": "AKIA...",
    "secretAccessKey": "...",
    "sessionToken": "...",
    "expiration": "2024-01-01T00:00:00Z"
}

Região Personalizada

let agent = try await Agent(
    auth: .sso("my-profile"),
    region: .eucentral1
)

Configuração Avançada

Modelos Personalizados

let agent = try await Agent(
    model: .claude_haiku_v3,
    auth: .sso("my-profile")
)

Prompts de Sistema

let agent = try await Agent(
    systemPrompt: "You are a helpful assistant specialized in weather and finance.",
    tools: [WeatherTool(), FXRateTool()]
)

Registro Personalizado

import Logging

var logger = Logger(label: "MyAgent")
logger.logLevel = .debug

let agent = try await Agent(
    tools: [WeatherTool()],
    logger: logger
)

Exemplos

O diretório Example contém exemplos completos e funcionais:

  • AgentClient: Demonstra vários padrões de uso de agentes
  • MCPServer: Mostra como criar servidores MCP com ferramentas
  • MCPClient: Ilustra a conexão a servidores MCP remotos

Compile e execute os exemplos:

cd Example
swift build
.build/debug/AgentClient
.build/debug/MCPServer
.build/debug/MCPClient

Licença

Este projeto é licenciado sob a Licença MIT - consulte o arquivo LICENSE para obter detalhes.