diff --git a/Sources/MCP/Base/Error.swift b/Sources/MCP/Base/Error.swift index 9830fca0..6ce4e1a5 100644 --- a/Sources/MCP/Base/Error.swift +++ b/Sources/MCP/Base/Error.swift @@ -6,24 +6,8 @@ import Foundation @preconcurrency import SystemPackage #endif -/// Top-level namespace for backward compatibility -/// -/// This is provided to allow existing code that uses `MCP.Error` to continue -/// to work without modification. -/// -/// The MCPError type is now the recommended way to handle errors in MCP. -/// -/// - Warning: This namespace is deprecated and will be removed in a future version. -public enum MCP { - /// Deprecated type alias for MCPError - @available(*, deprecated, renamed: "MCPError", message: "Use MCPError instead of MCP.Error") - public typealias Error = MCPError -} - -// MARK: - - /// A model context protocol error. -public enum MCPError: Error, Sendable { +public enum MCPError: Swift.Error, Sendable { // Standard JSON-RPC 2.0 errors (-32700 to -32603) case parseError(String?) // -32700 case invalidRequest(String?) // -32600 @@ -36,7 +20,7 @@ public enum MCPError: Error, Sendable { // Transport specific errors case connectionClosed - case transportError(Error) + case transportError(Swift.Error) /// The JSON-RPC 2.0 error code public var code: Int { @@ -53,7 +37,7 @@ public enum MCPError: Error, Sendable { } /// Check if an error represents a "resource temporarily unavailable" condition - public static func isResourceTemporarilyUnavailable(_ error: Error) -> Bool { + public static func isResourceTemporarilyUnavailable(_ error: Swift.Error) -> Bool { #if canImport(System) if let errno = error as? System.Errno, errno == .resourceTemporarilyUnavailable { return true @@ -246,3 +230,12 @@ extension MCPError: Hashable { } } } + +// MARK: - + +/// This is provided to allow existing code that uses `MCP.Error` to continue +/// to work without modification. +/// +/// The MCPError type is now the recommended way to handle errors in MCP. +@available(*, deprecated, renamed: "MCPError", message: "Use MCPError instead of MCP.Error") +public typealias Error = MCPError diff --git a/Sources/MCP/Base/Transports.swift b/Sources/MCP/Base/Transports.swift index 28eec380..f9e8151e 100644 --- a/Sources/MCP/Base/Transports.swift +++ b/Sources/MCP/Base/Transports.swift @@ -23,7 +23,7 @@ public protocol Transport: Actor { func send(_ data: Data) async throws /// Receives data in an async sequence - func receive() -> AsyncThrowingStream + func receive() -> AsyncThrowingStream } /// Standard input/output transport implementation @@ -158,7 +158,7 @@ public actor StdioTransport: Transport { } } - public func receive() -> AsyncThrowingStream { + public func receive() -> AsyncThrowingStream { return AsyncThrowingStream { continuation in Task { for await message in messageStream { @@ -179,8 +179,8 @@ public actor StdioTransport: Transport { public nonisolated let logger: Logger private var isConnected = false - private let messageStream: AsyncThrowingStream - private let messageContinuation: AsyncThrowingStream.Continuation + private let messageStream: AsyncThrowingStream + private let messageContinuation: AsyncThrowingStream.Continuation // Track connection state for continuations private var connectionContinuationResumed = false @@ -195,7 +195,7 @@ public actor StdioTransport: Transport { ) // Create message stream - var continuation: AsyncThrowingStream.Continuation! + var continuation: AsyncThrowingStream.Continuation! self.messageStream = AsyncThrowingStream { continuation = $0 } self.messageContinuation = continuation } @@ -209,7 +209,7 @@ public actor StdioTransport: Transport { // Wait for connection to be ready try await withCheckedThrowingContinuation { - [weak self] (continuation: CheckedContinuation) in + [weak self] (continuation: CheckedContinuation) in guard let self = self else { continuation.resume(throwing: MCPError.internalError("Transport deallocated")) return @@ -245,7 +245,7 @@ public actor StdioTransport: Transport { } } - private func handleConnectionReady(continuation: CheckedContinuation) + private func handleConnectionReady(continuation: CheckedContinuation) async { if !connectionContinuationResumed { @@ -259,7 +259,7 @@ public actor StdioTransport: Transport { } private func handleConnectionFailed( - error: Error, continuation: CheckedContinuation + error: Swift.Error, continuation: CheckedContinuation ) async { if !connectionContinuationResumed { connectionContinuationResumed = true @@ -268,7 +268,7 @@ public actor StdioTransport: Transport { } } - private func handleConnectionCancelled(continuation: CheckedContinuation) + private func handleConnectionCancelled(continuation: CheckedContinuation) async { if !connectionContinuationResumed { @@ -299,7 +299,7 @@ public actor StdioTransport: Transport { var sendContinuationResumed = false try await withCheckedThrowingContinuation { - [weak self] (continuation: CheckedContinuation) in + [weak self] (continuation: CheckedContinuation) in guard let self = self else { continuation.resume(throwing: MCPError.internalError("Transport deallocated")) return @@ -326,7 +326,7 @@ public actor StdioTransport: Transport { } } - public func receive() -> AsyncThrowingStream { + public func receive() -> AsyncThrowingStream { return AsyncThrowingStream { continuation in Task { do { @@ -382,7 +382,7 @@ public actor StdioTransport: Transport { var receiveContinuationResumed = false return try await withCheckedThrowingContinuation { - [weak self] (continuation: CheckedContinuation) in + [weak self] (continuation: CheckedContinuation) in guard let self = self else { continuation.resume(throwing: MCPError.internalError("Transport deallocated")) return diff --git a/Sources/MCP/Client/Client.swift b/Sources/MCP/Client/Client.swift index 7b4dd31a..50de0567 100644 --- a/Sources/MCP/Client/Client.swift +++ b/Sources/MCP/Client/Client.swift @@ -112,16 +112,16 @@ public actor Client { private var task: Task? /// An error indicating a type mismatch when decoding a pending request - private struct TypeMismatchError: Error {} + private struct TypeMismatchError: Swift.Error {} /// A pending request with a continuation for the result private struct PendingRequest { - let continuation: CheckedContinuation + let continuation: CheckedContinuation } /// A type-erased pending request private struct AnyPendingRequest { - private let _resume: (Result) -> Void + private let _resume: (Result) -> Void init(_ request: PendingRequest) { _resume = { result in @@ -146,7 +146,7 @@ public actor Client { _resume(.success(value)) } - func resume(throwing error: Error) { + func resume(throwing error: Swift.Error) { _resume(.failure(error)) } } @@ -274,7 +274,7 @@ public actor Client { private func addPendingRequest( id: ID, - continuation: CheckedContinuation, + continuation: CheckedContinuation, type: T.Type ) { pendingRequests[id] = AnyPendingRequest(PendingRequest(continuation: continuation)) diff --git a/Tests/MCPTests/ClientTests.swift b/Tests/MCPTests/ClientTests.swift index 4eaf1361..502bc728 100644 --- a/Tests/MCPTests/ClientTests.swift +++ b/Tests/MCPTests/ClientTests.swift @@ -132,7 +132,7 @@ struct ClientTests { try await client.connect(transport: transport) // Create a task for listPrompts - let promptsTask = Task { + let promptsTask = Task { do { _ = try await client.listPrompts() #expect(Bool(false), "Expected listPrompts to fail in strict mode") diff --git a/Tests/MCPTests/Helpers/MockTransport.swift b/Tests/MCPTests/Helpers/MockTransport.swift index 1ebdce5c..bcd8dd9d 100644 --- a/Tests/MCPTests/Helpers/MockTransport.swift +++ b/Tests/MCPTests/Helpers/MockTransport.swift @@ -1,10 +1,10 @@ -import class Foundation.JSONEncoder -import class Foundation.JSONDecoder +import Logging + import struct Foundation.Data +import class Foundation.JSONDecoder +import class Foundation.JSONEncoder import struct Foundation.POSIXError -import Logging - @testable import MCP /// Mock transport for testing @@ -30,7 +30,7 @@ actor MockTransport: Transport { private var dataToReceive: [Data] = [] private(set) var receivedMessages: [String] = [] - private var dataStreamContinuation: AsyncThrowingStream.Continuation? + private var dataStreamContinuation: AsyncThrowingStream.Continuation? var shouldFailConnect = false var shouldFailSend = false @@ -59,8 +59,8 @@ actor MockTransport: Transport { sentData.append(message) } - public func receive() -> AsyncThrowingStream { - return AsyncThrowingStream { continuation in + public func receive() -> AsyncThrowingStream { + return AsyncThrowingStream { continuation in dataStreamContinuation = continuation for message in dataToReceive { continuation.yield(message) diff --git a/Tests/MCPTests/TransportTests.swift b/Tests/MCPTests/TransportTests.swift index b4871bee..e395fbe0 100644 --- a/Tests/MCPTests/TransportTests.swift +++ b/Tests/MCPTests/TransportTests.swift @@ -57,7 +57,7 @@ struct StdioTransportTests { try writer.close() // Start receiving messages - let stream: AsyncThrowingStream = await transport.receive() + let stream: AsyncThrowingStream = await transport.receive() var iterator = stream.makeAsyncIterator() // Get first message @@ -79,7 +79,7 @@ struct StdioTransportTests { try writer.writeAll(invalidJSON.data(using: .utf8)!) try writer.close() - let stream: AsyncThrowingStream = await transport.receive() + let stream: AsyncThrowingStream = await transport.receive() var iterator = stream.makeAsyncIterator() _ = try await iterator.next()