MCPSwift

Un framework de Swift para construir servidores del Model Context Protocol (MCP) con una API simplificada.

Documentación

AgentKit

Un framework de Swift para construir agentes de IA con soporte para Amazon Bedrock y Model Context Protocol (MCP). AgentKit simplifica la creación de agentes de IA conversacionales que pueden usar herramientas e integrarse con servidores MCP.

Descripción general

AgentKit proporciona una API de alto nivel para construir agentes de IA que pueden:

  • Mantener conversaciones usando modelos de Amazon Bedrock
  • Usar herramientas locales para realizar acciones
  • Conectarse a servidores MCP remotos para capacidades extendidas
  • Manejar autenticación y configuración sin problemas

Requisitos

  • macOS 15 o posterior
  • Swift 6.2 o posterior
  • Credenciales de AWS configuradas

Instalación

Añade AgentKit a tu paquete de Swift:

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

1. Agente Simple

Crea un agente conversacional básico con configuración 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. Herramientas

Crea herramientas que los agentes puedan usar para realizar acciones específicas. Las herramientas se definen usando la macro @Tool.

Importante: Los comentarios de Swift DocC en los parámetros de la función handle y las propiedades de la estructura @SchemaDefinition son cruciales: se convierten en las descripciones de herramientas que los modelos de IA usan para entender cómo invocar tus herramientas correctamente.

Herramienta de Cadena Simple

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)
    }
}

Herramienta Estructurada Compleja

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)")
        }
    }
}

Herramienta de Cambio de Divisas

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 + Herramientas

Combina agentes con herramientas locales para capacidades mejoradas:

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. Exponer Herramientas como Servidor MCP

Comparte tus herramientas con otras aplicaciones creando 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 con 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

Conecta agentes a servidores MCP remotos para capacidades extendidas:

Usando Archivo de Configuración

Crea un archivo de configuración 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
        }
    }
}

Usa el archivo de configuración:

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 Directamente

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?")

Herramientas Locales y Remotas Mixtas

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. Autenticación

AgentKit admite múltiples métodos de autenticación de AWS:

Cadena de Credenciales Predeterminada

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 Nombrado

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

Credenciales Temporales

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

El archivo de credenciales temporales debe contener:

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

Región Personalizada

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

Configuración Avanzada

Modelos Personalizados

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

Prompts del 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
)

Ejemplos

El directorio Example contiene ejemplos completos y funcionales:

  • AgentClient: Demuestra varios patrones de uso de agentes
  • MCPServer: Muestra cómo crear servidores MCP con herramientas
  • MCPClient: Ilustra la conexión a servidores MCP remotos

Compila y ejecuta los ejemplos:

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

Licencia

Este proyecto está licenciado bajo la Licencia MIT; consulta el archivo LICENSE para más detalles.