Skip to main content
Glama
MCPClientService.swift4.16 kB
// // MCPClientService.swift // PeekabooCLI // import MCP import PeekabooCore import TachikomaMCP struct MCPServerInfo { let name: String let config: TachikomaMCP.MCPServerConfig let connected: Bool } protocol MCPClientService: AnyObject { func bootstrap(connect: Bool) async func serverNames() -> [String] func serverInfo(name: String) async -> MCPServerInfo? func probeAll(timeoutMs: Int) async -> [String: MCPServerHealth] func probe(name: String, timeoutMs: Int) async -> MCPServerHealth func execute(server: String, tool: String, args: [String: Any]) async throws -> ToolResponse func addServer(name: String, config: TachikomaMCP.MCPServerConfig) async throws func removeServer(name: String) async func enableServer(name: String) async throws func disableServer(name: String) async func persist() throws func checkServerHealth(name: String, timeoutMs: Int) async -> MCPServerHealth func externalToolsByServer() async -> [String: [MCP.Tool]] } /// Main implementation backed by TachikomaMCPClientManager. @MainActor final class DefaultMCPClientService: MCPClientService { static let shared = DefaultMCPClientService(manager: TachikomaMCPClientManager.shared) private let manager: TachikomaMCPClientManager private var defaultsRegistered = false init(manager: TachikomaMCPClientManager) { self.manager = manager } func bootstrap(connect: Bool) async { self.registerDefaultsIfNeeded() await self.manager.initializeFromProfile(connect: connect) } func serverNames() -> [String] { self.manager.getServerNames() } func serverInfo(name: String) async -> MCPServerInfo? { guard let info = await self.manager.getServerInfo(name: name) else { return nil } return MCPServerInfo(name: name, config: info.config, connected: info.connected) } func probeAll(timeoutMs: Int) async -> [String: MCPServerHealth] { let probes = await self.manager.probeAllServers(timeoutMs: timeoutMs) var healthResults: [String: MCPServerHealth] = [:] for (name, probe) in probes { healthResults[name] = probe.isConnected ? .connected( toolCount: probe.toolCount, responseTime: probe.responseTime ) : .disconnected(error: probe.error ?? "unknown error") } return healthResults } func probe(name: String, timeoutMs: Int) async -> MCPServerHealth { let probe = await self.manager.probeServer(name: name, timeoutMs: timeoutMs) return probe.isConnected ? .connected(toolCount: probe.toolCount, responseTime: probe.responseTime) : .disconnected(error: probe.error ?? "unknown error") } func execute(server: String, tool: String, args: [String: Any]) async throws -> ToolResponse { try await self.manager.executeTool(serverName: server, toolName: tool, arguments: args) } func addServer(name: String, config: TachikomaMCP.MCPServerConfig) async throws { try await self.manager.addServer(name: name, config: config) } func removeServer(name: String) async { await self.manager.removeServer(name: name) } func enableServer(name: String) async throws { try await self.manager.enableServer(name: name) } func disableServer(name: String) async { await self.manager.disableServer(name: name) } func persist() throws { try self.manager.persist() } func checkServerHealth(name: String, timeoutMs: Int = 5000) async -> MCPServerHealth { await self.probe(name: name, timeoutMs: timeoutMs) } func externalToolsByServer() async -> [String: [MCP.Tool]] { await self.manager.getExternalToolsByServer() } private func registerDefaultsIfNeeded() { guard !self.defaultsRegistered else { return } let defaultChromeDevTools = ChromeDevToolsServerFactory.tachikomaConfig(timeout: 15.0, autoReconnect: true) self.manager.registerDefaultServers([MCPDefaults.serverName: defaultChromeDevTools]) self.defaultsRegistered = true } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steipete/Peekaboo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server