A toolkit built on top of the official Swift SDK for Model Context Protocol server and clients that makes it easy to define strongly-typed tools.
Conform to MCPTool, describe your parameters using the JSONSchemaBuilder or @Schemable from swift-json-schema, and implement the call(with:) method.
struct WeatherTool: MCPTool {
let name = "weather"
let description: String? = "Return the weather for a location"
@Schemable
enum Unit {
case fahrenheit
case celsius
}
@Schemable
@ObjectOptions(.additionalProperties { false })
struct Parameters {
/// Location as city, like "Detroit" or "New York"
let location: String
/// Unit for temperature
let unit: Unit
}
func call(with arguments: Parameters) async throws -> CallTool.Result {
let weather: String
switch arguments.unit {
case .fahrenheit:
weather = "The weather in \(arguments.location) is 75°F and sunny."
case .celsius:
weather = "The weather in \(arguments.location) is 24°C and sunny."
}
return .init(content: [.text(weather)])
}
}Compare to see the vanilla swift-sdk approach
// Example/Sources/MCPToolkitExample/Tools/VanillaWeatherTool.swift
import MCP
struct VanillaWeatherTool {
static let name = "weather"
static func configure(server: Server) async {
await server.withMethodHandler(ListTools.self) { _ in
let tools = [
Tool(
name: Self.name,
description: "Return the weather for a location",
inputSchema: .object([
"type": .string("object"),
"additionalProperties": .bool(false),
"properties": .object([
"location": .object([
"type": .string("string"),
"description": .string("Location as city, like \"Detroit\" or \"New York\""),
]),
"unit": .object([
"type": .string("string"),
"enum": .array(["fahrenheit", "celsius"].map { .string($0) }),
"description": .string("Unit for temperature"),
]),
]),
"required": .array([.string("location"), .string("unit")]),
])
)
]
return .init(tools: tools)
}
await server.withMethodHandler(CallTool.self) { params async in
guard let arguments = params.arguments else {
return .init(
content: [.text("Missing arguments for tool \(Self.name)")],
isError: true
)
}
guard
case .string(let location)? = arguments["location"],
case .string(let unit)? = arguments["unit"]
else {
return .init(
content: [.text("Arguments for tool \(Self.name) failed validation.")],
isError: true
)
}
let summary: String
switch unit {
case "fahrenheit":
summary = "The weather in \(location) is 75°F and sunny."
case "celsius":
summary = "The weather in \(location) is 24°C and sunny."
default:
return .init(
content: [.text("Arguments for tool \(Self.name) failed validation.")],
isError: true
)
}
return .init(content: [.text(summary)])
}
}
}Create the same Server instance you would when using the swift-sdk, then call register(tools:) with your tool instance(s).
The optional messaging: parameter lets you customise every toolkit-managed response if you want to adjust tone, add metadata, or localise error messages.
import MCPToolkit
let server = Server(
name: "Weather Station",
version: "1.0.0",
capabilities: .init(tools: .init(listChanged: true))
)
await server.register(
tools: [WeatherTool()],
messaging: ResponseMessagingFactory.defaultWithOverrides { overrides in
overrides.toolThrew = { context in
CallTool.Result(
content: [
.text("Weather machine failure: \(context.error.localizedDescription)")
],
isError: true
)
}
}
)If you are happy with the toolkit's defaults, simply omit the messaging: argument.
MCP Inspector is an interactive development tool for MCP servers.
To install MCP Inspector, run:
npm install -g @modelcontextprotocol/inspectorThen you can run the example cli with either stdio or HTTP transport modes.
To run the example server with stdio transport, use:
npx @modelcontextprotocol/inspector@latest swift run MCPToolkitExample --transport stdioThis will start the server and connect it to MCP Inspector.
In HTTP mode, the CLI will spin up a Vapor web server (on port 8080 by default) with MCP tools at /mcp endpoint.
First start the Vapor server:
swift run MCPToolkitExample --transport httpThen in another terminal, start MCP Inspector and connect to the server:
npx @modelcontextprotocol/inspector@latest --server-url http://127.0.0.1:8080/mcp --transport httpFull API documentation is available on Swift Package Index here.
Add swift-mcp-toolkit to your Package.swift:
dependencies: [
.package(url: "https://github.com/ajevans99/swift-mcp-toolkit.git", from: "0.1.0")
]Then add the dependency to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "MCPToolkit", package: "swift-mcp-toolkit")
]
)We welcome contributions! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License. See LICENSE for details.

