A Swift Package library for integrating Claude Code UI into your macOS apps.
ClaudeCodeUI is a dependency-only library that provides a beautiful, native macOS graphical interface for Claude Code conversations. It is designed to be integrated directly into your own macOS applications as a Swift Package — it is not distributed as a standalone app.
- 🎨 Native macOS Design - Beautiful SwiftUI interface that feels right at home on macOS
- 💬 Full Chat Interface - Complete conversation management with message history
- 📎 File Attachments - Support for images, PDFs, and other file types
- 🎯 Code Selections - Display and manage code snippets within conversations
- 🗂️ Session Management - Built-in session picker and persistence
- 🎨 Theming - Automatic dark/light mode support
- ⚡ Real-time Streaming - Live response streaming with token usage tracking
- 🛠️ Tool Integration - Full support for Claude's tool use capabilities
- 🔧 MCP Support - Model Context Protocol server integration
Integrate ClaudeCodeUI into your macOS app:
Add ClaudeCodeUI to your project through Xcode:
- File → Add Package Dependencies
- Enter:
https://github.com/jamesrochabrun/ClaudeCodeUI - Select "Up to Next Major Version" with
1.0.0
Or add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/jamesrochabrun/ClaudeCodeUI", from: "1.0.0")
]When using ClaudeCodeUI as a package dependency, you need to build and provide the ApprovalMCPServer separately for security reasons:
-
Add the ApprovalMCPServer dependency:
dependencies: [ .package(url: "https://github.com/jamesrochabrun/ClaudeCodeUI", from: "1.0.0"), .package(url: "https://github.com/jamesrochabrun/ClaudeCodeApprovalServer", .exact("1.0.0")) // Pin version for security ]
-
Build the server in your build phase (see Package Integration Guide for details)
This build-from-source approach ensures maximum security by allowing you to audit and compile the approval server yourself.
- macOS 14.0+
- Claude CLI installed (
npm install -g @anthropic/claude-code)
For development:
- Xcode 15.0+
- Swift 5.9+
The entire Claude interface in just a few lines:
import SwiftUI
import ClaudeCodeCore
import ClaudeCodeSDK
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ClaudeCodeContainer(
claudeCodeConfiguration: ClaudeCodeConfiguration.default,
uiConfiguration: UIConfiguration(
appName: "My Claude App",
showSettingsInNavBar: true
)
)
}
}
}That's it! ClaudeCodeContainer handles everything else automatically.
Configure how Claude Code operates:
var config = ClaudeCodeConfiguration.default
// Enable debug logging
config.enableDebugLogging = true
// Set working directory (defaults to user's home)
config.workingDirectory = "/path/to/project"
// Configure Claude command (if not using default)
config.command = "claude"
// Add custom PATH locations for finding the Claude CLI
config.additionalPaths = [
"/usr/local/bin",
"/opt/homebrew/bin",
NSHomeDirectory() + "/.nvm/current/bin"
]
// Pass to container
ClaudeCodeContainer(
claudeCodeConfiguration: config,
uiConfiguration: uiConfig
)Customize the interface appearance and behavior:
let uiConfig = UIConfiguration(
// App name shown in the interface
appName: "My Assistant",
// Show settings button in navigation bar
showSettingsInNavBar: true,
// Show risk/safety data in UI (optional)
showRiskData: false,
// Custom tooltip for working directory selector
workingDirectoryToolTip: "Select your project folder",
// Add custom system prompt
initialAdditionalSystemPromptPrefix: """
You are an expert Swift developer assistant.
Focus on SwiftUI best practices and modern Swift conventions.
"""
)Track when users send messages for analytics or logging:
ClaudeCodeContainer(
claudeCodeConfiguration: config,
uiConfiguration: uiConfig,
onUserMessageSent: { message, codeSelections, attachments in
// Log the message
print("User sent: \(message)")
// Track code selections if any
if let selections = codeSelections {
print("With \(selections.count) code selections")
}
// Track attachments if any
if let files = attachments {
print("With \(files.count) attachments")
}
}
)ClaudeCodeUI automatically supports MCP (Model Context Protocol) servers. Users can configure MCP servers through the Settings interface.
The MCP configuration is stored at ~/.claude/mcp_settings.json:
{
"servers": {
"filesystem": {
"command": "npx",
"args": ["@anthropic/mcp-server-filesystem", "/Users/me/projects"]
},
"github": {
"command": "npx",
"args": ["@anthropic/mcp-server-github"],
"env": {
"GITHUB_TOKEN": "your-token"
}
}
}
}Here's a fully configured implementation:
import SwiftUI
import ClaudeCodeCore
import ClaudeCodeSDK
@main
struct ClaudeCodeUIApp: App {
var config: ClaudeCodeConfiguration {
var config = ClaudeCodeConfiguration.default
config.enableDebugLogging = true
// Add common Node.js installation paths
let homeDir = NSHomeDirectory()
config.additionalPaths = [
"/usr/local/bin",
"/opt/homebrew/bin",
"\(homeDir)/.nvm/current/bin",
"\(homeDir)/.nvm/versions/node/v22.16.0/bin"
]
return config
}
var uiConfig: UIConfiguration {
UIConfiguration(
appName: "Claude Code Assistant",
showSettingsInNavBar: true,
showRiskData: false,
workingDirectoryToolTip: "Select your project folder",
initialAdditionalSystemPromptPrefix: """
You are a helpful coding assistant with expertise in Swift and SwiftUI.
Always provide clear explanations with your code suggestions.
"""
)
}
var body: some Scene {
WindowGroup {
ClaudeCodeContainer(
claudeCodeConfiguration: config,
uiConfiguration: uiConfig,
onUserMessageSent: { message, selections, attachments in
// Optional: Handle message events
logUserInteraction(message, selections, attachments)
}
)
}
}
func logUserInteraction(_ message: String, _ selections: [TextSelection]?, _ attachments: [FileAttachment]?) {
// Your analytics/logging code here
print("User interaction logged: \(message)")
}
}⌘N- New conversation⌘,- Open settings⌘K- Clear conversation⌘Enter- Send messageEscape- Cancel current operation
Add these entitlements to your app's .entitlements file:
<!-- App Sandbox -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- Network access for Claude API -->
<key>com.apple.security.network.client</key>
<true/>
<!-- File system access for attachments -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<!-- For working directory access -->
<key>com.apple.security.files.downloads.read-write</key>
<true/>If you see "Claude command not found":
-
Install the Claude CLI:
npm install -g @anthropic/claude-code
-
Verify installation:
which claude
-
Add the path to your configuration:
config.additionalPaths = [ "/path/returned/by/which/command" ]
ClaudeCodeContainer automatically manages sessions internally. Sessions are stored in a SQLite database and include:
- Conversation history
- Working directory per session
- Timestamps and metadata
If MCP servers aren't working:
- Check the MCP configuration in Settings
- Verify server commands are installed:
npm list -g | grep mcp-server - Check
~/.claude/mcp_settings.jsonfor syntax errors - Enable debug logging to see detailed errors
To contribute to or modify the package:
# Clone the repository
git clone https://github.com/jamesrochabrun/ClaudeCodeUI.git
cd ClaudeCodeUI
# Open Package.swift in Xcode
open Package.swift
For issues, questions, or contributions, please visit the GitHub repository.
MIT
Built on top of ClaudeCodeSDK and the Claude CLI by Anthropic.
Thanks to cmd for early testing, feedback, and bug reports that helped make ClaudeCodeUI better!