A Swift library for building Model Context Protocol (MCP) servers.
MCPToolbox provides a simple, type-safe API for creating MCP servers that can expose tools, resources, and prompts to AI assistants like Claude.
- Tools: Define callable functions with JSON Schema input validation
- Resources: Expose static and dynamic data via URI-based access
- Resource Templates: Support parameterized URIs with
{placeholder}syntax - Prompts: Create reusable message templates for AI interactions
- Elicitation: Request user input from clients during tool execution
- Streamable HTTP Transport: HTTP/SSE-based communication (MCP 2025-11-25)
- Actor-based Concurrency: Thread-safe by design with Swift actors
- Full DocC Documentation: Comprehensive documentation for all public APIs
- Swift 6.0+
- macOS 14.0+ / Linux
Add MCPToolbox to your Package.swift:
dependencies: [
.package(url: "https://github.com/example/MCPToolbox.git", from: "1.0.0")
]Then add it to your target:
.target(
name: "YourTarget",
dependencies: ["MCPToolbox"]
)import MCPToolbox
let server = MCPServer(
name: "my-server",
version: "1.0.0",
host: "127.0.0.1",
port: 8080
)
// Register your tools, resources, and prompts
await server.registerTool(MyTool())
await server.registerResource(MyResource())
await server.registerPrompt(MyPrompt())
// Start the server
try await server.start()struct AddTool: MCPToolHandler {
let name = "add"
let description = "Add two numbers together"
let inputSchema = JSONSchema.object(
properties: [
"a": .number(description: "First number"),
"b": .number(description: "Second number")
],
required: ["a", "b"]
)
func execute(arguments: [String: JSONValue]) async throws -> CallToolResult {
guard let a = arguments["a"]?.doubleValue,
let b = arguments["b"]?.doubleValue else {
throw ToolError.invalidArguments("Both 'a' and 'b' must be numbers")
}
return .text("Result: \(a + b)")
}
}struct ConfigResource: MCPResourceHandler {
let uri = "config://app"
let name = "Application Configuration"
let description: String? = "Current app settings"
let mimeType: String? = "application/json"
func read() async throws -> [ResourceContents] {
let config = """
{"theme": "dark", "language": "en"}
"""
return [.text(TextResourceContents(uri: uri, mimeType: mimeType, text: config))]
}
}struct GreetingPrompt: MCPPromptHandler {
let name = "greeting"
let description: String? = "Generate a personalized greeting"
let arguments: [PromptArgument] = [
PromptArgument(name: "name", description: "Person to greet", required: true)
]
func get(arguments: [String: String]) async throws -> GetPromptResult {
let name = arguments["name"] ?? "friend"
return GetPromptResult(
messages: [
PromptMessage(
role: .user,
content: .text(TextContent(text: "Hello, \(name)!"))
)
]
)
}
}Tools can request user input during execution using elicitation:
struct ConfirmTool: MCPContextualToolHandler {
let name = "confirm"
let description = "Perform an action with user confirmation"
let inputSchema = JSONSchema.object(
properties: ["action": .string(description: "Action to confirm")],
required: ["action"]
)
func execute(
arguments: [String: JSONValue],
context: ToolExecutionContext
) async throws -> CallToolResult {
let action = arguments["action"]?.stringValue ?? ""
let result = try await context.requestInput(
message: "Do you want to proceed with: \(action)?",
schema: .object(properties: ["confirmed": .boolean()])
)
if result.action == .accept,
let confirmed = result.content?["confirmed"]?.boolValue,
confirmed {
return .text("Action confirmed!")
}
return .text("Action cancelled.")
}
}MCPToolbox/
├── MCPServer.swift # Main server actor
├── Transport/
│ └── StreamableHTTPTransport # HTTP/SSE transport
├── Session/
│ └── MCPSession # Client session management
├── Protocol/
│ ├── MCPTypes # MCP message types
│ ├── Capabilities # Server/client capabilities
│ └── ProtocolVersion # Protocol versioning
├── JSONRPC/
│ ├── JSONRPCMessage # JSON-RPC types
│ └── JSONRPCError # Error handling
├── Handlers/
│ ├── ToolHandler # Tool protocols
│ ├── ResourceHandler # Resource protocols
│ └── PromptHandler # Prompt protocols
└── Utilities/
├── JSONValue # Dynamic JSON handling
└── Logging # Server logging
The package includes mcptool, a reference MCP server implementation:
swift run mcptool --port 8080 --verboseOptions:
--host: Host to bind to (default: 127.0.0.1)--port: Port to listen on (default: 8080)--endpoint: Endpoint path (default: /mcp)--verbose: Enable verbose logging--debug: Enable debug logging--allow-remote: Allow remote connections
MCPToolbox implements the MCP specification version 2025-11-25 with support for:
- Streamable HTTP Transport (POST/GET/DELETE on single endpoint)
- Server-Sent Events for server-to-client messages
- Session management with MCP-Session-Id headers
- Tools, Resources, Resource Templates, and Prompts
- Elicitation for server-initiated user input requests
See LICENSE file for license information.