Summary
Splits the single effectiveMode switch into two: effectiveCommitMode (still gates billable mail-piece sends behind LOB_LIVE_MODE=true) and effectiveReadMode (defaults to live whenever LOB_LIVE_API_KEY is configured). Analytics like "how many letters last week?" now return real-account data without unlocking billable commits.
Also tightens every list-tool description to lead with the count idiom (include: ['total_count'] + limit: 1) so LLM-driven clients stop paginating to count.
What changed
Read/commit mode split
LobClient.request()picks the default key by operation kind: billable POSTs (/postcards,/letters,/self_mailers,/checks,/buckslips/{id}/orders,/cards/{id}/orders) default to commit mode; everything else (lists, gets, searches, cancels, deletes, non-billable creates, verifications) defaults to read mode.- New env var
LOB_READS_USE_TEST=trueforces reads back onto the test key for dev environments where the live key is mounted but you want test responses. - Boot banner now prints both modes on startup so request routing is observable before any tool is invoked.
- Wizard prompt clarified: "Enable LIVE COMMITS now?" (was the ambiguous "Enable live mode now?").
Description hints for analytical questions (1.3-equivalent of the count fix that landed alongside)
- Every list tool description leads with: pass
include: ['total_count']withlimit: 1to answer "how many?" in one call instead of paginating. The three endpoints that don't acceptinclude[]=total_count(/webhooks,/buckslips/{id}/orders,/cards/{id}/orders— verified against Lob's live API) get an honest "not supported" note. listParamsSchema.includeanddateFilterSchemareinforce the same pattern at the parameter level.
Tests
- +14 unit tests covering env split (5) and method-based key routing (12: GET → live, billable POST → test, non-billable POST → live, DELETE → live, PATCH → live, verifications → live, explicit
keyMode: "test"override, theLOB_READS_USE_TESTopt-out, full-live mode parity). - Total unit suite: 183 → 197. Integration smoke (22/22) and stdio smoke (78 tools, 23 resources) unchanged.
Migration
| Setup | Before | After |
|---|---|---|
| Test-only | reads + commits both test | unchanged |
Live key, LOB_LIVE_MODE unset |
reads + commits both test | reads now hit live, commits still test |
| Full live | reads + commits both live | unchanged |
If the prior behavior is needed (live key mounted, but reads should still hit test), set LOB_READS_USE_TEST=true.
Internal callers of env.effectiveMode need to switch to effectiveCommitMode (billing-gated logic) or effectiveReadMode (read-side logic).
🤖 Generated with Claude Code