Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 12 additions & 19 deletions Sources/MCP/Base/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
24 changes: 12 additions & 12 deletions Sources/MCP/Base/Transports.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public protocol Transport: Actor {
func send(_ data: Data) async throws

/// Receives data in an async sequence
func receive() -> AsyncThrowingStream<Data, Error>
func receive() -> AsyncThrowingStream<Data, Swift.Error>
}

/// Standard input/output transport implementation
Expand Down Expand Up @@ -158,7 +158,7 @@ public actor StdioTransport: Transport {
}
}

public func receive() -> AsyncThrowingStream<Data, Error> {
public func receive() -> AsyncThrowingStream<Data, Swift.Error> {
return AsyncThrowingStream { continuation in
Task {
for await message in messageStream {
Expand All @@ -179,8 +179,8 @@ public actor StdioTransport: Transport {
public nonisolated let logger: Logger

private var isConnected = false
private let messageStream: AsyncThrowingStream<Data, Error>
private let messageContinuation: AsyncThrowingStream<Data, Error>.Continuation
private let messageStream: AsyncThrowingStream<Data, Swift.Error>
private let messageContinuation: AsyncThrowingStream<Data, Swift.Error>.Continuation

// Track connection state for continuations
private var connectionContinuationResumed = false
Expand All @@ -195,7 +195,7 @@ public actor StdioTransport: Transport {
)

// Create message stream
var continuation: AsyncThrowingStream<Data, Error>.Continuation!
var continuation: AsyncThrowingStream<Data, Swift.Error>.Continuation!
self.messageStream = AsyncThrowingStream { continuation = $0 }
self.messageContinuation = continuation
}
Expand All @@ -209,7 +209,7 @@ public actor StdioTransport: Transport {

// Wait for connection to be ready
try await withCheckedThrowingContinuation {
[weak self] (continuation: CheckedContinuation<Void, Error>) in
[weak self] (continuation: CheckedContinuation<Void, Swift.Error>) in
guard let self = self else {
continuation.resume(throwing: MCPError.internalError("Transport deallocated"))
return
Expand Down Expand Up @@ -245,7 +245,7 @@ public actor StdioTransport: Transport {
}
}

private func handleConnectionReady(continuation: CheckedContinuation<Void, Error>)
private func handleConnectionReady(continuation: CheckedContinuation<Void, Swift.Error>)
async
{
if !connectionContinuationResumed {
Expand All @@ -259,7 +259,7 @@ public actor StdioTransport: Transport {
}

private func handleConnectionFailed(
error: Error, continuation: CheckedContinuation<Void, Error>
error: Swift.Error, continuation: CheckedContinuation<Void, Swift.Error>
) async {
if !connectionContinuationResumed {
connectionContinuationResumed = true
Expand All @@ -268,7 +268,7 @@ public actor StdioTransport: Transport {
}
}

private func handleConnectionCancelled(continuation: CheckedContinuation<Void, Error>)
private func handleConnectionCancelled(continuation: CheckedContinuation<Void, Swift.Error>)
async
{
if !connectionContinuationResumed {
Expand Down Expand Up @@ -299,7 +299,7 @@ public actor StdioTransport: Transport {
var sendContinuationResumed = false

try await withCheckedThrowingContinuation {
[weak self] (continuation: CheckedContinuation<Void, Error>) in
[weak self] (continuation: CheckedContinuation<Void, Swift.Error>) in
guard let self = self else {
continuation.resume(throwing: MCPError.internalError("Transport deallocated"))
return
Expand All @@ -326,7 +326,7 @@ public actor StdioTransport: Transport {
}
}

public func receive() -> AsyncThrowingStream<Data, Error> {
public func receive() -> AsyncThrowingStream<Data, Swift.Error> {
return AsyncThrowingStream { continuation in
Task {
do {
Expand Down Expand Up @@ -382,7 +382,7 @@ public actor StdioTransport: Transport {
var receiveContinuationResumed = false

return try await withCheckedThrowingContinuation {
[weak self] (continuation: CheckedContinuation<Data, Error>) in
[weak self] (continuation: CheckedContinuation<Data, Swift.Error>) in
guard let self = self else {
continuation.resume(throwing: MCPError.internalError("Transport deallocated"))
return
Expand Down
10 changes: 5 additions & 5 deletions Sources/MCP/Client/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,16 @@ public actor Client {
private var task: Task<Void, Never>?

/// 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<T> {
let continuation: CheckedContinuation<T, Error>
let continuation: CheckedContinuation<T, Swift.Error>
}

/// A type-erased pending request
private struct AnyPendingRequest {
private let _resume: (Result<Any, Error>) -> Void
private let _resume: (Result<Any, Swift.Error>) -> Void

init<T: Sendable & Decodable>(_ request: PendingRequest<T>) {
_resume = { result in
Expand All @@ -146,7 +146,7 @@ public actor Client {
_resume(.success(value))
}

func resume(throwing error: Error) {
func resume(throwing error: Swift.Error) {
_resume(.failure(error))
}
}
Expand Down Expand Up @@ -274,7 +274,7 @@ public actor Client {

private func addPendingRequest<T: Sendable & Decodable>(
id: ID,
continuation: CheckedContinuation<T, Error>,
continuation: CheckedContinuation<T, Swift.Error>,
type: T.Type
) {
pendingRequests[id] = AnyPendingRequest(PendingRequest(continuation: continuation))
Expand Down
2 changes: 1 addition & 1 deletion Tests/MCPTests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct ClientTests {
try await client.connect(transport: transport)

// Create a task for listPrompts
let promptsTask = Task<Void, Error> {
let promptsTask = Task<Void, Swift.Error> {
do {
_ = try await client.listPrompts()
#expect(Bool(false), "Expected listPrompts to fail in strict mode")
Expand Down
14 changes: 7 additions & 7 deletions Tests/MCPTests/Helpers/MockTransport.swift
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -30,7 +30,7 @@ actor MockTransport: Transport {
private var dataToReceive: [Data] = []
private(set) var receivedMessages: [String] = []

private var dataStreamContinuation: AsyncThrowingStream<Data, Error>.Continuation?
private var dataStreamContinuation: AsyncThrowingStream<Data, Swift.Error>.Continuation?

var shouldFailConnect = false
var shouldFailSend = false
Expand Down Expand Up @@ -59,8 +59,8 @@ actor MockTransport: Transport {
sentData.append(message)
}

public func receive() -> AsyncThrowingStream<Data, Error> {
return AsyncThrowingStream<Data, Error> { continuation in
public func receive() -> AsyncThrowingStream<Data, Swift.Error> {
return AsyncThrowingStream<Data, Swift.Error> { continuation in
dataStreamContinuation = continuation
for message in dataToReceive {
continuation.yield(message)
Expand Down
4 changes: 2 additions & 2 deletions Tests/MCPTests/TransportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct StdioTransportTests {
try writer.close()

// Start receiving messages
let stream: AsyncThrowingStream<Data, Error> = await transport.receive()
let stream: AsyncThrowingStream<Data, Swift.Error> = await transport.receive()
var iterator = stream.makeAsyncIterator()

// Get first message
Expand All @@ -79,7 +79,7 @@ struct StdioTransportTests {
try writer.writeAll(invalidJSON.data(using: .utf8)!)
try writer.close()

let stream: AsyncThrowingStream<Data, Error> = await transport.receive()
let stream: AsyncThrowingStream<Data, Swift.Error> = await transport.receive()
var iterator = stream.makeAsyncIterator()

_ = try await iterator.next()
Expand Down