### Basic Server Setup in Swift Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Initialize a server with specified capabilities and start it using a transport layer. This is the foundational step for hosting model functionalities. ```swift import MCP // Create a server with given capabilities let server = Server( name: "MyModelServer", version: "1.0.0", capabilities: .init( completions: .init(), logging: .init(), prompts: .init(listChanged: true), resources: .init(subscribe: true, listChanged: true), tools: .init(listChanged: true) ) ) // Create transport and start server let transport = StdioTransport() try await server.start(transport: transport) // Now register handlers for the capabilities you've enabled ``` -------------------------------- ### OAuthConfiguration Examples Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Illustrates creating OAuthConfiguration instances for different grant types. The first example shows machine-to-machine configuration using client credentials, while the second demonstrates user authentication setup with an authorization delegate. ```swift // Machine-to-machine let m2mConfig = OAuthConfiguration( grantType: .clientCredentials, authentication: .clientSecretBasic(clientID: "app", clientSecret: "s3cr3t") ) // User authentication let userConfig = OAuthConfiguration( grantType: .authorizationCode, authentication: .none(clientID: "app"), authorizationDelegate: MyAuthDelegate() ) ``` -------------------------------- ### Client-Side Progress Tracking Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md Example demonstrating how to implement client-side progress tracking using `ProgressToken` and handling `ProgressNotification`. ```APIDOC ## Client-Side Progress Tracking Example ### Description This example shows how to generate a `ProgressToken`, register a handler for `ProgressNotification`, and then call a tool with the token to receive and process progress updates. ### Steps 1. **Generate Token**: Create a unique `ProgressToken` using `ProgressToken.unique()`. 2. **Register Handler**: Use `client.onNotification` to listen for `ProgressNotification` messages. 3. **Filter Updates**: Inside the handler, filter notifications by matching the `progressToken`. 4. **Process Progress**: Calculate and display the progress percentage and status message. 5. **Call Tool**: Invoke a tool using `client.callTool`, passing the `progressToken` within the `Metadata`. 6. **Handle Results**: Process the content returned by the tool call. ``` -------------------------------- ### Start Server with Transport Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/exports.md Starts the server using a specified transport. This is the basic method for initiating server operations. ```swift public func start(transport: any Transport) async throws ``` -------------------------------- ### Start Server with Transport and Initialization Handler Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/exports.md Starts the server with a transport and an asynchronous initialization handler. The handler is executed upon successful client connection and capability negotiation. ```swift public func start(transport: any Transport, onInitialize: @escaping (ClientInfo, Client.Capabilities) async throws -> Void) async throws ``` -------------------------------- ### Client Setup and Usage Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/README.md Demonstrates how to create, connect, and use a client with the SDK. Ensure proper error handling for network operations. ```swift // 1. Create client let client = Client(name: "MyApp", version: "1.0.0") // 2. Create transport let transport = StdioTransport() // 3. Connect let result = try await client.connect(transport: transport) // 4. Use capabilities let tools = try await client.listTools() let (content, _) = try await client.callTool(name: "example", arguments: [:]) // 5. Disconnect await client.disconnect() ``` -------------------------------- ### TokenEndpointAuthentication Examples Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Provides examples of setting up TokenEndpointAuthentication. The first shows basic HTTP authentication using client ID and secret. The second demonstrates private key JWT authentication, including a factory for creating JWT assertions. ```swift // HTTP Basic authentication let basicAuth = TokenEndpointAuthentication.clientSecretBasic( clientID: "client123", clientSecret: "secretkey456" ) // Private key JWT (P-256 ECDSA) let jwtAuth = TokenEndpointAuthentication.privateKeyJWT( clientID: "app", assertionFactory: { tokenEndpoint, clientID in try OAuthConfiguration.makePrivateKeyJWTAssertion( clientID: clientID, tokenEndpoint: tokenEndpoint, privateKeyPEM: pemEncodedKey ) } ) ``` -------------------------------- ### Example of Server Capabilities Initialization Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Demonstrates how to initialize the Server.Capabilities struct with specific tool, resource, prompt, logging, and completion settings. ```swift let capabilities = Server.Capabilities( tools: .init(listChanged: true), resources: .init(subscribe: true, listChanged: true), prompts: .init(listChanged: true), logging: .init(), completions: .init() ) ``` -------------------------------- ### OAuthProtectedResourceServerMetadata Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Example of initializing `OAuthProtectedResourceServerMetadata` with resource details, authorization server URLs, and supported scopes. This shows how to construct the metadata object for a protected resource. ```swift let metadata = OAuthProtectedResourceServerMetadata( resource: "https://api.example.com", authorizationServers: [ URL(string: "https://auth.example.com")! ], scopesSupported: ["read", "write", "admin"] ) ``` -------------------------------- ### Basic Swift Client Setup Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Initialize the MCP client and establish a connection using a transport. Check server capabilities after connecting. ```swift import MCP // Initialize the client let client = Client(name: "MyApp", version: "1.0.0") // Create a transport and connect let transport = StdioTransport() let result = try await client.connect(transport: transport) // Check server capabilities if result.capabilities.tools != nil { // Server supports tools (implicitly including tool calling if the 'tools' capability object is present) } ``` -------------------------------- ### Server Setup and Handler Registration Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/README.md Illustrates how to set up a server, define its capabilities, and register handlers for specific methods. This is essential for building MCP services. ```swift // 1. Create server with capabilities let server = Server( name: "MyServer", version: "1.0.0", capabilities: .init( tools: .init(listChanged: true), resources: .init(subscribe: true) ) ) // 2. Register handlers server .withMethodHandler(ListTools.self) { _ in return .init(tools: [...]) } .withMethodHandler(CallTool.self) { params in // Handle tool call return .init(content: [...], isError: false) } // 3. Create transport and start let transport = StdioTransport() try await server.start(transport: transport) // 4. Stop when done await server.stop() ``` -------------------------------- ### Start Server with Initialization Hook Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Starts the server with a transport and an initialization hook. The hook is executed upon client connection to validate credentials or capabilities. Errors thrown by the hook will prevent the client from connecting. ```swift try await server.start(transport: transport) { clientInfo, clientCaps in guard clientInfo.name != "BlockedClient" else { throw MCPError.invalidRequest("Client not allowed") } print("Client \(clientInfo.name) v\(clientInfo.version) connected") } ``` -------------------------------- ### Basic Client Setup Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Demonstrates how to initialize the MCP client and connect to a server using a StdioTransport. It also shows how to check for server capabilities, specifically if tools are supported. ```APIDOC ## Basic Client Setup ### Description Initializes the MCP client and establishes a connection using a specified transport. Allows checking server capabilities upon successful connection. ### Method `Client.connect(transport:) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift import MCP // Initialize the client let client = Client(name: "MyApp", version: "1.0.0") // Create a transport and connect let transport = StdioTransport() let result = try await client.connect(transport: transport) // Check server capabilities if result.capabilities.tools != nil { // Server supports tools } ``` ### Response #### Success Response (200) `InitializationResult` object containing server capabilities. #### Response Example ```json { "capabilities": { "tools": {}, "resources": { "subscribe": true }, "prompts": {} } } ``` ``` -------------------------------- ### Start Server with Transport Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Starts the server using a specified transport. This method blocks until the server is stopped or an error occurs. Ensure the transport is correctly configured before calling. ```swift let transport = StdioTransport() try await server.start(transport: transport) ``` -------------------------------- ### Stdio Transport Setup Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Illustrates how to set up and use the StdioTransport for local subprocess communication with the MCP client. ```APIDOC ## Stdio Transport Setup ### Description Configures and connects the MCP client using `StdioTransport`, suitable for local inter-process communication. ### Method `client.connect(transport:) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift import MCP let client = Client(name: "MyApp", version: "1.0.0") // Create a stdio transport (simplest option) let transport = StdioTransport() try await client.connect(transport: transport) ``` ### Response #### Success Response (200) Indicates a successful connection. #### Response Example None (connection success is implicit) ``` -------------------------------- ### Server.start(transport:onInitialize:) Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Starts the server with an initialization hook. The hook is called when a client connects, allowing validation of client credentials or capabilities before proceeding. ```APIDOC ## Server.start(transport:onInitialize:) ### Description Starts the server with an initialization hook. The hook is called when a client connects, allowing validation of client credentials or capabilities before proceeding. ### Method `public func start( transport: any Transport, onInitialize: @escaping @Sendable (ClientInfo, Client.Capabilities) async throws -> Void ) async throws` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift try await server.start(transport: transport) { clientInfo, clientCaps in guard clientInfo.name != "BlockedClient" else { throw MCPError.invalidRequest("Client not allowed") } print("Client \(clientInfo.name) v\(clientInfo.version) connected") } ``` ### Response #### Success Response (Void) Returns Void upon successful startup. #### Response Example None ### Throws Transport or handler errors ``` -------------------------------- ### Server.start(transport:) Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Starts the server, accepting connections and requests on the specified transport. This method blocks until the server is stopped or an error occurs. ```APIDOC ## Server.start(transport:) ### Description Starts the server, accepting connections and requests. Blocks until the server is stopped or an error occurs. ### Method `public func start(transport: any Transport) async throws` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let transport = StdioTransport() try await server.start(transport: transport) ``` ### Response #### Success Response (Void) Returns Void upon successful startup. #### Response Example None ### Throws - `MCPError.internalError` if already running - Transport-specific errors if connection fails ``` -------------------------------- ### Custom Minimal Scope Selector Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md An example implementation of OAuthScopeSelecting that only requests the required scopes. This is useful for minimizing the permissions requested from the user. ```swift struct MinimalScopeSelector: OAuthScopeSelecting { func selectScopes(available: [String], required: [String]?) -> [String] { // Only request required scopes return required ?? [] } } let config = OAuthConfiguration( grantType: .clientCredentials, authentication: .clientSecretBasic(clientID: "app", clientSecret: "secret"), scopeSelector: MinimalScopeSelector() ) ``` -------------------------------- ### OAuthAuthorizer Usage Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Demonstrates how to configure and use the OAuthAuthorizer with an HTTPClientTransport. This example sets up client credentials grant type and basic client secret authentication, then connects a client to an MCP endpoint. ```swift let config = OAuthConfiguration( grantType: .clientCredentials, authentication: .clientSecretBasic(clientID: "app", clientSecret: "secret") ) let authorizer = OAuthAuthorizer(configuration: config) let transport = HTTPClientTransport( endpoint: URL(string: "https://api.example.com/mcp")!, authorizer: authorizer ) let client = Client(name: "MyApp", version: "1.0") try await client.connect(transport: transport) ``` -------------------------------- ### BearerTokenInfo Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Example of creating a `BearerTokenValidator` and using a closure to verify a JWT token and extract `BearerTokenInfo`. This demonstrates how to validate incoming tokens and extract relevant claims. ```swift let bearerValidator = BearerTokenValidator( resourceMetadataURL: url, resourceIdentifier: resourceURL, tokenValidator: { token, request, context in guard let claims = try verifyJWT(token) else { return .invalidToken(errorDescription: "Token verification failed") } return .valid(BearerTokenInfo( audience: claims.aud, expiresAt: claims.exp )) } ) ``` -------------------------------- ### Get Prompt Details Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/exports.md Fetches the description and messages for a specific prompt by its name and optional arguments. ```swift public func getPrompt(name: String, arguments: [String: String]? = nil) async throws -> (description: String?, messages: [Prompt.Message]) ``` -------------------------------- ### OAuth Authentication Setup Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/README.md Configures and uses OAuth for authentication with an HTTP client transport. Ensure your client ID and secret are correctly provided. ```swift let config = OAuthConfiguration( grantType: .clientCredentials, authentication: .clientSecretBasic(clientID: "app", clientSecret: "secret") ) let authorizer = OAuthAuthorizer(configuration: config) let transport = HTTPClientTransport( endpoint: URL(string: "https://api.example.com/mcp")!, authorizer: authorizer ) try await client.connect(transport: transport) ``` -------------------------------- ### Standard Validation Pipeline Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/transport-api.md Demonstrates setting up a validation pipeline with multiple built-in validators for HTTP requests. Includes metadata and token validation. ```swift let metadata = OAuthProtectedResourceServerMetadata( resource: "https://api.example.com", authorizationServers: [URL(string: "https://auth.example.com")!], scopesSupported: ["read", "write"] ) let pipeline = StandardValidationPipeline(validators: [ ProtectedResourceMetadataValidator(metadata: metadata), BearerTokenValidator( resourceMetadataURL: URL(string: "https://api.example.com/.well-known/oauth-protected-resource")!, resourceIdentifier: URL(string: "https://api.example.com")!, tokenValidator: { token, request, context in let claims = try verifyJWT(token) return .valid(BearerTokenInfo( audience: claims.audience, expiresAt: claims.expiresAt )) } ), AcceptHeaderValidator(mode: .sseRequired), ContentTypeValidator(), SessionValidator() ]) ``` -------------------------------- ### Client.connect(transport:) Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/client-api.md Establishes a connection to a server using the provided transport. It automatically sends an initialize request and starts the message handling loop. ```APIDOC ## Client.connect(transport:) ### Description Establishes connection to a server via the specified transport. Automatically sends the initialize request and starts the message handling loop. ### Method `async throws` ### Parameters #### Path Parameters - **transport** (Transport) - Required - The transport to connect over (e.g., StdioTransport, HTTPClientTransport) ### Returns `Initialize.Result` containing server capabilities and metadata ### Throws - `MCPError.transportError` if connection fails - `MCPError.internalError` if already connected ### Example ```swift let transport = StdioTransport() try await client.connect(transport: transport) ``` ``` -------------------------------- ### Initialize Server with Hook Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Start the server with an initialize hook to control client connections. This hook validates client information and capabilities before initialization succeeds. It can throw an error to reject the connection. ```swift // Start the server with an initialize hook try await server.start(transport: transport) { clientInfo, clientCapabilities in // Validate client info guard clientInfo.name != "BlockedClient" else { throw MCPError.invalidRequest("This client is not allowed") } // You can also inspect client capabilities if clientCapabilities.sampling == nil { print("Client does not support sampling") } // Perform any server-side setup based on client info print("Client \(clientInfo.name) v\(clientInfo.version) connected") // If the hook completes without throwing, initialization succeeds } ``` -------------------------------- ### HTTP Transport Setup Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Shows how to configure and utilize the HTTPClientTransport for connecting to remote MCP servers, with an option to enable streaming for real-time updates. ```APIDOC ## HTTP Transport Setup ### Description Configures and connects the MCP client using `HTTPClientTransport` for remote server communication. Supports enabling streaming via Server-Sent Events. ### Method `client.connect(transport:) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift import MCP let client = Client(name: "MyApp", version: "1.0.0") // Create a streaming HTTP transport let transport = HTTPClientTransport( endpoint: URL(string: "http://localhost:8080")!, streaming: true // Enable Server-Sent Events for real-time updates ) try await client.connect(transport: transport) ``` ### Response #### Success Response (200) Indicates a successful connection. #### Response Example None (connection success is implicit) ``` -------------------------------- ### Client Credentials Flow Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md Use this snippet to implement the Client Credentials Flow for OAuth authentication. It shows how to configure OAuth, create an authorizer with token storage, set up the HTTP transport, and connect the client. ```swift import MCP // 1. Configure OAuth let config = OAuthConfiguration( grantType: .clientCredentials, authentication: .clientSecretBasic( clientID: "my-app", clientSecret: "app-secret-key" ) ) // 2. Create authorizer with persistent token storage let authorizer = OAuthAuthorizer( configuration: config, tokenStorage: KeychainTokenStorage() ) // 3. Create HTTP transport with OAuth let transport = HTTPClientTransport( endpoint: URL(string: "https://api.example.com/mcp")!, authorizer: authorizer ) // 4. Connect client let client = Client(name: "MyApp", version: "1.0.0") try await client.connect(transport: transport) // 5. Use client normally let tools = try await client.listTools() ``` -------------------------------- ### Handle Complete Server Method Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Implement a handler for the `Complete` method to provide auto-completions for prompts or resources. This example shows how to handle prompt completions for a 'languages' prompt, filtering by user input. ```swift server.withMethodHandler(Complete.self) { params in // Handle prompt or resource completions switch params.ref { case .prompt(let promptRef): if promptRef.name == "languages" && params.argument.name == "lang" { let languages = ["python", "swift", "rust"] let matches = languages.filter { $0.hasPrefix(params.argument.value) } return .init( completion: .init( values: Array(matches.prefix(10)), total: matches.count, hasMore: false ) ) } case .resource: break } return .init(completion: .init(values: [], total: 0, hasMore: false)) } ``` -------------------------------- ### Client-Side Tool Call with Progress Tracking Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md This example demonstrates how a client can initiate a tool call with progress tracking enabled. It involves creating a `ProgressToken`, registering a notification handler to receive and process `ProgressNotification` messages, and then making the tool call with the token included in the `Metadata`. ```swift import MCP // Create unique progress token let progressToken = ProgressToken.unique() // Register notification handler for progress updates await client.onNotification(ProgressNotification.self) { message in let params = message.params // Filter by your progress token if params.progressToken == progressToken { let percent = params.total.map { Int(Double(params.progress) / Double($0) * 100) } ?? 0 print("Progress: \(params.progress)/\(params.total ?? 0) (\(percent)%)") if let status = params.message { print("Status: \(status)") } } } // Call tool with progress tracking let (content, isError) = try await client.callTool( name: "long-running-analysis", arguments: ["data": Value("large dataset")], meta: Metadata(progressToken: progressToken) ) if !isError { for item in content { if case .text(let text, _, _) = item { print("Result: \(text)") } } } ``` -------------------------------- ### Timeout-Based Cancellation Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md Illustrates how to implement a timeout for a request by using a separate Task to call cancelRequest after a specified duration. ```swift let context = try client.send(request) // Cancel after 30 seconds let timeoutTask = Task { try await Task.sleep(nanoseconds: 30 * 1_000_000_000) try await client.cancelRequest(context.requestID, reason: "30 second timeout") } do { let result = try await context.value timeoutTask.cancel() print("Completed before timeout: \(result)") } catch is CancellationError { print("Request timed out") } ``` -------------------------------- ### List and Get Prompts in Swift Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Retrieve a list of available prompts and fetch a specific prompt with its associated messages, providing arguments to template the prompt. ```swift // List available prompts let (prompts, nextCursor) = try await client.listPrompts() print("Available prompts: \(prompts.map { $0.name }.joined(separator: ", "))") // Get a prompt with arguments let (description, messages) = try await client.getPrompt( name: "customer-service", arguments: [ "customerName": "Alice", "orderNumber": "ORD-12345", "issue": "delivery delay" ] ) // Use the prompt messages in your application print("Prompt description: \(description)") for message in messages { if case .text(text: let text) = message.content { print("\(message.role): \(text)") } } ``` -------------------------------- ### User Cancellation Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md Shows how to handle user-initiated cancellation by calling cancelRequest when a user action occurs, such as pressing a cancel button. ```swift let context = try client.send( CallTool.request(.init(name: "long-operation", arguments: [:])) ) // Later, user clicks cancel button @IBAction func cancelButtonPressed() { Task { try await client.cancelRequest(context.requestID, reason: "User cancelled") } } // Await result do { let result = try await context.value } catch is CancellationError { updateUI(withMessage: "Operation cancelled by user") } ``` -------------------------------- ### Implement MCP Server as a Service Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Implement the MCP server as a Service conforming to ServiceLifecycle's Service protocol. This includes starting the server and handling graceful shutdown. ```swift import MCP import ServiceLifecycle import Logging struct MCPService: Service { let server: Server let transport: Transport init(server: Server, transport: Transport) { self.server = server self.transport = transport } func run() async throws { // Start the server try await server.start(transport: transport) // Keep running until external cancellation try await Task.sleep(for: .days(365 * 100)) // Effectively forever } func shutdown() async throws { // Gracefully shutdown the server await server.stop() } } ``` -------------------------------- ### Value Usage Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/types.md Demonstrates how to create Value instances from different data types and how to extract specific values using their respective properties. This showcases the flexibility of the Value type for data manipulation. ```swift let intVal = Value(42) let strVal = Value("hello") let objVal = Value.object([ "name": Value("Alice"), "age": Value(30) ]) // Extract values if let name = objVal.objectValue?["name"]?.stringValue { print(name) // "Alice" } ``` -------------------------------- ### Implement Custom MCP Transport in Swift Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Demonstrates how to create a custom transport by conforming to the `Transport` protocol. This example shows the basic structure for connection, disconnection, sending, and receiving messages. ```swift import MCP import Foundation public actor MyCustomTransport: Transport { public nonisolated let logger: Logger private var isConnected = false private let messageStream: AsyncThrowingStream private let messageContinuation: AsyncThrowingStream.Continuation public init(logger: Logger? = nil) { self.logger = logger ?? Logger(label: "my.custom.transport") var continuation: AsyncThrowingStream.Continuation! self.messageStream = AsyncThrowingStream { continuation = $0 } self.messageContinuation = continuation } public func connect() async throws { // Implement your connection logic isConnected = true } public func disconnect() async { // Implement your disconnection logic isConnected = false messageContinuation.finish() } public func send(_ data: Data) async throws { // Implement your message sending logic } public func receive() -> AsyncThrowingStream { return messageStream } } ``` -------------------------------- ### Send Request and Get Context Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md Demonstrates sending a request using the MCP client and obtaining a RequestContext for managing the request's lifecycle. ```swift import MCP // Send request and get context let context = try client.send( CallTool.request(.init(name: "analyze", arguments: ["data": Value("x")])) ) // Track the request ID print("Request ID: \(context.requestID)") // Can cancel later try await client.cancelRequest(context.requestID, reason: "User cancelled") // Await result do { let result = try await context.value print("Result: \(result.content)") } catch is CancellationError { print("Request was cancelled") } ``` -------------------------------- ### Connect Client to Server Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/client-api.md Establishes a connection to the server using the specified transport. Automatically sends an initialize request and starts the message handling loop. Ensure the transport is correctly configured before calling. ```swift let transport = StdioTransport() try await client.connect(transport: transport) ``` -------------------------------- ### WebSocket Transport Implementation Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/transport-api.md An example implementation of a custom WebSocket transport using Swift. This demonstrates how to create a `Transport` conforming type for real-time communication. ```APIDOC ## WebSocket Transport ### Description An example implementation of a custom WebSocket transport using Swift. This demonstrates how to create a `Transport` conforming type for real-time communication. ### Class `WebSocketTransport` ### Initializer `init(url: URL, logger: Logger? = nil)` - Initializes the WebSocket transport with a given URL and an optional logger. ### Methods - `connect() async throws`: Establishes a WebSocket connection. - `disconnect() async`: Closes the WebSocket connection and finishes the message stream. - `send(_ data: Data) async throws`: Sends data over the WebSocket connection. - `receive() -> AsyncThrowingStream`: Returns a stream of incoming data messages. ``` -------------------------------- ### Custom Token Storage Implementation Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Implement the TokenStorage protocol to persist tokens across sessions. This example shows a basic structure for storing tokens in the system Keychain. ```swift final class KeychainTokenStorage: TokenStorage { func save(_ token: OAuthAccessToken) { // Encode and store token.value in the system Keychain } func load() -> OAuthAccessToken? { // Load and decode token from the Keychain return nil } func clear() { // Delete from the Keychain } } let authorizer = OAuthAuthorizer( configuration: config, tokenStorage: KeychainTokenStorage() ) ``` -------------------------------- ### Handle Progress and Cancellation on Client Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/request-context-progress.md This Swift example shows a client listening for progress notifications and handling cancellation. It sets up a task to simulate user cancellation after a delay and registers a notification handler to print progress updates. The request includes a `progressToken` in its metadata. ```swift let progressToken = ProgressToken.unique() var cancelled = false // Listen for cancellation let cancellationTask = Task { // User cancels after 5 seconds try await Task.sleep(nanoseconds: 5_000_000_000) try await client.cancelRequest(context.requestID, reason: "User cancelled") } // Listen for progress await client.onNotification(ProgressNotification.self) { message in if message.params.progressToken == progressToken { print("Progress: \(message.params.progress)/\(message.params.total ?? 0)") } } // Make request let context = try client.send(CallTool.request(.init( name: "analyze", arguments: ["input": Value("data")], meta: Metadata(progressToken: progressToken) ))) do { let result = try await context.value print("Completed: \(result.content)") cancellationTask.cancel() } catch is CancellationError { print("Cancelled by user") } ``` -------------------------------- ### Authorization Code Flow Example Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/oauth-authentication.md This snippet demonstrates the Authorization Code Flow for OAuth authentication. It includes implementing a custom authorization delegate for web view presentation, configuring OAuth, and setting up the authorizer and transport. ```swift import MCP import AuthenticationServices // 1. Implement authorization delegate struct WebViewAuthDelegate: OAuthAuthorizationDelegate { func presentAuthorizationURL(_ url: URL) async throws -> URL { return try await withCheckedThrowingContinuation { continuation in let session = ASWebAuthenticationSession( url: url, callbackURLScheme: "com.example.mcp" ) { callbackURL, error in if let error = error { continuation.resume(throwing: error) } else if let callbackURL = callbackURL { continuation.resume(returning: callbackURL) } } session.start() } } } // 2. Configure OAuth with auth delegate let config = OAuthConfiguration( grantType: .authorizationCode, authentication: .none(clientID: "my-app"), authorizationDelegate: WebViewAuthDelegate() ) // 3. Create authorizer and transport let authorizer = OAuthAuthorizer( configuration: config, tokenStorage: KeychainTokenStorage() ) let transport = HTTPClientTransport( endpoint: URL(string: "https://api.example.com/mcp")!, authorizer: authorizer ) // 4. Connect (will show webview for authorization) let client = Client(name: "MyApp", version: "1.0.0") try await client.connect(transport: transport) ``` -------------------------------- ### Complete Prompt with Arguments Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/client-api.md Use this method to get completion suggestions for a given prompt name, argument name, and partial argument value. Context can be provided for previously resolved arguments. ```swift public func complete( promptName: String, argumentName: String, argumentValue: String, context: [String: Value]? = nil ) async throws -> Completion ``` ```swift let completion = try await client.complete( promptName: "code_review", argumentName: "language", argumentValue: "py" ) for suggestion in completion.values { print("Suggestion: \(suggestion)") } ``` -------------------------------- ### Enable Completions Capability and Register Handler Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Enables the completions capability for the server and registers a handler to provide autocompletion suggestions for prompt and resource template arguments. This example shows how to provide language completions. ```swift // Enable completions capability let server = Server( name: "MyServer", version: "1.0.0", capabilities: .init( completions: .init(), prompts: .init(listChanged: true) ) ) // Register a completion handler await server.withMethodHandler(Complete.self) { params in // Get the argument being completed let argumentName = params.argument.name let currentValue = params.argument.value // Check which prompt or resource is being completed switch params.ref { case .prompt(let promptRef): // Provide completions for a prompt argument if promptRef.name == "code_review" && argumentName == "language" { // Simple prefix matching let allLanguages = ["python", "perl", "php", "javascript", "java", "swift"] let matches = allLanguages.filter { $0.hasPrefix(currentValue.lowercased()) } return .init( completion: .init( values: Array(matches.prefix(100)), // Max 100 items total: matches.count, hasMore: matches.count > 100 ) ) } case .resource(let resourceRef): // Provide completions for a resource template argument if resourceRef.uri == "file:///{path}" && argumentName == "path" { // Return directory suggestions let suggestions = try getDirectoryCompletions(for: currentValue) return .init( completion: .init( values: suggestions, total: suggestions.count, hasMore: false ) ) } } // No completions available return .init(completion: .init(values: [], total: 0, hasMore: false)) } ``` -------------------------------- ### Configure and Run MCP Application Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Set up the MCP server, add method handlers, and integrate it into a ServiceGroup for managed startup and shutdown with signal handling. ```swift import MCP import ServiceLifecycle import Logging let logger = Logger(label: "com.example.mcp-server") // Create the MCP server let server = Server( name: "MyModelServer", version: "1.0.0", capabilities: .init( prompts: .init(listChanged: true), resources: .init(subscribe: true, listChanged: true), tools: .init(listChanged: true) ) ) // Add handlers directly to the server await server.withMethodHandler(ListTools.self) { _ in // Your implementation return .init(tools: [ Tool(name: "example", description: "An example tool") ]) } await server.withMethodHandler(CallTool.self) { params in // Your implementation return .init(content: [.text("Tool result")], isError: false) } // Create MCP service and other services let transport = StdioTransport(logger: logger) let mcpService = MCPService(server: server, transport: transport) let databaseService = DatabaseService() // Your other services // Create service group with signal handling let serviceGroup = ServiceGroup( services: [mcpService, databaseService], configuration: .init( gracefulShutdownSignals: [.sigterm, .sigint] ), logger: logger ) // Run the service group - this blocks until shutdown try await serviceGroup.run() ``` -------------------------------- ### Initialize Server with Name and Version Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Use this initializer to create a basic Server instance with only its name and version. This is suitable when default capabilities and configuration are sufficient. ```swift let server = Server( name: "MyDataServer", version: "2.1.0" ) ``` -------------------------------- ### Initialize Server with Custom Capabilities and Configuration Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Create a Server instance with specific capabilities and configuration. This allows fine-grained control over which features are advertised to clients. Ensure the capabilities object is correctly populated with desired features. ```swift let server = Server( name: "AnalysisServer", version: "1.0.0", capabilities: .init( tools: .init(listChanged: true), resources: .init(subscribe: true, listChanged: true), prompts: .init(listChanged: true), logging: .init(), completions: .init() ) ) ``` -------------------------------- ### Server.init(name:version:capabilities:configuration:) Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Initializes a Server actor with name, version, custom capabilities, and configuration. This allows for fine-grained control over advertised features. ```APIDOC ## Server.init(name:version:capabilities:configuration:) ### Description Creates a server with specified capabilities. Only capabilities declared here are advertised to clients. ### Parameters #### Path Parameters - **name** (String) - Required - Server name - **version** (String) - Required - Server version - **capabilities** (Capabilities) - Optional - Server capabilities to advertise (defaults to empty) - **configuration** (Configuration) - Optional - Configuration options (defaults to .default) ### Request Example ```swift let server = Server( name: "AnalysisServer", version: "1.0.0", capabilities: .init( tools: .init(listChanged: true), resources: .init(subscribe: true, listChanged: true), prompts: .init(listChanged: true), logging: .init(), completions: .init() ) ) ``` ### Response #### Success Response - **Server** (actor) - An initialized Server actor with specified capabilities and configuration ``` -------------------------------- ### Lifecycle Methods Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/exports.md Methods for managing the lifecycle of the client, including starting and stopping the service. ```APIDOC ## start(transport: any Transport) ### Description Starts the client with the specified transport. ### Method `async throws` ### Parameters - **transport** (any Transport) - The transport layer to use for communication. ``` ```APIDOC ## start(transport: any Transport, onInitialize: @escaping (ClientInfo, Client.Capabilities) async throws -> Void) ### Description Starts the client with the specified transport and an initialization callback. ### Method `async throws` ### Parameters - **transport** (any Transport) - The transport layer to use for communication. - **onInitialize** (@escaping (ClientInfo, Client.Capabilities) async throws -> Void) - A callback function executed upon successful initialization. ``` ```APIDOC ## stop() ### Description Stops the client and releases associated resources. ### Method `async` ``` ```APIDOC ## waitUntilCompleted() ### Description Waits until the client has completed all its operations. ### Method `async` ``` -------------------------------- ### List Prompts Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Retrieves a list of all available prompts that can be used to start conversations or generate messages. ```APIDOC ## List Prompts ### Description Fetches a list of all available prompts on the MCP server that can be used to initiate conversations or generate templated messages. ### Method `client.listPrompts() ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let (prompts, nextCursor) = try await client.listPrompts() print("Available prompts: \(prompts.map { $0.name }.joined(separator: ", "))") ``` ### Response #### Success Response (200) A tuple containing an array of `Prompt` objects and a cursor for pagination. #### Response Example ```json { "prompts": [ { "name": "customer-service", "description": "Template for customer service inquiries." } ], "nextCursor": "next_page_cursor" } ``` ``` -------------------------------- ### Get Prompt Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Retrieves a specific prompt by name, along with its associated messages, potentially populated with arguments. ```APIDOC ## Get Prompt ### Description Retrieves a specific prompt by its name and provides its description and a sequence of messages, which can be generated using provided arguments. ### Method `client.getPrompt(name:arguments:) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let (description, messages) = try await client.getPrompt( name: "customer-service", arguments: [ "customerName": "Alice", "orderNumber": "ORD-12345", "issue": "delivery delay" ] ) print("Prompt description: \(description)") for message in messages { if case .text(text: let text) = message.content { print("\(message.role): \(text)") } } ``` ### Response #### Success Response (200) A tuple containing the prompt's description string and an array of `Message` objects. #### Response Example ```json { "description": "Customer service inquiry template.", "messages": [ { "role": "user", "content": { "type": "text", "text": "Customer Alice with order ORD-12345 is experiencing a delivery delay." } } ] } ``` ``` -------------------------------- ### Initialize SDK Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/exports.md Asynchronously initializes the SDK. This operation may throw an error. ```swift public func initialize() async throws -> Initialize.Result ``` -------------------------------- ### Server.init(name:version:) Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Initializes a Server actor with a name and version. This is a basic initialization for the server. ```APIDOC ## Server.init(name:version:) ### Description Initializes a Server actor with a name and version. ### Parameters #### Path Parameters - **name** (String) - Required - The server name - **version** (String) - Required - The server version in semver format ### Request Example ```swift let server = Server( name: "MyDataServer", version: "2.1.0" ) ``` ### Response #### Success Response - **Server** (actor) - An initialized Server actor with default capabilities and configuration ``` -------------------------------- ### HTTP Request Validators Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/transport-api.md Details the `HTTPRequestValidator` protocol and provides an example of setting up a validation pipeline with built-in validators. ```APIDOC ## HTTP Request Validators ### Description Request validators form a pipeline to validate HTTP requests before routing to handlers. This section outlines the `HTTPRequestValidator` protocol and provides an example of its usage. ### Protocol `HTTPRequestValidator` ### Method - `validate(request: HTTPRequest, context: HTTPContext) async throws`: Validates an incoming HTTP request. ### Built-in Validators - **AcceptHeaderValidator**: Validates `Accept` header (SSE vs non-streaming). - **ContentTypeValidator**: Validates `Content-Type` is application/json. - **SessionValidator**: Manages session lifecycle for stateful transports. - **ProtectedResourceMetadataValidator**: Serves `/.well-known/oauth-protected-resource`. - **BearerTokenValidator**: Validates OAuth Bearer tokens. ### Example Usage Demonstrates creating a `StandardValidationPipeline` with several built-in validators, including `ProtectedResourceMetadataValidator` and `BearerTokenValidator`. ``` -------------------------------- ### List Filesystem Roots Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Requests the list of filesystem roots exposed by the client. Use this to get an array of Root objects. ```swift public func listRoots() async throws -> [Root] ``` ```swift let roots = try await server.listRoots() for root in roots { print("Root: \(root.name ?? root.uri)") } ``` -------------------------------- ### Get Prompt with Arguments Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/client-api.md Retrieves a specific prompt by name, allowing customization through arguments. Throws an error if the prompt is not found. ```swift public func getPrompt( name: String, arguments: [String: String]? = nil ) async throws -> (description: String?, messages: [Prompt.Message]) ``` ```swift let (description, messages) = try await client.getPrompt( name: "code-review", arguments: ["language": "swift", "file": "client.swift"] ) print("Prompt: \(description ?? "")") for message in messages { print("[\(message.role)]: \(message.content)") } ``` -------------------------------- ### Handle ListPrompts Server Method Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/_autodocs/api-reference/server-api.md Implement a handler for the `ListPrompts` method to define available prompts. This includes setting the prompt name, description, and required arguments. ```swift server.withMethodHandler(ListPrompts.self) { params in let prompts = [ Prompt( name: "code-review", description: "Code review assistant", arguments: [ .init(name: "language", description: "Programming language", required: true) ] ) ] return .init(prompts: prompts, nextCursor: nil) } ``` -------------------------------- ### Implementing Resource Handlers in Swift Source: https://github.com/modelcontextprotocol/swift-sdk/blob/main/README.md Set up handlers for listing, reading, and subscribing to resources. This allows clients to access and interact with your server's data. ```swift // Register a resource list handler await server.withMethodHandler(ListResources.self) { params in let resources = [ Resource( name: "Knowledge Base Articles", uri: "resource://knowledge-base/articles", description: "Collection of support articles and documentation" ), Resource( name: "System Status", uri: "resource://system/status", description: "Current system operational status" ) ] return .init(resources: resources, nextCursor: nil) } ``` ```swift // Register a resource read handler await server.withMethodHandler(ReadResource.self) { params in switch params.uri { case "resource://knowledge-base/articles": return .init(contents: [Resource.Content.text("# Knowledge Base\n\nThis is the content of the knowledge base...", uri: params.uri)]) case "resource://system/status": let status = getCurrentSystemStatus() // Your implementation let statusJson = """ { "status": "\(status.overall)", "components": { "database": "\(status.database)", "api": "\(status.api)", "model": "\(status.model)" }, "lastUpdated": "\(status.timestamp)" } """ return .init(contents: [Resource.Content.text(statusJson, uri: params.uri, mimeType: "application/json")]) default: throw MCPError.invalidParams("Unknown resource URI: \(params.uri)") } } ``` ```swift // Register a resource subscribe handler await server.withMethodHandler(ResourceSubscribe.self) { params in // Store subscription for later notifications. // Client identity for multi-client scenarios needs to be managed by the server application, // potentially using information from the initialize handshake if the server handles one client post-init. // addSubscription(clientID: /* some_client_identifier */, uri: params.uri) print("Client subscribed to \(params.uri). Server needs to implement logic to track this subscription.") return .init() } ```