- Swift 99.8%
- Shell 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
* Delay SSE GET connection until after session ID is established - Add a signaling mechanism to ensure the SSE streaming task waits for the initial session ID to be set before attempting the GET connection. - Use a TaskGroup to race between session ID signal and a 10-second timeout, logging the outcome. - Trigger the signal when a session ID is received for the first time from any response. - Add detailed logging for all code paths to aid debugging and clarify connection timing. - Clean up signal resources on disconnect to prevent leaks. This addresses the initialization timing issue where the SSE GET could be attempted before the session was established, as discussed in MCP PR #91. * Update tests for SSE timing * Use configurable timeout for acquiring session ID * Remove Actor protocol conformance for HTTPClientTransport * Configure shorter session ID timeout for tests * Add documentation comments to HTTPClientTransport * Rename sessionIDWaitTimeout to sseInitializationTimeout |
||
| .github/workflows | ||
| .vscode | ||
| Sources/MCP | ||
| Tests/MCPTests | ||
| .gitignore | ||
| LICENSE | ||
| Package.resolved | ||
| Package.swift | ||
| README.md | ||
MCP Swift SDK
Swift implementation of the Model Context Protocol (MCP).
Requirements
- Swift 6.0+ (Xcode 16+)
See the Platform Availability section below for more information about platform requirements.
Installation
Swift Package Manager
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/modelcontextprotocol/swift-sdk.git", from: "0.7.1")
]
Usage
Basic Client Setup
import MCP
// Initialize the client
let client = Client(name: "MyApp", version: "1.0.0")
// Create a transport and connect
let transport = StdioTransport()
try await client.connect(transport: transport)
// Initialize the connection
let result = try await client.initialize()
Streaming HTTP Transport
The HTTP transport supports streaming mode for real-time communication using Server-Sent Events (SSE):
import MCP
// Create a streaming HTTP transport
let transport = HTTPClientTransport(
endpoint: URL(string: "http://localhost:8080")!,
)
// Initialize the client with streaming transport
let client = Client(name: "MyApp", version: "1.0.0")
try await client.connect(transport: transport)
// Initialize the connection
let result = try await client.initialize()
// The transport will automatically handle SSE events
// and deliver them through the client's notification handlers
Basic Server Setup
import MCP
// Initialize the server with capabilities
let server = Server(
name: "MyServer",
version: "1.0.0",
capabilities: .init(
prompts: .init(),
resources: .init(
subscribe: true
),
tools: .init()
)
)
// Create transport and start server
let transport = StdioTransport()
try await server.start(transport: transport)
// Register method handlers
server.withMethodHandler(ReadResource.self) { params in
// Handle resource read request
let uri = params.uri
let content = [Resource.Content.text("Example content")]
return .init(contents: content)
}
// Register notification handlers
server.onNotification(ResourceUpdatedNotification.self) { message in
// Handle resource update notification
}
// Stop the server when done
await server.stop()
Working with Tools
// List available tools
let tools = try await client.listTools()
// Call a tool
let (content, isError) = try await client.callTool(
name: "example-tool",
arguments: ["key": "value"]
)
// Handle tool content
for item in content {
switch item {
case .text(let text):
print(text)
case .image(let data, let mimeType, let metadata):
// Handle image data
}
}
Working with Resources
// List available resources
let (resources, nextCursor) = try await client.listResources()
// Read a resource
let contents = try await client.readResource(uri: "resource://example")
// Subscribe to resource updates
try await client.subscribeToResource(uri: "resource://example")
// Handle resource updates
await client.onNotification(ResourceUpdatedNotification.self) { message in
let uri = message.params.uri
let content = message.params.content
// Handle the update
}
Working with Prompts
// List available prompts
let (prompts, nextCursor) = try await client.listPrompts()
// Get a prompt with arguments
let (description, messages) = try await client.getPrompt(
name: "example-prompt",
arguments: ["key": "value"]
)
Platform Availability
The Swift SDK has the following Apple platform requirements:
| Platform | Minimum Version |
|---|---|
| macOS | 13.0+ |
| iOS / Mac Catalyst | 16.0+ |
| watchOS | 9.0+ |
| tvOS | 16.0+ |
| visionOS | 1.0+ |
While the core library works on any platform supporting Swift 6 (including Linux and Windows), running a client or server requires a compatible transport.
MCP's transport layer handles communication between clients and servers. The Swift SDK provides multiple built-in transports:
StdioTransport: Implements stdio transport. Available on Apple platforms and Linux distributions with glibc (Ubuntu, Debian, Fedora, CentOS, RHEL).HTTPClientTransport: Implements Streamable HTTP transport using Foundation URL Loading SystemNetworkTransport: Implements custom transport over TCP and UDP using Apple's Networking framework. Available exclusively on Apple platforms.
You can implement a custom transport for platforms without built-in support. 1
For custom transport implementation details,
see the Transport protocol.
Changelog
This project follows Semantic Versioning. For pre-1.0 releases, minor version increments (0.X.0) may contain breaking changes.
For details about changes in each release, see the GitHub Releases page.
License
This project is licensed under the MIT License.
-
We're working to add stdio transport support for Alpine Linux and Windows. If you're interested in either of those platforms, please take a look at their respective PRs and leave a comment! ↩︎