FastMCP: Build Swift MCP Servers in 3 Lines
A Swift builder pattern that reduces MCP server boilerplate from 50+ lines to just 3.
Model Context Protocol (MCP) is Anthropic’s open standard for connecting AI assistants to external tools. Building MCP servers with the official Swift SDK requires significant boilerplate.
The Problem
Standard MCP server setup:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import MCP
let server = Server(
name: "My Server",
version: "1.0.0",
capabilities: Server.Capabilities(
prompts: nil,
resources: nil,
tools: .init(listChanged: false)
)
)
await server.withMethodHandler(Tools.self) { _ in
// Return tool definitions...
}
await server.withMethodHandler(CallTool.self) { params in
// Handle tool calls...
}
let transport = StdioTransport(logger: logger)
try await server.start(transport: transport)
// Handle shutdown signals...
// Set up logging...
The Solution
1
2
3
4
try await FastMCP.builder()
.name("My Server")
.addTools([WeatherTool()])
.run()
Three lines. Server running.
Building a Tool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import FastMCP
struct WeatherTool: MCPTool {
let name = "get_weather"
let description: String? = "Get weather for a location"
@Schemable
struct Parameters: Sendable {
let location: String
let unit: Unit?
}
@Schemable
enum Unit: String, Sendable {
case celsius, fahrenheit
}
func call(with args: Parameters) async throws(ToolError) -> Content {
let temp = args.unit == .fahrenheit ? "72°F" : "22°C"
return [ToolContentItem(text: "Weather in \(args.location): \(temp), Sunny")]
}
}
@main
struct WeatherServer {
static func main() async throws {
try await FastMCP.builder()
.name("Weather Server")
.addTools([WeatherTool()])
.run()
}
}
The @Schemable macro auto-generates JSON schema for Claude to understand parameters.
Resources
Expose data to AI:
1
2
3
4
5
6
7
8
9
10
11
12
struct ConfigResource: MCPResource {
let uri = "config://app/settings"
let name = "App Settings"
let description: String? = "Application configuration"
let mimeType: String? = "application/json"
var content: Content {
"""
{"theme": "dark", "version": "1.0.0"}
"""
}
}
Prompts
Reusable conversation templates:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct CodeReviewPrompt: MCPPrompt {
let name = "code_review"
let description: String? = "Review code with specific focus"
let arguments: [Prompt.Argument]? = [
.init(name: "language", description: "Programming language", required: true),
.init(name: "focus", description: "Review focus area")
]
func getMessages(arguments: [String: Value]?) async throws -> [Prompt.Message] {
let lang = arguments?["language"]?.stringValue ?? "Swift"
let focus = arguments?["focus"]?.stringValue ?? "best practices"
return [
.user("Review this \(lang) code focusing on \(focus)."),
.assistant("I'll review your \(lang) code with attention to \(focus). Please share the code.")
]
}
}
Full Builder API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try await FastMCP.builder()
// Identity
.name("My Awesome Server")
.version("2.0.0")
// MCP Capabilities
.addTools([WeatherTool(), MathTool()])
.addResources([ConfigResource()])
.addPrompts([CodeReviewPrompt()])
.enableSampling()
// Transport
.transport(.stdio) // or .inMemory for testing
// Configuration
.logger(myLogger)
.shutdownSignals([.sigterm, .sigint])
// Lifecycle Hooks
.onStart { print("Server started") }
.onShutdown { print("Server stopped") }
.run()
Everything has sensible defaults. Configure only what you need.
Claude Desktop Integration
Add to claude_desktop_config.json:
1
2
3
4
5
6
7
{
"mcpServers": {
"my-server": {
"command": "/path/to/my-server"
}
}
}
Restart Claude Desktop. Tools appear automatically.
Installation
1
2
3
4
// Package.swift
dependencies: [
.package(url: "https://github.com/mehmetbaykar/swift-fast-mcp", from: "1.0.0")
]
Requirements: macOS 14+, Swift 6.2+
☕ Support My Work
If you found this post helpful and want to support more content like this, you can buy me a coffee!
Your support helps me continue creating useful articles and tips for fellow developers. Thank you! 🙏