From 414b31f0e9422974676dfd3cd979e9b56aec7e03 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Fri, 7 Mar 2025 10:07:52 -0800 Subject: [PATCH 1/8] Fixing issues for env variables --- .../DataChannel+StdioProcess.swift | 129 +++++++++++------- 1 file changed, 77 insertions(+), 52 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index e3d83b2..818a5e1 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -1,4 +1,3 @@ - import Foundation import JSONRPC import MCPInterface @@ -64,44 +63,46 @@ extension Transport { guard !executable.contains("/") else { return executable } - do { - let path = try locate(executable: executable, env: env) - return path.isEmpty ? nil : path - } catch { - // Most likely an error because we could not locate the executable - return nil + + // Create the process + func path(for executable: String, env: [String: String]?) -> String? { + guard !executable.contains("/") else { + return executable + } + do { + let path = try locate(executable: executable, env: env) + return path.isEmpty ? nil : path + } catch { + // Most likely an error because we could not locate the executable + return nil + } } - } - - let process = Process() - // In MacOS, zsh is the default since macOS Catalina 10.15.7. We can safely assume it is available. - process.launchPath = "/bin/zsh" - if let executable = path(for: executable, env: env) { - let command = "\(executable) \(args.joined(separator: " "))" - process.arguments = ["-c"] + [command] - process.environment = env ?? ProcessInfo.processInfo.environment - } else { - // If we cannot locate the executable, try loading the default environment for zsh, as the current process might not have the correct PATH. - process.environment = try loadZshEnvironment() + + let process = Process() + // In MacOS, zsh is the default since macOS Catalina 10.15.7. We can safely assume it is available. + process.launchPath = "/bin/zsh" + + // Load shell environment and merge with user-provided environment + process.environment = try loadZshEnvironment(userEnv: env) + let command = "\(executable) \(args.joined(separator: " "))" process.arguments = ["-c"] + [command] - } - - // Working directory - if let cwd { - process.currentDirectoryPath = cwd - } - - // Input/output - let stdin = Pipe() - let stdout = Pipe() - let stderr = Pipe() - process.standardInput = stdin - process.standardOutput = stdout - process.standardError = stderr - - return try stdioProcess(unlaunchedProcess: process, verbose: verbose) - } + + // Working directory + if let cwd { + process.currentDirectoryPath = cwd + } + + // Input/output + let stdin = Pipe() + let stdout = Pipe() + let stderr = Pipe() + process.standardInput = stdin + process.standardOutput = stdout + process.standardError = stderr + + return try stdioProcess(unlaunchedProcess: process, verbose: verbose) + } /// Creates a new `Transport` by launching the given process and attaching to its standard IO. public static func stdioProcess( @@ -207,22 +208,46 @@ extension Transport { } return executablePath } - - private static func loadZshEnvironment() throws -> [String: String] { - let process = Process() - process.launchPath = "/bin/zsh" - // Those are loaded for interactive login shell by zsh: - // https://www.freecodecamp.org/news/how-do-zsh-configuration-files-work/ - process.arguments = ["-c", "source ~/.zshenv; source ~/.zprofile; source ~/.zshrc; source ~/.zshrc; printenv"] - let env = try getProcessStdout(process: process) - - if let path = env?.split(separator: "\n").filter({ $0.starts(with: "PATH=") }).last { - return ["PATH": String(path.dropFirst("PATH=".count))] - } else { - return ProcessInfo.processInfo.environment - } - } - + + private static func loadZshEnvironment(userEnv: [String: String]? = nil) throws -> [String: String] { + // Load shell environment as base + let shellProcess = Process() + shellProcess.executableURL = URL(fileURLWithPath: "/bin/zsh") + shellProcess.arguments = ["-ilc", "printenv"] + + let outputPipe = Pipe() + shellProcess.standardOutput = outputPipe + shellProcess.standardError = Pipe() + + try shellProcess.run() + shellProcess.waitUntilExit() + + let data = outputPipe.fileHandleForReading.readDataToEndOfFile() + guard let outputString = String(data: data, encoding: .utf8) else { + logger.error("Failed to read environment from shell.") + return ProcessInfo.processInfo.environment + } + + // Parse shell environment + var mergedEnv: [String: String] = [:] + outputString.split(separator: "\n").forEach { line in + let components = line.split(separator: "=", maxSplits: 1) + guard components.count == 2 else { return } + let key = String(components[0]) + let value = String(components[1]) + mergedEnv[key] = value + } + + // Overlay user-defined environment variables explicitly + userEnv?.forEach { key, value in + mergedEnv[key] = value + } + + // Log for debugging clarity + logger.debug("Final merged environment: \(mergedEnv)") + + return mergedEnv + } private static func getProcessStdout(process: Process) throws -> String? { let stdout = Pipe() let stderr = Pipe() From fe79026afb1a30e8cc4d55dd4d5323c34a118176 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Sun, 9 Mar 2025 22:55:40 -0700 Subject: [PATCH 2/8] PR review --- .../DataChannel+StdioProcess.swift | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index 818a5e1..aa7c735 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -44,24 +44,20 @@ extension JSONRPCSetupError: LocalizedError { extension Transport { - /// Creates a new `Transport` by launching the given executable with the specified arguments and attaching to its standard IO. - public static func stdioProcess( - _ executable: String, - args: [String] = [], - cwd: String? = nil, - env: [String: String]? = nil, - verbose: Bool = false) - throws -> Transport - { - if verbose { - let command = "\(executable) \(args.joined(separator: " "))" - logger.log("Running ↪ \(command)") - } - - // Create the process - func path(for executable: String, env: [String: String]?) -> String? { - guard !executable.contains("/") else { - return executable + // MARK: Public + + /// Creates a new `Transport` by launching the given executable with the specified arguments and attaching to its standard IO. + public static func stdioProcess( + _ executable: String, + args: [String] = [], + cwd: String? = nil, + env: [String: String]? = nil, + verbose: Bool = false) + throws -> Transport + { + if verbose { + let command = "\(executable) \(args.joined(separator: " "))" + logger.log("Running ↪ \(command)") } // Create the process @@ -82,11 +78,17 @@ extension Transport { // In MacOS, zsh is the default since macOS Catalina 10.15.7. We can safely assume it is available. process.launchPath = "/bin/zsh" - // Load shell environment and merge with user-provided environment - process.environment = try loadZshEnvironment(userEnv: env) - - let command = "\(executable) \(args.joined(separator: " "))" - process.arguments = ["-c"] + [command] + if let executable = path(for: executable, env: env) { + // If executable is found directly, use user-provided env or current process env + process.environment = env ?? ProcessInfo.processInfo.environment + let command = "\(executable) \(args.joined(separator: " "))" + process.arguments = ["-c"] + [command] + } else { + // If we cannot locate the executable, try loading the default environment for zsh + process.environment = try loadZshEnvironment(userEnv: env) + let command = "\(executable) \(args.joined(separator: " "))" + process.arguments = ["-c"] + [command] + } // Working directory if let cwd { From c71ab7c9dadae60ac406f3f455e49af438680823 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Sun, 9 Mar 2025 23:22:59 -0700 Subject: [PATCH 3/8] merging user provided env variables --- .../DataChannel+StdioProcess.swift | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index aa7c735..1b62c19 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -215,7 +215,19 @@ extension Transport { // Load shell environment as base let shellProcess = Process() shellProcess.executableURL = URL(fileURLWithPath: "/bin/zsh") - shellProcess.arguments = ["-ilc", "printenv"] + + // When userEnv exists, we need to explicitly export these variables in the shell + // before running printenv so they're included in the environment output + if let userEnv = userEnv, !userEnv.isEmpty { + var exportCommands = userEnv.map { key, value in + return "export \(key)=\(value.replacingOccurrences(of: "\"", with: "\\\""))" + }.joined(separator: "; ") + + exportCommands += "; printenv" + shellProcess.arguments = ["-ilc", exportCommands] + } else { + shellProcess.arguments = ["-ilc", "printenv"] + } let outputPipe = Pipe() shellProcess.standardOutput = outputPipe @@ -240,16 +252,12 @@ extension Transport { mergedEnv[key] = value } - // Overlay user-defined environment variables explicitly - userEnv?.forEach { key, value in - mergedEnv[key] = value - } - - // Log for debugging clarity - logger.debug("Final merged environment: \(mergedEnv)") + // Debug logging to verify environment was properly merged + logger.debug("Shell environment loaded with user variables successfully merged") return mergedEnv } + private static func getProcessStdout(process: Process) throws -> String? { let stdout = Pipe() let stderr = Pipe() From 4b043a2baaad63feb167e2d58a063cffd0479ce3 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Sun, 9 Mar 2025 23:57:54 -0700 Subject: [PATCH 4/8] lint --- .../DataChannel+StdioProcess.swift | 212 +++++++++--------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index 1b62c19..cf764f1 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -45,66 +45,66 @@ extension JSONRPCSetupError: LocalizedError { extension Transport { // MARK: Public - - /// Creates a new `Transport` by launching the given executable with the specified arguments and attaching to its standard IO. - public static func stdioProcess( - _ executable: String, - args: [String] = [], - cwd: String? = nil, - env: [String: String]? = nil, - verbose: Bool = false) - throws -> Transport - { - if verbose { - let command = "\(executable) \(args.joined(separator: " "))" - logger.log("Running ↪ \(command)") - } - - // Create the process - func path(for executable: String, env: [String: String]?) -> String? { - guard !executable.contains("/") else { - return executable - } - do { - let path = try locate(executable: executable, env: env) - return path.isEmpty ? nil : path - } catch { - // Most likely an error because we could not locate the executable - return nil - } - } - - let process = Process() - // In MacOS, zsh is the default since macOS Catalina 10.15.7. We can safely assume it is available. - process.launchPath = "/bin/zsh" - - if let executable = path(for: executable, env: env) { - // If executable is found directly, use user-provided env or current process env - process.environment = env ?? ProcessInfo.processInfo.environment - let command = "\(executable) \(args.joined(separator: " "))" - process.arguments = ["-c"] + [command] - } else { - // If we cannot locate the executable, try loading the default environment for zsh - process.environment = try loadZshEnvironment(userEnv: env) - let command = "\(executable) \(args.joined(separator: " "))" - process.arguments = ["-c"] + [command] + + /// Creates a new `Transport` by launching the given executable with the specified arguments and attaching to its standard IO. + public static func stdioProcess( + _ executable: String, + args: [String] = [], + cwd: String? = nil, + env: [String: String]? = nil, + verbose: Bool = false) + throws -> Transport + { + if verbose { + let command = "\(executable) \(args.joined(separator: " "))" + logger.log("Running ↪ \(command)") + } + + // Create the process + func path(for executable: String, env: [String: String]?) -> String? { + guard !executable.contains("/") else { + return executable } - - // Working directory - if let cwd { - process.currentDirectoryPath = cwd + do { + let path = try locate(executable: executable, env: env) + return path.isEmpty ? nil : path + } catch { + // Most likely an error because we could not locate the executable + return nil } - - // Input/output - let stdin = Pipe() - let stdout = Pipe() - let stderr = Pipe() - process.standardInput = stdin - process.standardOutput = stdout - process.standardError = stderr - - return try stdioProcess(unlaunchedProcess: process, verbose: verbose) - } + } + + let process = Process() + // In MacOS, zsh is the default since macOS Catalina 10.15.7. We can safely assume it is available. + process.launchPath = "/bin/zsh" + + if let executable = path(for: executable, env: env) { + // If executable is found directly, use user-provided env or current process env + process.environment = env ?? ProcessInfo.processInfo.environment + let command = "\(executable) \(args.joined(separator: " "))" + process.arguments = ["-c"] + [command] + } else { + // If we cannot locate the executable, try loading the default environment for zsh + process.environment = try loadZshEnvironment(userEnv: env) + let command = "\(executable) \(args.joined(separator: " "))" + process.arguments = ["-c"] + [command] + } + + // Working directory + if let cwd { + process.currentDirectoryPath = cwd + } + + // Input/output + let stdin = Pipe() + let stdout = Pipe() + let stderr = Pipe() + process.standardInput = stdin + process.standardOutput = stdout + process.standardError = stderr + + return try stdioProcess(unlaunchedProcess: process, verbose: verbose) + } /// Creates a new `Transport` by launching the given process and attaching to its standard IO. public static func stdioProcess( @@ -210,54 +210,54 @@ extension Transport { } return executablePath } - - private static func loadZshEnvironment(userEnv: [String: String]? = nil) throws -> [String: String] { - // Load shell environment as base - let shellProcess = Process() - shellProcess.executableURL = URL(fileURLWithPath: "/bin/zsh") - - // When userEnv exists, we need to explicitly export these variables in the shell - // before running printenv so they're included in the environment output - if let userEnv = userEnv, !userEnv.isEmpty { - var exportCommands = userEnv.map { key, value in - return "export \(key)=\(value.replacingOccurrences(of: "\"", with: "\\\""))" - }.joined(separator: "; ") - - exportCommands += "; printenv" - shellProcess.arguments = ["-ilc", exportCommands] - } else { - shellProcess.arguments = ["-ilc", "printenv"] - } - - let outputPipe = Pipe() - shellProcess.standardOutput = outputPipe - shellProcess.standardError = Pipe() - - try shellProcess.run() - shellProcess.waitUntilExit() - - let data = outputPipe.fileHandleForReading.readDataToEndOfFile() - guard let outputString = String(data: data, encoding: .utf8) else { - logger.error("Failed to read environment from shell.") - return ProcessInfo.processInfo.environment - } - - // Parse shell environment - var mergedEnv: [String: String] = [:] - outputString.split(separator: "\n").forEach { line in - let components = line.split(separator: "=", maxSplits: 1) - guard components.count == 2 else { return } - let key = String(components[0]) - let value = String(components[1]) - mergedEnv[key] = value - } - - // Debug logging to verify environment was properly merged - logger.debug("Shell environment loaded with user variables successfully merged") - - return mergedEnv - } - + + private static func loadZshEnvironment(userEnv: [String: String]? = nil) throws -> [String: String] { + // Load shell environment as base + let shellProcess = Process() + shellProcess.executableURL = URL(fileURLWithPath: "/bin/zsh") + + // When userEnv exists, we need to explicitly export these variables in the shell + // before running printenv so they're included in the environment output + if let userEnv = userEnv, !userEnv.isEmpty { + var exportCommands = userEnv.map { key, value in + "export \(key)=\(value.replacingOccurrences(of: "\"", with: "\\\""))" + }.joined(separator: "; ") + + exportCommands += "; printenv" + shellProcess.arguments = ["-ilc", exportCommands] + } else { + shellProcess.arguments = ["-ilc", "printenv"] + } + + let outputPipe = Pipe() + shellProcess.standardOutput = outputPipe + shellProcess.standardError = Pipe() + + try shellProcess.run() + shellProcess.waitUntilExit() + + let data = outputPipe.fileHandleForReading.readDataToEndOfFile() + guard let outputString = String(data: data, encoding: .utf8) else { + logger.error("Failed to read environment from shell.") + return ProcessInfo.processInfo.environment + } + + // Parse shell environment + var mergedEnv: [String: String] = [:] + outputString.split(separator: "\n").forEach { line in + let components = line.split(separator: "=", maxSplits: 1) + guard components.count == 2 else { return } + let key = String(components[0]) + let value = String(components[1]) + mergedEnv[key] = value + } + + // Debug logging to verify environment was properly merged + logger.debug("Shell environment loaded with user variables successfully merged") + + return mergedEnv + } + private static func getProcessStdout(process: Process) throws -> String? { let stdout = Pipe() let stderr = Pipe() From eca280d5722201c891d19106c8cb47f36946bdaa Mon Sep 17 00:00:00 2001 From: James Rochabrun Date: Mon, 10 Mar 2025 10:34:39 -0700 Subject: [PATCH 5/8] Update MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift Co-authored-by: Guillaume Sabran --- .../DataChannel+StdioProcess.swift | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index cf764f1..945a546 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -242,20 +242,17 @@ extension Transport { return ProcessInfo.processInfo.environment } - // Parse shell environment - var mergedEnv: [String: String] = [:] - outputString.split(separator: "\n").forEach { line in - let components = line.split(separator: "=", maxSplits: 1) - guard components.count == 2 else { return } - let key = String(components[0]) - let value = String(components[1]) - mergedEnv[key] = value - } - // Debug logging to verify environment was properly merged logger.debug("Shell environment loaded with user variables successfully merged") - return mergedEnv + return outputString + .split(separator: "\n") + .reduce(into: [String: String]()) { result, line in + // Parse the env variable key / value + let components = line.split(separator: "=", maxSplits: 1) + guard components.count == 2 else { return } + result[String(components[0])] = String(components[1]) + } } private static func getProcessStdout(process: Process) throws -> String? { From 8f03d26d760877f4d9707cb930a435c962927e69 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Mon, 10 Mar 2025 10:45:49 -0700 Subject: [PATCH 6/8] Swift format --- .../stdioTransport/DataChannel+StdioProcess.swift | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index 945a546..79c29df 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -44,8 +44,6 @@ extension JSONRPCSetupError: LocalizedError { extension Transport { - // MARK: Public - /// Creates a new `Transport` by launching the given executable with the specified arguments and attaching to its standard IO. public static func stdioProcess( _ executable: String, @@ -218,7 +216,7 @@ extension Transport { // When userEnv exists, we need to explicitly export these variables in the shell // before running printenv so they're included in the environment output - if let userEnv = userEnv, !userEnv.isEmpty { + if let userEnv, !userEnv.isEmpty { var exportCommands = userEnv.map { key, value in "export \(key)=\(value.replacingOccurrences(of: "\"", with: "\\\""))" }.joined(separator: "; ") @@ -248,10 +246,10 @@ extension Transport { return outputString .split(separator: "\n") .reduce(into: [String: String]()) { result, line in - // Parse the env variable key / value - let components = line.split(separator: "=", maxSplits: 1) - guard components.count == 2 else { return } - result[String(components[0])] = String(components[1]) + // Parse the env variable key / value + let components = line.split(separator: "=", maxSplits: 1) + guard components.count == 2 else { return } + result[String(components[0])] = String(components[1]) } } From f902585c66b43e8ab92f6d9e9d5a8c17b1c0f092 Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Tue, 11 Mar 2025 21:47:37 -0700 Subject: [PATCH 7/8] PR review --- .../DataChannel+StdioProcess.swift | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift index 79c29df..8ed97fd 100644 --- a/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift +++ b/MCPClient/Sources/stdioTransport/DataChannel+StdioProcess.swift @@ -214,19 +214,15 @@ extension Transport { let shellProcess = Process() shellProcess.executableURL = URL(fileURLWithPath: "/bin/zsh") - // When userEnv exists, we need to explicitly export these variables in the shell - // before running printenv so they're included in the environment output - if let userEnv, !userEnv.isEmpty { - var exportCommands = userEnv.map { key, value in - "export \(key)=\(value.replacingOccurrences(of: "\"", with: "\\\""))" - }.joined(separator: "; ") - - exportCommands += "; printenv" - shellProcess.arguments = ["-ilc", exportCommands] + // Set process environment - either use userEnv if it exists and isn't empty, or use system environment + if let env = userEnv, !env.isEmpty { + shellProcess.environment = env } else { - shellProcess.arguments = ["-ilc", "printenv"] + shellProcess.environment = ProcessInfo.processInfo.environment } + shellProcess.arguments = ["-ilc", "printenv"] + let outputPipe = Pipe() shellProcess.standardOutput = outputPipe shellProcess.standardError = Pipe() @@ -240,13 +236,10 @@ extension Transport { return ProcessInfo.processInfo.environment } - // Debug logging to verify environment was properly merged - logger.debug("Shell environment loaded with user variables successfully merged") - + // Parse shell environment return outputString .split(separator: "\n") .reduce(into: [String: String]()) { result, line in - // Parse the env variable key / value let components = line.split(separator: "=", maxSplits: 1) guard components.count == 2 else { return } result[String(components[0])] = String(components[1]) From 077d21a892aada311937eda10dd0c606a2d7a19a Mon Sep 17 00:00:00 2001 From: jamesrochabrun Date: Tue, 11 Mar 2025 21:55:50 -0700 Subject: [PATCH 8/8] package resolutions on demo --- .../MCPClientChat.xcodeproj/project.pbxproj | 19 +++++++++---------- .../xcshareddata/swiftpm/Package.resolved | 7 ++++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.pbxproj b/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.pbxproj index 99d7087..9af0426 100644 --- a/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.pbxproj +++ b/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.pbxproj @@ -7,8 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 7B73E9F52D814ABE00BF0CD1 /* MCPClient in Frameworks */ = {isa = PBXBuildFile; productRef = 7B73E9F42D814ABE00BF0CD1 /* MCPClient */; }; 7BDD62DB2D764B3D00E18088 /* SwiftAnthropic in Frameworks */ = {isa = PBXBuildFile; productRef = 7BDD62DA2D764B3D00E18088 /* SwiftAnthropic */; }; - 7BDD62ED2D764B7C00E18088 /* MCPClient in Frameworks */ = {isa = PBXBuildFile; productRef = 7BDD62EC2D764B7C00E18088 /* MCPClient */; }; 7BDD644F2D7811BA00E18088 /* SwiftOpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = 7BDD644E2D7811BA00E18088 /* SwiftOpenAI */; }; /* End PBXBuildFile section */ @@ -58,9 +58,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BDD62ED2D764B7C00E18088 /* MCPClient in Frameworks */, 7BDD644F2D7811BA00E18088 /* SwiftOpenAI in Frameworks */, 7BDD62DB2D764B3D00E18088 /* SwiftAnthropic in Frameworks */, + 7B73E9F52D814ABE00BF0CD1 /* MCPClient in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -130,8 +130,8 @@ name = MCPClientChat; packageProductDependencies = ( 7BDD62DA2D764B3D00E18088 /* SwiftAnthropic */, - 7BDD62EC2D764B7C00E18088 /* MCPClient */, 7BDD644E2D7811BA00E18088 /* SwiftOpenAI */, + 7B73E9F42D814ABE00BF0CD1 /* MCPClient */, ); productName = MCPClientChat; productReference = 7BDD62A92D764A4A00E18088 /* MCPClientChat.app */; @@ -217,8 +217,8 @@ minimizedProjectReferenceProxies = 1; packageReferences = ( 7BDD62D72D764ADA00E18088 /* XCRemoteSwiftPackageReference "SwiftAnthropic" */, - 7BDD62D82D764B1800E18088 /* XCLocalSwiftPackageReference "../../../mcp-swift-sdk" */, 7BDD644D2D7811B300E18088 /* XCRemoteSwiftPackageReference "SwiftOpenAI" */, + 7B73E9F32D814ABE00BF0CD1 /* XCLocalSwiftPackageReference "../../../mcp-swift-sdk" */, ); preferredProjectObjectVersion = 77; productRefGroup = 7BDD62AA2D764A4A00E18088 /* Products */; @@ -576,7 +576,7 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - 7BDD62D82D764B1800E18088 /* XCLocalSwiftPackageReference "../../../mcp-swift-sdk" */ = { + 7B73E9F32D814ABE00BF0CD1 /* XCLocalSwiftPackageReference "../../../mcp-swift-sdk" */ = { isa = XCLocalSwiftPackageReference; relativePath = "../../../mcp-swift-sdk"; }; @@ -602,16 +602,15 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 7B73E9F42D814ABE00BF0CD1 /* MCPClient */ = { + isa = XCSwiftPackageProductDependency; + productName = MCPClient; + }; 7BDD62DA2D764B3D00E18088 /* SwiftAnthropic */ = { isa = XCSwiftPackageProductDependency; package = 7BDD62D72D764ADA00E18088 /* XCRemoteSwiftPackageReference "SwiftAnthropic" */; productName = SwiftAnthropic; }; - 7BDD62EC2D764B7C00E18088 /* MCPClient */ = { - isa = XCSwiftPackageProductDependency; - package = 7BDD62D82D764B1800E18088 /* XCLocalSwiftPackageReference "../../../mcp-swift-sdk" */; - productName = MCPClient; - }; 7BDD644E2D7811BA00E18088 /* SwiftOpenAI */ = { isa = XCSwiftPackageProductDependency; package = 7BDD644D2D7811B300E18088 /* XCRemoteSwiftPackageReference "SwiftOpenAI" */; diff --git a/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ffdaaf7..bd90525 100644 --- a/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/MCPClientChatDemo/MCPClientChat/MCPClientChat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,12 +1,13 @@ { - "originHash" : "ea89bc09a647584f246cc2ccc1334b5e579f0d3a53f72aa83011d8c436a3060f", + "originHash" : "cce6852fb88fdb9dea165eaa0f67690c423dc6b8f55b0b5fc6ee4cb95709df9b", "pins" : [ { "identity" : "jsonrpc", "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/JSONRPC", + "location" : "https://github.com/gsabran/JSONRPC", "state" : { - "revision" : "ef61a695bafa0e07080dadac65a0c59b37880548" + "revision" : "56c936de4e4385287dc18f260557dbdf443a55bd", + "version" : "0.9.1" } }, {