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.