Fire in da houseTop Tip:Most people pay up to $340 per month for Perplexity, MidJourney, Runway, ChatGPT, and more - but you can get them all your AI tools for $15 with Galaxy. It's free to test!Fire in da houseCheck it out

SwiftMCP

MCP.Pizza Chef: gavinaboulhosn

SwiftMCP is a Swift-based server implementation of the Model Context Protocol (MCP), designed to enable robust, type-safe integration of language model capabilities into Swift applications. Leveraging modern Swift concurrency features such as actors and async/await, SwiftMCP offers efficient message handling with support for multiple transports including stdio and Server-Sent Events (SSE). It is built for performance, featuring timeout and retry mechanisms, and aims to provide feature parity with the established TypeScript MCP implementation. SwiftMCP is ideal for developers looking to embed LLM context and interaction capabilities natively within macOS and iOS environments, ensuring secure, scalable, and maintainable AI-enhanced workflows.

Use This MCP server To

Integrate LLM context management in Swift applications Enable real-time LLM interactions using Swift concurrency Build AI-enhanced macOS and iOS apps with MCP support Implement type-safe MCP message handling in Swift Support multiple communication transports like stdio and SSE Develop performant LLM servers with timeout and retry logic

README

SwiftMCP

Swift Platforms License

SwiftMCP is a work-in-progress Swift implementation of the Model Context Protocol (MCP), aiming to provide a robust and type-safe way to integrate Language Model capabilities into Swift applications.

⚠️ Note: This SDK is under active development. APIs may change as we work towards feature parity with the TypeScript implementation.

Features

  • πŸƒ Modern Swift Concurrency - Built with Swift's actor model and async/await
  • πŸ”’ Type-Safe - Full type safety for all MCP messages and operations
  • πŸ”Œ Multiple Transports - Support for stdio and Server-Sent Events (SSE)
  • ⚑️ Performance - Efficient message handling with timeout and retry support
  • πŸ›  Rich Capabilities - Support for resources, prompts, tools, and more
  • πŸ“¦ SwiftPM Ready - Easy integration through Swift Package Manager

Installation

Add SwiftMCP to your Swift package:

dependencies: [
    .package(url: "https://github.com/gavinaboulhosn/SwiftMCP.git", branch: "main")
]

Or add it to your Xcode project:

  1. File > Add Package Dependencies
  2. Enter: https://github.com/gavinaboulhosn/SwiftMCP.git

Basic Usage

Creating a Client

import SwiftMCP

// Initialize client
let client = MCPClient(
    clientInfo: .init(name: "MyApp", version: "1.0.0"),
    capabilities: .init(
        roots: .init(listChanged: true)  // Enable roots with change notifications
    )
)

// Connect using stdio transport
let transport = StdioTransport(
    options: .init(
        command: "npx",
        arguments: ["-y", "@modelcontextprotocol/server-memory"]
    )
)

// Start the client
try await client.start(transport)

// Make requests
let resources = try await client.listResources()
print("Found \(resources.resources.count) resources")

// Listen for notifications
for await notification in await client.notifications {
    switch notification {
    case let resourceUpdate as ResourceUpdatedNotification:
        print("Resource updated: \(resourceUpdate.params?.uri ?? "")")
    default:
        break
    }
}

Hosts

Hosts are used to manage client connections and provide a higher-level API for handling requests and notifications:

Basic Setup

To get started, you need to create an MCPHost instance and connect to a server using a transport layer:

import SwiftMCP

// Basic host - assumes app name and version via Bundle properties
let host = MCPHost()
// or more advanced configuration
let host = MCPHost(config:
    .init(
        roots: .list([Root(uri: "file:///some/root")]),
        sampling: .init(
            handler: { request in
                /** Use your llm to fulfill the server's sampling request */
                let completion = try await myLLM.complete(
                    messages: request.messages,
                    // other options
                )
                return CreateMessageResult( /** the result */)

                // or reject the request
                throw Error.notAllowed
            }),
        clientInfo: /** your explicit client info */,
        capabilities: /** Your explicit client capabilities (inferred by default from what root / sampling config is provided) */

    )
)

let transport = StdioTransport(command: "npx", arguments: ["-y", "@modelcontextprotocol/server-everything"])

let connection = try await host.connect("test", transport: transport)

Sending Requests

let tools = try await connection.listTools()

print("Available tools: \(tools.tools)")

