MCP server for controlling Apple TV, HomePod, and AirPlay devices via pyatv.
mcp-pyatv is an MCP (Model Context Protocol) server that bridges any MCP client to Apple TV, HomePod, and AirPlay devices on your local network. It wraps pyatv -- the open-source Python library that implements the actual Apple TV and AirPlay protocols -- and exposes its functionality as MCP tools.
This lets you control your devices using natural language through Claude Desktop, Claude Code, Cursor, or any other MCP-compatible client.
This project does not implement any device protocols. All protocol-level communication is handled by pyatv. mcp-pyatv is purely the MCP bridge layer.
- Apple TV -- all generations, including tvOS 15+
- HomePod / HomePod Mini
- AirPort Express
- Third-party AirPlay speakers
- macOS (Music/iTunes)
pip install mcp-pyatvOr run directly without installing:
uvx mcp-pyatvAdd this to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"apple-tv": {
"command": "uvx",
"args": ["--python", "python3.13", "mcp-pyatv"]
}
}
}Note: Claude Desktop may not inherit your shell's PATH. If you get a "command not found" error, use the full path to
uvx(runwhich uvxin your terminal to find it):{ "mcpServers": { "apple-tv": { "command": "/Users/you/.local/bin/uvx", "args": ["--python", "python3.13", "mcp-pyatv"] } } }
If you've cloned the repo and want to run from source:
{
"mcpServers": {
"apple-tv": {
"command": "/path/to/venv/bin/python",
"args": ["-m", "mcp_pyatv.server"],
"env": {
"PYTHONPATH": "/path/to/mcp-pyatv/src"
}
}
}
}On first use, just say "Pair my Apple TV" to your MCP client. The server handles the rest:
- It scans your network and discovers devices.
- A PIN appears on your TV screen.
- You tell the client the PIN.
- Credentials are stored locally and persist across sessions.
You only need to pair once per device. HomePods do not require pairing.
mcp-pyatv exposes 32 tools organized by category:
| Tool | Description |
|---|---|
scan_devices |
Scan the local network for Apple TV and AirPlay devices |
device_info |
Get detailed information about a specific device |
| Tool | Description |
|---|---|
start_pairing |
Begin the pairing process with a device |
finish_pairing |
Complete pairing by submitting the PIN shown on screen |
| Tool | Description |
|---|---|
play |
Resume playback |
pause |
Pause playback |
play_pause |
Toggle play/pause |
stop |
Stop playback |
next_track |
Skip to next track |
previous_track |
Go to previous track |
skip_forward |
Skip forward by a number of seconds |
skip_backward |
Skip backward by a number of seconds |
set_position |
Seek to a specific position |
set_shuffle |
Set shuffle mode |
set_repeat |
Set repeat mode |
| Tool | Description |
|---|---|
navigate |
Send remote control commands -- supports up, down, left, right, select, menu, home, top_menu with single_tap, double_tap, or hold actions |
| Tool | Description |
|---|---|
get_volume |
Get the current volume level |
set_volume |
Set volume to a specific level |
volume_up |
Increase volume |
volume_down |
Decrease volume |
| Tool | Description |
|---|---|
list_apps |
List all installed apps |
launch_app |
Launch an app by name or bundle ID |
| Tool | Description |
|---|---|
turn_on |
Turn on the device |
turn_off |
Turn off / put the device to sleep |
power_state |
Check if the device is on or off |
| Tool | Description |
|---|---|
set_text |
Type text into a text field (e.g., search boxes) |
get_text |
Get the current text field contents |
clear_text |
Clear the current text field |
| Tool | Description |
|---|---|
play_url |
Stream media from a URL to the device |
stream_file |
Stream a local file to the device |
| Tool | Description |
|---|---|
now_playing |
Get information about what's currently playing |
get_artwork |
Get the artwork for the currently playing media |
Checking what's playing:
"What's playing on my Apple TV?"
The server calls
scan_devicesto find your Apple TV, thennow_playingto get the current track/show info.
Launching an app:
"Open Netflix"
The server calls
launch_appwith the Netflix bundle ID.
Adjusting volume:
"Set the volume to 40"
The server calls
set_volumewith level 40.
Pairing a new device:
"Pair my Apple TV"
The server calls
scan_devices, thenstart_pairing. A PIN appears on your TV. You say "The PIN is 1234", and the server callsfinish_pairingto complete the process.
| Variable | Description | Default |
|---|---|---|
MCP_PYATV_STORAGE_PATH |
Override the file path where pairing credentials are stored | ~/.pyatv.conf |
The default credential file (~/.pyatv.conf) is shared with pyatv's atvremote CLI tool. If you've already paired devices using atvremote, mcp-pyatv will pick up those credentials automatically.
play_urlbroken on tvOS 26.x -- upstream pyatv issue (#2821)stopignored by some apps -- YouTube and certain other apps do not respond to the stop commandget_artworkdepends on the app -- not all apps expose artwork metadata- Same network required -- your machine must be on the same WiFi network as your devices
set_shuffle/set_repeat-- require an active music playback queue to work- Python 3.14 -- not currently supported due to asyncio compatibility issues in pyatv
This project is built on pyatv by Pierre Stahl -- the Python library that implements the Companion, AirPlay, RAOP, MRP, and DMAP protocols used by Apple devices. All protocol-level communication, device discovery, and pairing logic happens inside pyatv. mcp-pyatv provides only the MCP server layer on top.
For protocol details, bug reports related to device communication, or to contribute to the underlying library, visit:
MIT -- see LICENSE for details.
