The Problem
macOS users who want to chat with many different AI providers currently must either use web UIs or install separate, often Electron‑based, clients. There is no single, native, lightweight macOS application that unifies ChatGPT, Claude, Gemini, Ollama, OpenRouter, Perplexity, xAI and OpenAI‑compatible APIs while offering iCloud sync, vision, and image‑generation features. The gap forces users to manage separate accounts, API tokens, and UI contexts.
What This Does
macai is a native macOS chat client that bundles support for virtually every major AI provider through a plug‑in style API‑service manager (macai/Utilities/APIServiceManager.swift). The core UI lives in macai/UI/ContentView.swift, which instantiates a ChatViewModel (macai/UI/Chat/ChatViewModel.swift) that drives the conversation flow. Message handling, attachment parsing, and model routing are orchestrated by a set of handler objects under macai/Utilities/APIHandlers/ (e.g., OpenAIHandlerBase.swift, ClaudeHandler.swift, OllamaHandler.swift). Persistence and sync are handled by ChatStore.swift (macai/Store/ChatStore.swift) backed by Core Data (macai/Store/macaiDataModel.xcdatamodeld). The UI components—bubbles, input, persona selector, and bottom container—are in macai/UI/Chat/ and share common theming via macai/UI/Components/ThemeMode.swift. A rich set of asset catalogs under macai/Assets.xcassets provides icons for each provider, and the app’s entitlements (macai/macai.entitlements) enable iCloud container access.
How It Is Wired
- Entry point:
macai/macaiApp.swiftlaunches the SwiftUI scene graph, which resolves tomacai/UI/ContentView.swift. - Chat flow:
ContentViewcreates aChatViewModel, which subscribes toChatService.swiftfor network I/O. When a user sends a message,MessageInputView.swift(macai/UI/Chat/BottomContainer/MessageInputView.swift) forwards the text to the view model, which callsAPIServiceManager.swiftto select the appropriate handler. - Handler dispatch: Each provider has a dedicated handler (e.g.,
ChatGPTHandler.swift,ClaudeHandler.swift). The manager inspects the user‑selected model and forwards the request; responses travel back throughChatService.swiftinto the view model, then intoChatMessagesView.swiftfor display. - Persistence:
ChatStore.swiftreads/writes chat objects, attachments, and migration state (macai/Store/V1ToV3Migration.swift). The Core Data stack is defined in the.xcdatamodeldfiles undermacai/Store/. - iCloud sync: Entitlements grant an iCloud ubiquity container;
CloudSyncManager.swift(macai/Utilities/CloudSyncManager.swift) watchesNSUbiquitousKeyValueStorefor changes and pushes updates across devices. - Blast radius: The largest single file is
macai/Models/ImageAttachment.swift(623 lines). Changes there ripple through attachment preview, storage, and UI rendering. The API‑handler layer (7 handler files) is the only code that touches the network outside the app sandbox.
How To Use It
Setup
- Binary: Download the latest universal binary from the releases page or install via Homebrew:
brew install --cask macai. - From source: Clone the repo: ``
bash git clone https://github.com/moses-y/macai cd macai`Openmacai.xcodeprojin Xcode 15+ and build; the project uses Swift Package Manager for API‑handler dependencies (resolved inmacai.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved`).
Configuration
- API keys are stored in
macai/Configuration/APIServiceTemplates.jsonand referenced byAppConstants.swift. Add your keys to the macOS Keychain or provide them via environment variables; the app reads them at launch. - To use Ollama locally, start the Ollama server (
ollama serve) and select the “Ollama” provider in the UI; no API key is required.
Running it After building or installing, launch macai. The first run prompts you to select an API provider and (if needed) paste a token. The main window (macai/UI/ContentView.swift) opens with an empty chat ready for prompts.
Real‑World Use
A knowledge‑worker can keep a single macOS window open all day, switching between Claude for coding help, Gemini for research, and Ollama for local model experimentation, while chats, preferences, and image‑generation history sync via iCloud to their iPhone or iPad. Image attachments are processed through AttachmentParser.swift and displayed via AttachmentPreviewViews.swift, enabling drag‑and‑drop of PDFs, screenshots, or raw images without leaving the app.
Code Health & Issues
- HIGH – No test suite: the repository has 94 source files and zero test files (
macaiTests/contains only utility stubs). Any change ships with no signal that existing behaviour still holds, so regressions reach production undetected. - MEDIUM – Oversized model file:
macai/Models/ImageAttachment.swiftcontains 623 lines of code, making it hard to reason about and causing wide‑ripple effects when modified. - LOW – CI workflow (
.github/workflows/swift-xcode.yml) declares nopermissionsforGITHUB_TOKEN, meaning the token inherits repository‑wide defaults and could allow injected steps to push commits or mint releases.
These findings stem from static analysis of the source tree; they are not subjective opinions.
The Bottom Line
macai delivers a polished, native macOS experience for interacting with a wide variety of AI services and adds iCloud sync, vision, and image‑generation out of the box. The codebase is functional but suffers from deep nesting, duplicated logic, and a notably large model‑attachment file that harms maintainability. The absence of a test suite and the permissive CI token permissions are the most pressing risks for long‑term stability. It is well‑suited for power users and small teams that need a single‑pane macOS front‑end for multiple LLMs and are comfortable managing API keys manually. Teams requiring rigorous regression testing or strict CI security hardening will need to add tests and tighten workflow permissions.