Docs

earctl

Earctl is a Rust HTTP API and CLI for controlling Nothing and CMF earbuds through the BlueZ Serial Port Profile. Run it on any Linux box to expose ANC, EQ, latency, and gesture controls to scripts or other devices on your network.

Key Features

  • HTTP API and CLI for Nothing/CMF earbuds via BlueZ RFCOMM.
  • Auto-detects connected devices, RFCOMM channel, and model metadata (SKU/serial overrides supported).
  • Controls ANC, EQ (including custom EQ), latency, gestures, enhanced bass, case LEDs, and Find My Buds.

Quick Stats

  • Default API bind: 127.0.0.1:8787 (Axum HTTP server).
  • Targets Nothing Ear (1), Ear (stick), Ear (2), Ear, Ear (a), Ear (open) and CMF Buds, Buds Pro, Buds Pro 2, Neckband Pro.
  • Rust 2024 edition on Tokio; depends on BlueZ utilities (bluetoothctl and sdptool).

Install

Earctl targets Linux with BlueZ. Pair your earbuds first and ensure bluez, bluez-utils (bluetoothctl), and bluez-deprecated-tools (sdptool) are installed. You need Rust (1.75+ recommended) to build.

git clone https://github.com/DaanHessen/earctl.git
cd earctl
cargo build --release
./target/release/earctl server --addr 0.0.0.0:8787

Install the binary locally from the repo:

cargo install --path .

The Arch package ships a user service. After installing the package, enable it:

systemctl --user enable --now earctl.service

Usage

Start the API server, connect to your buds, then query or set states from the CLI or HTTP.

earctl server --addr 0.0.0.0:8787
earctl auto-connect --name "Nothing Ear"
earctl battery
earctl anc set transparency
earctl custom-eq set --bass 2 --mid 0 --treble -1
earctl ring --enable true --side left

HTTP example:

curl -X POST http://127.0.0.1:8787/api/session/auto-connect \
  -H "Content-Type: application/json" \
  -d '{ "name": "Nothing Ear" }'
Note: Keep the earbuds connected in your OS Bluetooth menu. auto-connect reuses the active connection and falls back to channel 1 if SDP discovery fails. You can optionally specify "channel": <number> to override the detected channel.

Configuration

Configure earctl through CLI flags. There is no separate config file.

Global Options

OptionDefaultDescription
--endpointhttp://127.0.0.1:8787Base URL used by client commands to reach the API.

Server Options

OptionDefaultDescription
--addr127.0.0.1:8787Listen address for earctl server.

Command Options

auto-connect

OptionDescription
--bluetooth-addressExplicit MAC address; skips discovery.
--nameFilter connected devices by a substring of their name.
--channelRFCOMM channel fallback when SDP detection fails (default: 1).
--skuOverride detected model metadata (SKU).

connect

OptionDescription
--addressRequired. Bluetooth device address.
--channelRFCOMM channel (default: 1).
--model-idOverride model ID.
--skuOverride SKU.
--baseOverride model base type.

API Reference

Session

/api/session*

  • POST /api/session/auto-connect: Detect the connected buds, discover RFCOMM, and open a session.
  • POST /api/session/connect: Connect with an explicit MAC and channel.
  • POST /api/session/detect / POST /api/session/model: Read or override SKU/model metadata.
  • GET /api/session / DELETE /api/session: Show or close the active session.
Controls

/api/anc / /api/eq

  • /api/anc, /api/eq, /api/eq/custom: Read or set ANC and EQ (including custom bands).
  • /api/enhanced-bass: Read or set enhanced bass state (enabled + level).
  • /api/personalized-anc, /api/in-ear, /api/latency: Toggle feature switches per model support.
  • /api/gestures: Read or update gesture mappings.
  • /api/led-case: Read or set case LED pixels (Ear (1) only).
Status

/api/battery & tools

  • /api/battery, /api/firmware: Battery readings and firmware string.
  • /api/ear-fit: Start an ear-fit test (POST) and read the result (GET).
  • /api/ring: Trigger the Find My Buds tone (loud).
  • /api/session: Returns session ID, port path, and detected model summary.

Contributing

Issues and pull requests are welcome. Please check existing issues, keep changes scoped, and run cargo fmt and cargo test before submitting.

  • Fork the repository.
  • Create a feature branch.
  • Submit a pull request.

License

earctl is licensed under the GNU Affero General Public License v3.0. See LICENSE for details.