airbattery-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@airbattery-mcpWhat's the battery level on my AirPods and iPhone right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
airbattery-mcp
Let AI agents query the battery levels of your AirPods, iPhone, mouse, headphones and speakers.
A small MCP server on top of AirBattery. AirBattery discovers devices on your Mac; this server exposes their latest readings through a single read-only MCP tool over stdio. Compatible clients, including Codex and Claude, can launch the same server. No client-specific API is used. The server requires no Bluetooth permission of its own and runs as a process managed by the MCP client.
Ask your AI agent: "Which of my devices should I charge before tomorrow's flight?"
Download
Download the .mcpb installation bundle from the Assets section of the
latest release.
The initial release is v0.1.0.
Claude Desktop: Download and install the
.mcpbbundle, then ask Claude to check your device battery levels. You do not need to clone this repository for bundle installation.Codex and other MCP clients: Follow the Setup instructions to launch the server over stdio.
AirBattery must be installed and running on the same Mac. If you already configured this server manually, disable that configuration before using the bundle to avoid duplicate tools.
Related MCP server: btdiag
Requirements
macOS with AirBattery installed and running
An MCP client that supports local stdio servers, running on the same Mac
The server finds AirBattery's command line tool in this order:
$AIRBATTERY_CLI, /usr/local/bin/airbattery (AirBattery Settings → Command Line Tool),
/Applications/AirBattery.app/Contents/Resources/abt,
~/Applications/AirBattery.app/Contents/Resources/abt, then airbattery on PATH.
Setup
Clone this repository, then replace /absolute/path/to/AirBattery-mcp below with the absolute path to the repository root.
Use the output of command -v uv wherever /absolute/path/to/uv appears.
The first launch may download Python and dependencies through uv.
Codex
Register the local server:
codex mcp add airbattery -- /absolute/path/to/uv run --directory /absolute/path/to/AirBattery-mcp airbattery-mcpRestart your Codex client to load the configuration. codex mcp list lists configured servers;
use /mcp in the Codex CLI to inspect active connections.
See the official Codex MCP documentation for client configuration details.
Claude Desktop
Add the server to ~/Library/Application Support/Claude/claude_desktop_config.json, merging it with any existing servers:
{
"mcpServers": {
"airbattery": {
"command": "/absolute/path/to/uv",
"args": ["run", "--directory", "/absolute/path/to/AirBattery-mcp", "airbattery-mcp"]
}
}
}Restart Claude Desktop afterwards. Alternatively, use the release bundle or build one using the instructions below.
Claude Code
claude mcp add airbattery -- /absolute/path/to/uv run --directory /absolute/path/to/AirBattery-mcp airbattery-mcpOther MCP clients
Add a local stdio MCP server in your client's settings.
First, find the full path to the uv executable:
command -v uvUse that output as the Command value. Enter only the executable path in this field, for example /Users/yourname/.local/bin/uv.
Put the remaining command parts in Arguments, in this order:
[
"run",
"--directory",
"/absolute/path/to/AirBattery-mcp",
"airbattery-mcp"
]Replace /absolute/path/to/AirBattery-mcp with the absolute path to the repository root (the folder containing pyproject.toml).
If the client provides separate argument fields, enter each array element as one argument, without JSON quotes or commas.
For clients with a single full-command field, enter:
"/absolute/path/to/uv" run --directory "/absolute/path/to/AirBattery-mcp" airbattery-mcpReplace both paths with your actual paths. The quotes preserve paths containing spaces.
Optionally set the environment variable AIRBATTERY_CLI to the absolute path of the AirBattery CLI executable if automatic discovery does not find it.
The client launches the server and calls get_battery_status through MCP. An MCPB installation package is not required for this setup.
Install from Git
Once the MCP source is available in the remote repository, you can replace the local launch command with:
uvx --from "git+https://github.com/Terence1219/AirBattery-mcp" airbattery-mcpFor desktop clients, use the absolute path to uvx from command -v uvx.
Local setup is preferable while developing changes that have not been pushed.
Tool
get_battery_status(device?, include_nearcast?)
{
"devices": [
{
"device": "AirPods Pro",
"level_percent": 80,
"status": "discharging",
"minutes_since_update": 0,
"stale": false
}
]
}device: optional case-insensitive device-name substring filterinclude_nearcast: include devices reported by other Macs via AirBattery Nearcast; defaults tofalsestatus:charging,discharging,paused, orunknownstale:truewhen the reported reading is more than 10 minutes old
These are AirBattery's latest reported readings, not a guarantee of a fresh hardware measurement on every request. A stale reading is a last known value and may belong to a disconnected device. Device names and battery readings are returned to the connected MCP client and may be included in its model context.
Development
Run from the repository root:
uv run airbattery-mcpThe process serves MCP over stdio and waits for a client to connect. Running it in a terminal does not print a battery report by itself.
The Python entry point is src/mcp_server.py; the installed airbattery-mcp command calls mcp_server.main().
Build an MCPB bundle
Install the MCPB CLI, then run from the repository root:
mkdir -p dist
mcpb validate manifest.json
mcpb pack . dist/airbattery-mcp-0.1.0.mcpbThe bundle is an installation option for clients that support MCPB, such as Claude Desktop. Codex can launch the source directly using the setup above. Publish bundles as GitHub Release assets; keep their source files in Git.
License
This project is licensed under the MIT License.
AirBattery is a separate project under AGPL-3.0; this server only calls its command line tool.
Available Tools
1 toolget_battery_statusARead-only
Get current battery levels of the user's devices (AirPods, iPhone, mice, headphones, speakers...).
Data comes from the AirBattery app on this Mac. Each entry has:
level_percent: battery level 0-100
status: charging / discharging / paused / unknown
minutes_since_update: how old the reading is
stale: true when older than 10 minutes. A stale device is probably disconnected, so its level is the last known value, not the current one. Say so when answering.
Non-Apple devices only report while connected to this Mac, and some report coarse levels, so treat small differences cautiously.
Args: device: optional case-insensitive name filter, e.g. "airpods" or "mx master". include_nearcast: also include devices reported by other Macs on the LAN via AirBattery Nearcast.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| include_nearcast | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint annotation: it discloses the data source (AirBattery on this Mac), the meaning of each returned field, the 10-minute staleness threshold, that stale levels are last-known rather than current, and that non-Apple/coarse readings should be treated cautiously. This is exactly the interpretative context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then a scannable field list and an Args section. Most sentences earn their place, though the five-line field enumeration in a narrative description is slightly heavier than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by documenting the return shape and the staleness semantics, and it explains both parameters. An agent can call this tool and correctly narrate its results without any missing pieces.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the full load and does so: 'device' is described as an optional case-insensitive name filter with example values ('airpods', 'mx master'), and 'include_nearcast' is explained as pulling in devices reported by other Macs on the LAN. Both parameters gain meaning absent from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Get current battery levels of the user's devices' — and immediately names the concrete device classes (AirPods, iPhone, mice, headphones, speakers) plus the data source (AirBattery app). There is no ambiguity about what the tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No sibling tools exist, so alternative-routing guidance is moot, but the description supplies clear operational context: non-Apple devices only report while connected, coarse levels tolerate small differences, and near-LAN devices require include_nearcast. It stops short of explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.0- First observed
get_battery_status
TDQS
Scored across 1 tool
There is only one tool, so there is no possibility of misselection or overlap. Its purpose (read current battery levels) is stated precisely and its scope is unambiguous.
get_battery_status follows a clean verb_noun convention with no competing names to clash against. Within a single-tool server, naming is maximally consistent.
A single tool is on the thin side even for a narrow domain; a companion tool (e.g. listing known devices or per-device history) would round out the surface. The one tool does earn its place and the count is not excessive.
The read path is well covered: filtering by device, Nearcast inclusion, and rich per-entry metadata with staleness semantics. Minor gaps remain (no device enumeration without a call, no history or alerting), but the stated purpose is fully served.
Maintenance
Related MCP Connectors
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent
Use your Mac, Windows or Linux computer from ChatGPT, Claude or Codex: files, commands, documents.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server that exposes data from native macOS apps (Mail, Notes, Calendar, Reminders, Contacts, Messages, Spotlight) to AI agents over stdio, currently in early development with no domain tools wired yet.8 npm4MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to control Bluetooth audio devices via MCP tools, including battery status, connect/disconnect, find-my, and snoop decoding.MIT
- AlicenseNot gradedqualityCmaintenanceActvt's embedded MCP server for macOS. 25 tools for live CPU, GPU, memory and network metrics, listening ports with a guarded port_kill, and Claude Code and Codex session analytics (cost, tokens, transcript search, error patterns). It ships inside the Actvt macOS app and binds to loopback on the user's machine, so it starts with the app, not as a standalone or containerised process.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to discover and interact with iOS apps through a local MCP gateway, converting remote Streamable HTTP MCP endpoints into stdio tools. Provides dynamic device discovery, tool schema introspection, and deterministic tool calling for app analysis.-