Download and verify Hyperoptic broadband bill PDFs via Chrome DevTools browser automation. Use this skill whenever the user mentions Hyperoptic bills, broadband invoices, internet bill downloads, or wants to grab/fetch/save a bill from their Hyperoptic account. Also trigger when the user asks to download bills for expense tracking, filing, or record-keeping from Hyperoptic.
This skill automates downloading bill PDFs from the Hyperoptic customer portal using Chrome DevTools MCP for browser automation. It navigates the site, locates the target bill, downloads the PDF, renames it descriptively, and verifies the contents.
Chrome DevTools MCP server configured and running (npx @anthropic-ai/chrome-devtools-mcp@latest)
The MCP server registered in Claude Code settings under mcpServers
If MCP tools are unavailable, stop and ask the user to set up Chrome DevTools MCP first
Stale browser lock: If a tool call fails with "The browser is already running", check for a stale lock file and orphaned Chrome process using these commands:
# Check for stale lock
ls -la ~/.cache/chrome-devtools-mcp/chrome-profile/SingletonLock
# Find the PID from the symlink target (e.g. HOSTNAME-PID)
readlink ~/.cache/chrome-devtools-mcp/chrome-profile/SingletonLock
# If the process is an old MCP Chrome (not regular Chrome), kill it
kill <PID>
Determine:
~/Desktop/ if not specified.Billing cycle note: Hyperoptic generates bills around the 9th of each month. If the user asks for the current month's bill and it is early in the month (before the 10th), warn them it may not be available yet and offer to download the previous month's bill instead.
Confirm parameters with the user before proceeding.
https://account.hyperoptic.com/. This redirects to the dashboard if logged in, or shows the Keycloak login form if not./account, the user is logged in. Proceed to Step 3.wait_for with timeout 120000ms, looking for text: ["Dashboard", "Account", "My bills", "Welcome", "Bills"].Navigate directly to https://account.hyperoptic.com/bills-and-payments (sidebar nav links may be blocked by overlays, so always use direct URL navigation).
Take a snapshot. The page shows:
Note the current invoice amount from the account summary (e.g. "£53.00" next to "Current invoice"). This will be used for the filename of the latest bill.
Page structure: The bills page lists all 12 months. Clicking a month name opens a dialog with the PDF for that month's bill. Months without a bill may show an empty dialog or no response.
url attribute (e.g. blob:https://account.hyperoptic.com/<uuid>)The PDF is rendered inside the dialog via a blob: URL. Use evaluate_script to trigger a browser download from this blob URL.
Use evaluate_script to create a temporary anchor element that downloads the blob:
async () => {
const blobUrl = '<BLOB_URL_FROM_SNAPSHOT>';
const a = document.createElement('a');
a.href = blobUrl;
a.download = '<FILENAME>.pdf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
return { triggered: true };
}
Poll for up to 30 seconds to verify the file exists in ~/Downloads/<FILENAME>.pdf using Bash. A loop with a short sleep can be used to check for the file.
Why this approach? The get_network_request tool with responseFilePath often writes 0-byte files for PDF responses that have already been consumed by Chrome's PDF viewer. The blob URL download is reliable because the blob remains in memory.
Fallback: If the blob URL download fails:
list_network_requests with resourceTypes: ["fetch", "xhr", "document", "other"] to find the billing API request
(URL pattern: /billing/INVOICE_NUMBER).get_network_request with an absolute responseFilePath.Construct the filename: Hyperoptic_Bill_<Month>_<Year>_GBP<Amount>.pdf
Hyperoptic_Bill_March_2026_GBP53.00.pdfHyperoptic_Bill_March_2026.pdfMove from ~/Downloads/ to the save location:
mkdir -p "<SAVE_LOCATION>"
mv ~/Downloads/<FILENAME>.pdf "<SAVE_LOCATION>/Hyperoptic_Bill_<Month>_<Year>_GBP<Amount>.pdf"
Verify: test -s "<SAVE_LOCATION>/Hyperoptic_Bill_<Month>_<Year>_GBP<Amount>.pdf"
<full path><month/year><amount>If verification fails, warn the user but keep the file.
| Scenario | Action |
|---|---|
| MCP Chrome won't start (stale lock) | Check ~/.cache/chrome-devtools-mcp/chrome-profile/SingletonLock, kill orphaned process |
| Not logged in | Ask user to log in, wait with 120s timeout |
| Cookie banner blocking | Click accept/dismiss button |
| Sidebar nav not clickable | Navigate directly to /bills-and-payments URL |
| Target month not found | List available months, ask user to pick one |
| Year not available | Check year selector options, inform user of available range |
| Downloaded file 0 bytes | Switch to blob URL download method |
| Blob URL download fails | Fall back to network request interception |
| PDF verification mismatch | Warn user with details, keep the file |
| Multiple accounts | List accounts, ask user which to use |
| Page layout unexpected | Take a screenshot, describe what is visible, ask for guidance |