| name | grainger-fetch-route |
| description | Decide how to reach grainger.com and prove the route works before spending requests on it. Use at the start of any Grainger task, and whenever a fetch returns something that looks like an empty or missing page. |
| allowed-tools | Read, Bash(python3 *), Bash(ls *), Bash(stat *) |
Choosing a route into Grainger
The fact that governs everything here: Grainger refuses requests with HTTP 200.
Three distinct refusals, none with an error status, one of which is a convincing
"not found" page. A client that trusts the status code reports an empty result set
and sounds sure of itself.
Order of preference
scripts/grainger_fetch.py from this machine — typeahead, category search,
facets, result SKUs, branch stock. Cheap, fast, no browser.
claude-in-chrome — price, spec table, live availability, branch names.
Everything the script tier cannot reach. Costs a real browser session.
There is no third route. Verified 2026-08-17: anonymous curl, geo-egress from
Israel, geo-egress from the US Windscribe exit, and gateway Playwright all
return EDGE_BLOCK. A US IP alone is not enough. Do not spend calls rediscovering
this — see reference/access-routes.md.
Always probe first
python3 scripts/grainger_fetch.py probe
Read three fields off the result before doing anything else:
session.signed_in — false means the cookie jar has no gcom.access_token
session.token_expires_in_minutes — negative means re-export before continuing
status — OK, or one of the three refusals
When the probe says no
status | Meaning | Do |
|---|
NO_SESSION | No exported cookies found | Ask the user to export grainger.com cookies from their signed-in Chrome to ~/.local/share/claude-plugins/grainger/cookies.json. Do not attempt to sign in yourself |
EDGE_BLOCK | Session missing/stale, or UA mismatch | Re-export. Check --ua matches the exporting Chrome's version |
BOT_WALL | DataDome flagged the IP | Stop. Tell the user, and say that retrying extends the block. Switch to the browser tier or wait |
HTTP_ERROR | A genuine HTTP error | Report it as itself — distinct from a block |
NOT_JSON | 200, parseable as neither JSON nor a known block page | The endpoint shape may have changed. Capture the body and look before concluding anything |
What never happens here
- Captchas are not solved or bypassed. A
DATADOME_403 ends the script tier
for that request. Move to the browser or report the limit.
- No retry loops. Two attempts, then change route or ask.
- No parallel fan-out. This is a real account. Serial requests, with pauses.
- Cookie values are never printed and never written into the repo.
Reporting
Say which tier answered. A price from the script tier does not exist; if the
browser tier did not read it this session, report it as not retrieved rather than
carrying one over from earlier or inferring it from a list page.