plex
Query Plex Media Server for movies, TV shows, music, and playback history.
Skill by eddmann
Chalk Labs
Need help deploying plex?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/eddmann-plex
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/plex
What's inside
- Skill name
plex- Description
- Query Plex Media Server for movies, TV shows, music, and playback history. Use when the user asks about their Plex library, "what movies do I have", "recently added", "continue watching", "watch history", "search my Plex", or wants to explore media in their Plex server.
- License
- MIT
- Instructions
- 322 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Files (1)
- SKILL.md
SKILL.md (first lines)
# Plex Skill
Query Plex Media Server by writing UV inline Python scripts using plexapi.
## Setup
### Credentials
Requires `PLEX_SERVER_URL` in `workspace/.env`.
If not set, ask the user for their Plex server URL (e.g. `http://192.168.1.100:32400`), then append to `.env`:
```bash
echo 'PLEX_SERVER_URL=http://their-server:32400' >> .env
```
### Authentication
Plex uses OAuth with a PIN-based flow. This MUST be done in two separate steps because you need to show the user the link and wait for them to click it before polling.
**Step 1: Generate auth URL and save state**
```bash
set -a; source .env 2>/dev/null; set +a; uv run - <<'EOF'
# /// script
# requires-python = ">=3.11"
# dependencies = ["plexapi>=4.18"]
# ///
import json
from pathlib import Path
from plexapi.myplex import MyPlexPinLogin
pinlogin = MyPlexPinLogin(oauth=True)
code = pinlogin._getCode()
pin_id = pinlogin._id
client_id = pinlogin._headers()['X-Plex-Client-Identifier']
# Save state for step 2
Path("plex-oauth-state.json").write_text(json.dumps({
"pin_id": pin_id,
"code": code,
"client_id": client_id,
}))
print(f"URL: {pinlogin.oauthUrl()}")
EOF
```
Send the URL to the user as a clickable markdown link. Tell them to sign in and let you know when done.
The PIN is valid for ~15 minutes so there's no rush.
**IMPORTANT:** Do NOT call `pinlogin.run()` or `pinlogin.waitForLogin()` — these start a blocking polling thread that will timeout before the user can click the link. Instead, manually call `_getCode()` and save the state.
**Step 2: Poll for token** (run ONLY after user confirms they've signed in)
```bash
export PLEX_SERVER_URL=$(grep PLEX_SERVER_URL .env | cut -d= -f2); uv run - <<'EOF'
# /// script
# requires-python = ">=3.11"
# dependencies = ["plexapi>=4.18", "requests"]
# ///
import json, os, requests, time, xml.etree.ElementTree as ET
from pathlib import Path
from plexapi.server import PlexServer
from plexapi.myplex import MyPlexAccount
state = json.loads(Path("plex-oauth-state.json").read_text())
headers = {
"Accept": "application/xml",
"X-Plex-Client-Identifier": state["client_id"],
"X-Plex-Product": "PlexAPI",
}
# Poll with backoff to avoid rate limiting (429)
for i in range(15):
resp = requests.get(
f"https://plex.tv/api/v2/pins/{state['pin_id']}",
headers=headers, timeout=10
)
if resp.status_code == 429:
time.sleep(5)
continue
if resp.status_code == 200:
root = ET.fromstring(resp.text)
token = root.attrib.get('authToken', '')
if token:
server_url = os.environ["PLEX_SERVER_URL"]
plex = PlexServer(server_url, token)
Path("plex-token.json").write_text(json.dumps({
"token": token,
"server_url": server_url
}, indent=2))
Path("plex-token.json").chmod(0o600)
account = MyPlexAccount(token=token)
print(f"SUCCESS: Connected as {account.username}")
print(f"Server: {plex.friendlyName}")
for section in plex.library.sections():
print(f" - {section.title} ({section.type})")
exit(0)
time.sleep(3)
print("ERROR: No token received. Ask user to try signing in again.")
exit(1)
EOF
```
**Key details about the OAuth flow:**
- `MyPlexPinLogin.run()` generates a NEW pin and starts a blocking thread — don't use it for two-step auth
- `MyPlexPinLogin.pin` raises `BadRequest` when `oauth=True` — don't access it
- Use `_getCode()` to generate the PIN without starting the polling thread
- Save `_id` (pin ID), `_code`, and the client identifier to a file between steps
- In step 2, poll the Plex API directly with `requests` using the saved pin ID
- Plex rate limits aggressively — poll every 3s, back off on 429s
**Alternative: direct token auth.** If the user already has a Plex token, skip OAuth and store it directly:
```bashFrom eddmann/jeeves, MIT.
More from eddmann/jeeves
- 0.448score
zettelkasten
eddmann
Personal knowledge base using the Zettelkasten method.
SkillDFreshness: D★ 2Claude Code +9 - 0.448score
summarise
eddmann
Extract and summarise content from URLs, YouTube videos, podcasts, and files.
SkillDFreshness: D★ 2Claude Code +9 - 0.448score
twitter
eddmann
Fetch X/Twitter timeline and bookmarks.
SkillDFreshness: D★ 2Claude Code +9 - 0.448score
reminders
eddmann
Manage reminders — one-off and recurring.
SkillDFreshness: D★ 2Claude Code +9 - 0.448score
lists
eddmann
General-purpose lists — shopping, questions for appointments, packing lists, etc.
SkillDFreshness: D★ 2Claude Code +9 - 0.445score
pages
eddmann
Publish dynamic web pages for dashboards, trackers, or any data viewable in a browser.
SkillDFreshness: D★ 2Claude Code +9 - 0.443score
garmin
eddmann
Query Garmin Connect health and fitness data including activities, sleep, heart rate, HRV, stress, and body battery.
SkillDFreshness: D★ 2Claude Code +9 - 0.443score
strava
eddmann
Query Strava fitness data including activities, stats, and athlete info.
SkillDFreshness: D★ 2Claude Code +9 - 0.442score
skill-creator
eddmann
Create or update skills.
SkillDFreshness: D★ 2Claude Code +9 - 0.440score
playwright
eddmann
Render web pages with JavaScript using Playwright for sites that need browser rendering or have issues with simple HTTP fetching.
SkillDFreshness: D★ 2Claude Code +9 - 0.414score
github
eddmann
Interact with GitHub using the `gh` CLI.
SkillDFreshness: D★ 2Claude Code +9
Signals
- Stars
- 2
- Forks
- 1
- Open issues
- 0
- Last commit (this folder)
- Feb 12, 2026 (8 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/eddmann/jeeves
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from eddmann
- 0.556score
review
eddmann
Use when reviewing local code against repository conventions and coding guidelines.
SkillBFreshness: B★ 2Claude Code +9 - 0.556score
db
eddmann
Use when inspecting schemas, querying data or making authorized database changes.
SkillBFreshness: B★ 2Claude Code +9 - 0.553score
public-release
eddmann
Use when auditing a repository before making it public.
SkillBFreshness: B★ 2Claude Code +9 - 0.551score
commit
eddmann
Use when committing task changes using Conventional Commits.
SkillBFreshness: B★ 2Claude Code +9 - 0.551score
generate-readme
eddmann
Use when creating or updating a project's README from its actual capabilities and usage.
SkillBFreshness: B★ 2Claude Code +9 - 0.551score
context7
eddmann
Use when looking up library or framework documentation and version-specific API examples.
SkillBFreshness: B★ 2Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get plex running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
plex skill. Agent Mart. https://agentmart.dev/skills/eddmann-plex (last updated 2026-10-24)