A command-line tool for controlling the built-in Thread radio on Apple Silicon Macs via the private CoreThreadRadio.framework.
This framework talks to threadradiod over XPC, which appears to be a modified version of wpantund from OpenThread.
This radio appears to be included in M3 and later chips, though I cannot find exact documentation. The codename for the Thread radio appears to be "Fillmore".
This is a really rough implementation, but I did some basic testing on macOS Sequoia 15.6 on an M4 Pro MacBook Pro. The API is really cursed, not all the functions are properly implemented so I tried to work-around that. It's possible this has been improved in macOS 26.
The binary requires several private entitlements. Without them the XPC daemon will reject the connection. The included entitlements.xml covers the commands implemented here:
| Entitlement | Required for |
|---|---|
com.apple.private.ctr.thread |
All commands |
com.apple.private.fillmore.masterkey.get |
info, aod, start (reading Network:Key) |
com.apple.private.fillmore.threadLeave |
stop |
com.apple.private.fillmore.threadStart |
start |
Since we can't get these entitlements from Apple, we self sign the binary. This requires SIP and AMFI to be disabled. A script like amfid-allow.py can be used to patch AMFI (when SIP is disabled) rather than disabling AMFI entirely (which tends to break things).
Most of these are included in the info command output, but they can be manually queried with get:
| Property | Description |
|---|---|
NCP:State |
offline, associating, associated, etc. |
Config:TUN:InterfaceName |
TUN interface name (e.g. utun7) |
Network:Name |
Thread network name |
NCP:Channel |
Active 802.15.4 channel (11–26) |
NCP:ChannelMask |
Supported channel bitmask |
Network:PANID |
16-bit PAN ID |
Network:XPANID |
64-bit Extended PAN ID |
Network:Key |
128-bit Thread master key |
Network:PSKC |
Pre-Shared Key for Commissioner |
Network:NodeType |
router, end-device, unknown, etc. |
IPv6:MeshLocalPrefix |
Mesh-local /64 prefix |
com.apple.ThreadCommissionerService is a separate daemon which is responsible for storing and managing Thread credentials. This provides the com.apple.ThreadNetwork.xpc XPC service which powers the public ThreadNetwork.framework. Since this has no interaction with the actual Thread radio, it is not useful for our purposes.
com.apple.wpantund.xpc is the raw XPC service wrapped by CoreThreadRadio.framework. It might be easier to use this directly at some point, but I haven't explored it extensively.
threadradiod stores some state as preferences:
sudo plutil -convert xml1 -o - /private/var/root/Library/Preferences/com.apple.threadradiodData.plist
homed and /usr/libexec/srp-mdns-proxy (whatever that is) appear to be the only programs with the entitlements to talk to the Thread radio. If you have a Matter device added to HomeKit, you can see threadradiod activity when you open the Home app.