mcp-pyatv
MCP server for controlling Apple TV, HomePod, and AirPlay devices via pyatv.
What It Does
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.
Supported Devices
- Apple TV -- all generations, including tvOS 15+
- HomePod / HomePod Mini
- AirPort Express
- Third-party AirPlay speakers
- macOS (Music/iTunes)
Quick Start
Install
pip install mcp-pyatv
Or run directly without installing:
uvx mcp-pyatv
Claude Desktop Configuration
Add 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"] } } }
Local Development
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"
}
}
}
}
First Use / Pairing
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.
Available Tools
mcp-pyatv exposes 32 tools organized by category:
Discovery
| Tool | Description |
|---|---|
scan_devices |
Scan the local network for Apple TV and AirPlay devices |
device_info |
Get detailed information about a specific device |
Pairing
| Tool | Description |
|---|---|
start_pairing |
Begin the pairing process with a device |
finish_pairing |
Complete pairing by submitting the PIN shown on screen |
Playback
| 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 |
Navigation
| 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 |
Audio
| 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 |
Apps
| Tool | Description |
|---|---|
list_apps |
List all installed apps |
launch_app |
Launch an app by name or bundle ID |
Power
| 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 |
Keyboard
| 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 |
Streaming
| Tool | Description |
|---|---|
play_url |
Stream media from a URL to the device |
stream_file |
Stream a local file to the device |
Media Info
| Tool | Description |
|---|---|
now_playing |
Get information about what's currently playing |
get_artwork |
Get the artwork for the currently playing media |
Example Conversations
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.
Configuration
| 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.
Known Limitations
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
Built On
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:
License
MIT -- see LICENSE for details.
Metadata
Release files for mcp-pyatv 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_pyatv-0.2.0.tar.gz | 153.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_pyatv-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 170.4 kB
Release files / mcp_pyatv-0.2.0.tar.gz
| Download URL | mcp_pyatv-0.2.0.tar.gz |
|---|---|
| Size | 153.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2548241dc46f3f1147a7646e72f6a1f9405cc92cb7ac2139ad7d779eb8d20e0
|
|
BLAKE2b-256 checksum How to use checksums |
a64ab431bfc167bd7f0effe17dc259e1a1be57946039cf5bdb68373ae63a3fb9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mcp_pyatv-0.2.0-py3-none-any.whl
| Download URL | mcp_pyatv-0.2.0-py3-none-any.whl |
|---|---|
| Size | 16.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
84ec039c741ffbf64a8b65f79f66096446813a9410fc28b83a71b8be1eb771bc
|
|
BLAKE2b-256 checksum How to use checksums |
1ecb7508fe82b759d863a08d3ef317b56c45e6c2de768c31fb3d8ed73d2d463d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|