Queue URLs on YTPTube, directly or through the SSH jumphost
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-22 12:03:42 -04:00
README.md README: iOS share-sheet shortcut, key from Data Jar or pass, direct or via the jumphost 2026-10-22 12:03:42 -04:00
ytptube-add Initial ytptube-add: queue URLs on YTPTube, direct or via the jumphost 2026-10-22 11:51:53 -04:00

ytptube-add

Queue URLs for download on YTPTube through its API, either directly (LAN or VPN) or through an SSH tunnel via the jumphost (from the WAN).

ytptube-add URL...                      # direct, default preset
ytptube-add -p audio_m4a URL            # pick a preset
ytptube-add -j URL                      # from the WAN, via ssh.home.provost.one
ytptube-add -s -f music URL1 URL2       # into downloads/files/music, not started

Run ytptube-add -h for all options.

How it connects

  • Direct (default): POST $YTPTUBE_URL/api/history, by default https://ytdlp.home.provost.one (tightbeam's Caddy, LAN/VPN only, local-CA certificate - the client must trust that CA).
  • Jumphost (-j): opens ssh -L 18571:192.168.2.245:8571 ssh.home.provost.one sleep 10 in the background and posts to http://localhost:18571. The tunnel closes by itself once the request is done. Needs SSH access to the jumphost.

Environment

Variable Default
YTPTUBE_API_KEY (from pass) API key (YTPTube Settings -> API keys).
YTPTUBE_PASS_ENTRY personal/apikeys/ytptube/sulaco pass entry read when YTPTUBE_API_KEY is unset (line 1).
YTPTUBE_URL https://ytdlp.home.provost.one Direct URL.
YTPTUBE_JUMPHOST ssh.home.provost.one SSH host for -j.
YTPTUBE_TARGET 192.168.2.245:8571 YTPTube's host:port as seen from the jumphost.
YTPTUBE_LOCAL_PORT 18571 Local end of the -j tunnel.

The API key is sent to curl on stdin, never on its command line.

iOS: queue from the share sheet

iOS can't run ytptube-add, but a Shortcut can make the same API call. Build it once in the Shortcuts app; it then shows up as Add to YTPTube in the share sheet of Safari, YouTube and so on.

1. Store the API key

Pick one:

  • Data Jar (recommended - Shortcuts can read it directly): in Data Jar, add a text value at key path ytptube.apiKey holding the key (line 1 of personal/apikeys/ytptube/sulaco).
  • pass (Pass for iOS): keep using personal/apikeys/ytptube/sulaco. Pass for iOS has no Shortcuts actions, so the shortcut reads the key from the clipboard: copy the password in Pass, then share the link. (If your pass app does offer a "get password" action, use that instead of Get Clipboard.)

2. Build the shortcut

New shortcut, named Add to YTPTube. In its details (ⓘ), turn on Show in Share Sheet; set the share-sheet input types to URLs, Safari web pages and Text, and If there's no input to Ask For Text (so it can also be run from the app with a pasted link).

Actions, in order:

  1. Get URLs from Shortcut Input.

  2. The key, depending on step 1:

    • Data Jar: Get Value for key path ytptube.apiKey.
    • pass: Get Clipboard.

    Then Set Variable Key to that result.

  3. Choose from List with 720p_mp4, audio_m4a, default (any preset names), prompt "Preset". Set Variable Preset.

  4. Choose from Menu, prompt "Route", options Home / VPN and Away (jumphost):

    Home / VPN - talk to YTPTube through Caddy:

    • Get Contents of https://ytdlp.home.provost.one/api/history, Method POST, Headers: Authorization = Bearer + Key, Request Body JSON with url (Text) = URLs and preset (Text) = Preset.

    This needs the phone to trust Caddy's local CA: open http://ca.home.provost.one in Safari, install the profile (Settings → General → VPN & Device Management), then enable it under Settings → General → About → Certificate Trust Settings.

    Away (jumphost) - SSH to tightbeam and call YTPTube from there:

    • Text, exactly two lines:

      Authorization: Bearer [Key]
      {"url": "[URLs]", "preset": "[Preset]"}
      

      ([...] are variables inserted from the variable bar.)

    • Run Script over SSH: Host ssh.home.provost.one, Port 22, User paul, Authentication SSH Key, Input the Text above, Script:

      sh -c 'IFS= read -r h; exec curl -sS -H "$h" -H "Content-Type: application/json" --data-binary @- http://192.168.2.245:8571/api/history'
      

      The first stdin line becomes the auth header and the rest is the JSON body, so the key never appears on tightbeam's command line. The sh -c '...' wrapper is needed because paul's login shell on tightbeam is fish.

    • Shortcuts generates the SSH key the first time you pick SSH Key: tap it, Share Public Key, and add that line to ~/.ssh/authorized_keys for paul on tightbeam.

  5. Show Notification with the menu's result (YTPTube answers {"status": "accepted", ...}). ntfy's item_added notification confirms it too.

Neither route needs a VPN when away: the jumphost branch only uses SSH. YTPTube silently skips a URL that is already in its queue, while still answering "accepted".

YTPTube's upstream also publishes a ready-made Add To YTPTube shortcut. It talks to the instance URL directly, so it only covers the Home / VPN route.

Requirements

bash (3.2 is fine, so macOS's own works), curl, ssh for -j, and pass unless YTPTUBE_API_KEY is set.

The server side is deployed by the ytptube role.