Handling Notifications

Notifications can be handled by subscribing to the notifications stream:

Note: The connection automatically observes server notifications and will update tools, resources, and prompts accordingly. You only need to observe notifications if you want to handle them directly in your application code.

let notificationStream = await connection.notifications
for await notification in notificationStream {
    switch notification {
    case let toolChanged as ToolListChangedNotification:
        print("Tool list changed: \(toolChanged)")
    default:
        break
    }
}

Progress Tracking

For long-running operations, you can track progress using a progress handler:

let _ = try await connection.callTool(
    "longRunningOperation",
    arguments: ["duration": 5, "steps": 10]) { progress, total in
        print("Progress: \(progress) / \(total ?? 0)")
    }

Error Handling

SwiftMCP provides structured error handling:

do {
    try await client.start(transport)
} catch let error as MCPError {
    switch error.code {
    case .connectionClosed:
        print("Connection closed: \(error.message)")
    case .invalidRequest:
        print("Invalid request: \(error.message)")
    default:
        print("Error: \(error)")
    }
}

Advanced Features

Custom Transport

Implement your own transport by conforming to MCPTransport:

actor MyCustomTransport: MCPTransport {
    var state: TransportState = .disconnected
    let configuration: TransportConfiguration
    
    func messages() -> AsyncThrowingStream<Data, Error> {
        // Implement message streaming
    }
    
    func start() async throws {
        // Initialize transport
    }
    
    func stop() async {
        // Cleanup
    }
    
    func send(_ data: Data, timeout: TimeInterval?) async throws {
        // Send message
    }
}

Request Timeout & Retry

Configure timeout and retry policies:

let transport = StdioTransport(
    options: .init(command: "server"),
    configuration: .init(
        connectTimeout: 30.0,
        sendTimeout: 10.0,
        retryPolicy: .init(
            maxAttempts: 3,
            baseDelay: 1.0,
            backoffPolicy: .exponential
        )
    )
)

API Documentation

Visit modelcontextprotocol.io for full protocol documentation.

Key types and protocols:

  • MCPHost: Host interface
  • MCPClient: Main client interface
  • MCPTransport: Transport abstraction
  • MCPMessage: Base message protocol
  • MCPRequest/MCPResponse: Request/response protocols
  • MCPNotification: Notification protocol

Roadmap

  • βœ… Base protocol with JSON-RPC message handling
  • βœ… Core transports: stdio and SSE
  • βœ… Actor-based architecture with SwiftConcurrency
  • βœ… Type-safe requests and responses
  • βœ… Basic error handling and timeouts
  • βœ… Client implementation with transport abstraction
  • βœ… Host implementation improvements
  • βœ… Enhanced sampling capabilities
  • βœ… Progress monitoring enhancements
  • 🚧 WebSocket transport
  • 🚧 MCP Server implementation
  • 🚧 Example servers and implementations

Contributing

  1. Read the MCP Specification
  2. Fork the repository
  3. Create a feature branch
  4. Add tests for new functionality
  5. Submit a pull request

Limitations

  • StdioTransport does not work in sandboxed environments

Development

# Clone repository
git clone https://github.com/gavinaboulhosn/SwiftMCP.git

# Build
swift build

# Run tests
swift test

SwiftMCP FAQ

How do I install SwiftMCP in my Swift project?
You can add SwiftMCP via Swift Package Manager by including its GitHub repository URL in your Package.swift dependencies.
Is SwiftMCP compatible with iOS and macOS platforms?
Yes, SwiftMCP supports macOS 13+ and iOS 16+ platforms, leveraging native Swift concurrency features.
Does SwiftMCP support asynchronous operations?
Yes, it uses Swift's modern async/await and actor model for concurrency and efficient message handling.
What communication transports does SwiftMCP support?
SwiftMCP supports stdio and Server-Sent Events (SSE) transports for flexible integration.
Is SwiftMCP stable for production use?
SwiftMCP is currently under active development; APIs may change as it progresses toward feature parity with the TypeScript MCP implementation.
How does SwiftMCP ensure type safety?
SwiftMCP provides full type safety for all MCP messages and operations, reducing runtime errors and improving developer experience.
Can SwiftMCP handle message timeouts and retries?
Yes, it includes built-in support for timeout and retry mechanisms to ensure reliable communication.
Where can I find the source code and license for SwiftMCP?
The source code is available on GitHub under the MIT license.