MCP servers crash on macOS when accessing Bluetooth — missing NSBluetoothAlwaysUsageDescription in claude-code bundle

Resolved 💬 1 comment Opened May 12, 2026 by motivado Closed Jun 12, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Summary
On macOS, any MCP server spawned by Claude Code that touches Bluetooth (CoreBluetooth) is killed by TCC, even when the MCP server's own Info.plist correctly declares NSBluetoothAlwaysUsageDescription. Root cause: macOS attributes the BLE access to the responsible app (Claude Code), and the claude-code bundle does not declare the BLE usage string.

Reproduction
macOS 26.x (also reproduces on 14/15 per design of TCC).
Configure any MCP server that uses CoreBluetooth (in my case, tokymaker-mcp for ESP32 boards over BLE) via .mcp.json stdio command.
Trigger any tool that initiates a BLE scan or connect.
The MCP child process is killed with SIGABRT. Claude sees MCP error -32000: Connection closed.
Diagnostic evidence
Crash report (~/Library/Logs/DiagnosticReports/<server>-*.ips):

termination.details: "This app has crashed because it attempted to access
privacy-sensitive data without a usage description. The app's Info.plist
must contain an NSBluetoothAlwaysUsageDescription key..."
responsibleProc: claude
parentProc: claude
The responsible process is:
~/Library/Application Support/Claude/claude-code/<version>/claude.app
Bundle ID: com.anthropic.claude-code

plutil -p on that bundle's Info.plist shows NSMicrophoneUsageDescription but no NSBluetoothAlwaysUsageDescription. The MCP server's own Info.plist does declare the key — irrelevant, because TCC checks the responsible app.

Impact
Affects every BLE-using MCP server on macOS Claude Code: hardware-control servers (ESP32, Arduino, micro:bit), smart-home (Govee, Bluetooth-only HomeKit accessories), health (heart-rate monitors), etc. There is no user-side fix — re-signing the MCP server doesn't help, and granting Bluetooth permission to other apps doesn't apply.

Workarounds today require either (a) running Claude Code from Terminal so Terminal becomes the responsible app, or (b) wrapping the MCP server in a stdio→HTTP proxy launched from Terminal. Both are inaccessible to non-developer users.

Environment
Claude Code 2.1.128 (embedded in Claude desktop)
macOS 26.3.1, Apple Silicon
MCP server: tokymaker-mcp 0.1.0 (any BLE MCP server would reproduce)

Proposed Solution

Suggested fix
Add to claude.app/Contents/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Claude Code uses Bluetooth on behalf of MCP servers that control Bluetooth devices.</string>
One-line bundle change. Note that /Applications/Claude.app already declares this — only the embedded claude-code bundle is missing it.

Alternative Solutions

_No response_

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

_No response_

Additional Context

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