{
  "markdown": "# Browser Fetch Router\n\n`browser-fetch-router` is a shared, policy-aware browser and web-fetch CLI for\ncoding agents. It centralizes provider routing, URL safety, approvals, caching,\ncost controls, audit logging, and lifecycle cleanup so individual agents do not\nreimplement those rules.\n\n## Install\n\n```bash\npython3 -m pip install .\nbrowser-fetch-router --help\n```\n\nThe package exposes these entry points:\n\n- `browser-fetch-router`\n- `read-web`\n- `read-user-tabs`\n- `interactive-browser`\n\n## Agent Usage\n\nEach agent invocation should set:\n\n- `BFR_AGENT=<agent-name>`\n- `BFR_SESSION_ID=<uuid-or-ulid>`\n\nThen call the shared CLI:\n\n```bash\nbrowser-fetch-router read-web <url> --json\nbrowser-fetch-router read-web <url> --allow-jina-auth --json\nbrowser-fetch-router read-web https://example.com --json\nbrowser-fetch-router read-user-tabs list --json\nbrowser-fetch-router interactive-browser \"open example.com and summarize visible text\" --json\n```\n\n### read-web Provider Credential\n\nGeneric public pages use Jina Reader. The default is anonymous: ambient\n`JINA_API_KEY` presence alone never authorizes use, and the anonymous path does\nnot read or validate it. Retry an anonymous `jina_auth_required` result with\n`--allow-jina-auth` when authenticated Reader access is intended.\n\nAuthenticated Jina may consume free or prepaid account tokens.\n`--allow-paid` controls only a new Parallel fallback; it never authorizes Jina\nauthentication. An adapter must not read or embed the credential. Credential\nretrieval, validation, request construction, caching, and rate limiting stay in\nthe shared CLI.\n\n`browser-fetch-router doctor --json` reports only the local state\n`missing`, `malformed`, or `configured`, plus that authenticated opt-in is\nrequired. It does not make a Reader request or claim that the remote service\naccepted the credential.\n\n### read-user-tabs CDP Setup\n\n`read-user-tabs` reads from a loopback Chrome CDP endpoint at\n`http://127.0.0.1:9222`. Start a separate temporary profile. Do not use the\nnormal browser profile for CDP. The required flags are\n`--remote-debugging-address=127.0.0.1 --remote-debugging-port=9222 --user-data-dir=<temporary-profile>`.\n\nThe managed setup helper prints the safe path, and `--launch` starts the\ntemporary loopback profile:\n\n```bash\nbrowser-fetch-router read-user-tabs setup --json\nbrowser-fetch-router read-user-tabs setup --launch --start-url https://example.com --json\n```\n\n```bash\nBFR_TMPDIR=\"${TMPDIR:-/tmp}\"\nBFR_CDP_PROFILE=\"$(mktemp -d \"${BFR_TMPDIR%/}/bfr-cdp-profile.XXXXXX\")\"\n\n# macOS:\nexport CHROME_BIN=\"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\"\n# Linux:\n# export CHROME_BIN=\"$(command -v google-chrome || command -v chromium || command -v chromium-browser)\"\n\n\"$CHROME_BIN\" \\\n  --remote-debugging-address=127.0.0.1 \\\n  --remote-debugging-port=9222 \\\n  --user-data-dir=\"$BFR_CDP_PROFILE\" \\\n  --no-first-run \\\n  --no-default-browser-check\n```\n\n### interactive-browser Providers\n\n- `--provider cloud` is live when `BROWSER_USE_API_KEY` is present and\n  `--allow-hosted-browser` is supplied.\n- `--provider browserbase` is live when `BROWSERBASE_API_KEY` is present and\n  `--allow-hosted-browser` is supplied. If your Browserbase account requires a\n  project id, also set `BROWSERBASE_PROJECT_ID`.\n- Local interactive mode is not advertised as a daily-use provider in this\n  build because it would require additional model/provider credentials.\n\n## Agent Adapter Install\n\nInstall thin agent adapters with the shared CLI:\n\n```bash\nbrowser-fetch-router install-agent --all --json\nbrowser-fetch-router install-agent pi --json\nbrowser-fetch-router install-agent --select codex,gemini,opencode --json\n```\n\nThe supported/default agent matrix, Pi migration note, Kimi inheritance caveat,\nenvironment override behavior, and `--adapter-path` rules are documented in\n[`docs/browser-fetch-router-install-agent-contract.md`](docs/browser-fetch-router-install-agent-contract.md).\n\nTo prove an external global command is not stale, capture its path before\nactivating or prepending the reviewed candidate environment. Then run the\ncandidate verifier against that absolute target:\n\n```bash\ncheckout_root=\"/absolute/path/to/reviewed-browser-fetch-router\"\ncd \"$checkout_root\"\nexternal_bfr_shim=\"$(command -v browser-fetch-router)\"\npython3 -m browser_fetch_router doctor --global-install --global-shim \"$external_bfr_shim\" --json\n```\n\nThe verifier reports candidate and target identities, package roots, schema\ndefaults, the target's `read-web --help` capability, and doctor health. It\nrejects self-verification. If the external command does not match this\npackage's expected contract it returns `stale_global_install` with a\n`pipx install --force \"$checkout_root\"` reinstall instruction using the\nreviewed checkout's captured absolute path.\n\n## Tests\n\n```bash\npython3 -m pytest tests/browser_fetch_router\n```\n\nFor contributor readiness, also verify package installability from outside the\nrepository:\n\n```bash\npython3 -m pip install <checkout-path>\nbrowser-fetch-router --help\n```\n\nGenerated virtualenvs, caches, bytecode, and package metadata are ignored by the\nrepository. Keep `git status --short` clean after running the documented flow.\n",
  "bytes": 5192,
  "sha": "d8a559b8e26d45cac0f1cf561eccbcdb13c53a783f7aaa781244723b432d1fd2",
  "repo_slug": "seungpyoson/browser-fetch-router",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_seungpyoson_browser_fetch_router_ec1be034/readme"
}