Files
Termind/TFM/Features/Settings/MCPClientSetupCommand.swift

57 lines
2.1 KiB
Swift

// SPDX-FileCopyrightText: 2026 Kaede Akino
// SPDX-License-Identifier: GPL-3.0-only
import Foundation
/// Presentation-only commands for registering the local server with external clients.
struct MCPClientSetupCommand {
enum Client: String, CaseIterable, Identifiable {
case codex = "Codex"
case claudeCode = "Claude Code"
case copilot = "GitHub Copilot CLI"
case openClaw = "OpenClaw"
case hermes = "Hermes Agent"
var id: Self { self }
var requiresBridge: Bool { self == .codex || self == .hermes }
}
let port: Int
let token: String
let bridgePath: String?
func command(for client: Client) -> String? {
guard !token.isEmpty else { return nil }
if client.requiresBridge, bridgePath?.isEmpty != false { return nil }
let url = "http://localhost:\(port)/mcp"
let quotedURL = Self.quote(url)
let header = Self.quote("Authorization: Bearer \(token)")
let urlEnvironment = Self.quote("TERMIND_MCP_URL=\(url)")
let tokenEnvironment = Self.quote("TERMIND_MCP_TOKEN=\(token)")
switch client {
case .codex:
guard let bridgePath else { return nil }
return
"codex mcp add termind --env \(urlEnvironment) --env \(tokenEnvironment) -- \(Self.quote(bridgePath))"
case .claudeCode:
return "claude mcp add --scope user --transport http --header \(header) termind \(quotedURL)"
case .copilot:
return "copilot mcp add --transport http --header \(header) termind \(quotedURL)"
case .openClaw:
let header = Self.quote("Authorization=Bearer \(token)")
return "openclaw mcp add termind --url \(quotedURL) --transport streamable-http --header \(header)"
case .hermes:
guard let bridgePath else { return nil }
return
"hermes mcp add termind --command \(Self.quote(bridgePath)) --env \(urlEnvironment) \(tokenEnvironment)"
}
}
private static func quote(_ value: String) -> String {
"'" + value.replacingOccurrences(of: "'", with: "'\"'\"'") + "'"
}
}