A macOS app that bridges Apple HomeKit with the Model Context Protocol, letting Claude (or other MCP-compatible LLMs) control your smart home devices over natural language.
Built as a Mac Catalyst app using the native HomeKit framework and the official Swift MCP SDK. Runs headless with an optional menu bar status item.
- macOS 15.0+
- Xcode 26+ (includes Swift, Mac Catalyst support, and the iOS SDK)
- Apple Developer account (free or paid) for code signing — HomeKit requires a signed app with entitlements
- HomeKit-configured home — at least one home set up in the Apple Home app on your Mac or iOS device
-
Clone the repository:
git clone https://github.com/grahamaloo/homekit_mcp.git cd homekit_mcp/HomeKitMCP -
Configure your development team:
cp Local.xcconfig.template Local.xcconfig
Open
Local.xcconfigand replaceYOUR_TEAM_ID_HEREwith your Apple Development Team ID. This file is gitignored so your credentials stay local. -
Open in Xcode:
open HomeKitMCP.xcodeproj
The project will pick up your team ID from
Local.xcconfigautomatically. The HomeKit entitlement is already configured. -
Set the destination to My Mac (Mac Catalyst) in the Xcode toolbar
-
Build and run (
Cmd+R) -
Grant HomeKit access when macOS prompts for permission on first launch
The built app will be located at:
~/Library/Developer/Xcode/DerivedData/HomeKitMCP-<hash>/Build/Products/Debug-maccatalyst/HomeKitMCP.app
Tip: To find the exact path, right-click the app in Xcode's Products group and select "Show in Finder", or use
xcodebuild -showBuildSettings | grep BUILT_PRODUCTS_DIR.
Add to ~/.claude/mcp.json:
{
"mcpServers": {
"homekit": {
"command": "/path/to/HomeKitMCP.app/Contents/MacOS/HomeKitMCP",
"args": ["--headless"]
}
}
}Add to your Claude Desktop MCP config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"homekit": {
"command": "/path/to/HomeKitMCP.app/Contents/MacOS/HomeKitMCP",
"args": ["--headless"]
}
}
}Replace /path/to/ with the actual path to your built .app bundle.
The --headless flag runs the server without the menu bar status item, which is recommended when launched by an MCP client.
| Tool | Description |
|---|---|
list_homes |
List all HomeKit homes configured on this Mac |
list_rooms |
List rooms in a home with device counts |
list_devices |
List devices, filtered by home, room, or type |
get_device_state |
Get current state of a device (power, brightness, temperature, etc.) |
control_device |
Control a single device (on/off, brightness, color, lock, thermostat, etc.) |
batch_control_devices |
Control multiple devices in one call |
batch_get_device_state |
Query multiple device states in one call |
control_devices_by_filter |
Apply an action to all devices matching a filter (e.g. all lights in a room) |
list_scenes |
List HomeKit scenes/action sets |
execute_scene |
Trigger a scene by name or ID |
| Type | Read | Control |
|---|---|---|
| Lights | Power, brightness, hue, saturation | on, off, toggle, set_brightness, set_hue, set_saturation, set_color |
| Switches / Outlets | Power | on, off, toggle |
| Fans | Power | on, off, toggle |
| Locks | Lock state | lock, unlock |
| Garage Doors | Door state | open, close |
| Thermostats | Current temp, target temp, mode | set_temperature, set_thermostat_mode (off/heat/cool/auto) |
| Temperature Sensors | Temperature | read-only |
| Humidity Sensors | Humidity | read-only |
| Motion Sensors | Motion detected | read-only |
| Contact Sensors | Contact state | read-only |
| Occupancy Sensors | Occupancy | read-only |
| Windows / Doors / Coverings | Position | read-only |
Devices can be addressed by:
- Name (case-insensitive):
"name": "Living Room Light" - Unique ID (from
list_devices):"id": "ABC123-DEF456"— preferred when multiple devices share a name - Name + qualifiers: add
"home"and/or"room"to disambiguate
Once configured, you can ask Claude (or any MCP-compatible LLM) things like:
- "Turn off all the lights in the bedroom"
- "What's the temperature in the living room?"
- "Set the thermostat to 72 degrees"
- "Lock the front door"
- "Dim the kitchen lights to 30%"
- "Run the Good Night scene"
MCP Client (Claude, etc.)
| (stdin/stdout JSON-RPC 2.0)
v
+---------------------------+
| HomeKitMCP.app |
| (Mac Catalyst) |
| |
| +----------------------+ |
| | MCPServerManager | | <- JSON-RPC over stdio
| | (StdioTransport) | |
| +----------+-----------+ |
| | |
| +----------v-----------+ |
| | HomeKitManager | | <- async/await actor
| | (HMHomeManager) | |
| +----------+-----------+ |
| | |
| +----------v-----------+ |
| | Apple HomeKit | | <- native framework
| | Framework | |
| +----------------------+ |
+---------------------------+
"HomeKit permission denied" or no devices found:
- Open System Settings > Privacy & Security > HomeKit and ensure HomeKitMCP is allowed
- Make sure you have at least one home configured in the Apple Home app
- The Mac must be signed into the same iCloud account as your Home setup
Build fails with signing errors:
- Make sure you've created
Local.xcconfigfrom the template and set your Team ID - Alternatively, select a team manually in Xcode under Signing & Capabilities
- A free Apple Developer account works, but the app must be re-signed every 7 days
- A paid account ($99/year) provides longer-lived signing
MCP client can't connect:
- Verify the path in your MCP config points to the actual built
.appbundle - Make sure you're pointing to
Contents/MacOS/HomeKitMCPinside the.app - Check that the app has been run at least once manually to grant HomeKit permission
MIT