npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@marrowdev/browse-core

v0.16.0

Published

The browser-side reading kit behind marrow-browse: the map of what can be pressed, opening what can be opened, walking pages, and reading the DOM. Published so Marrow's deep read can share it instead of keeping a second copy.

Downloads

673

Readme

marrow-browse

人がログイン/2FA/CAPTCHA を通し、AI がその先を歩くローカル MCP サーバ。 ブラウザは本人のマシンの、昨日ログインしたままの Chrome。

売りは「解けること」ではなく「解かないと言い切れること」。 CAPTCHA を解かず、破壊的な control を押さず、人に手渡す。

[ browse-mcp ]  browse_open / act / read / paginate / wait_for_human / list / close / shutdown
     ↓
[ 実 Chrome ]  永続プロファイル ~/.local/share/marrow/profiles/default
     └ keeper タブ  browse-mcp/keeper.ts  ← 閉じると全部落ちる=この製品が持つ唯一の面

使い方はリポのルートにある USAGE.md、道具の詳細は browse-mcp/README.md。

🚨 ここをリンクにしないこと(#19)。この README は @marrowdev/browse-core に同梱されて配られる (リポのルート=あのパッケージのルート)。⚠️ npm は README を files に関わらず必ず同梱するので、 外すこともできない ⇒ tarball に入っていない物へのリンクは npmjs.com で 404 する(#12 と同じ穴)。 💭 @marrowdev/browse-mcp の方は browse-mcp/ に自分のルートを持つので、配るのはあちらの README。 browse-mcp/check-dist.mjs が prepublishOnly から両方のパッケージを見張っている。


この repo が出している 2 つのパッケージ

| | | | |---|---|---| | @marrowdev/browse-mcp | bin | これ —— 下に書いてあるローカル MCP サーバ。客が npx で入れる物 | | @marrowdev/browse-core | library | src/ の読む道具 5 本(押せる物の地図・開く・歩く・読む)を TS のまま配る。Marrow の deep 読みがコピーを持たずに借りるためだけに在る |

💭 npm でこのページを読んでいて、探しているのが後者なら —— 下の説明は前者(MCP サーバ)の物。 library の中身は src/affordance.ts / reveal.ts / paginate.ts / dom.ts / wait.ts で、 ⚠️ 出所は LAN の Gitea なので公開の置き場は無い(repository を載せていないのはそのため)。

🚨 library を使うなら、起動時に describeHost() を呼ぶ(0.15.0・#37)

affordance.ts の 2 つの文字列は呼び出し側のモデルに届く(破壊的 control の断り/地図の cap 警告)。⭐ 0.14.0 まで、その 2 つは marrow-browse と名乗り、browse_wait_for_human と browse_act を名指ししていた —— 出荷している客が 1 人だった間は真だった文。

import { describeHost } from '@marrowdev/browse-core/affordance';

describeHost({
  product: 'your-tool',                        // 断りが名乗る名前
  handoff: 'your_wait_for_human',              // ⚠️ 無いなら書かない(後述)
  snapshot: 'your_act {do:"snapshot"}',        // 地図を取り直す呼び方
});

⭐ 呼ばなくても壊れない —— 名前を 1 つも出さない、真だが少し漠然とした文になる。 🚨 handoff を「それらしい名前」で埋めないこと。 ⚠️ handoff.ts は tarball に入っていない ので、library の客に人へ手渡す道具が在るとは限らない —— 🚨 無い道具を名指しされたモデルは、 断られた control を押す別の道を探しに行く(それを止めるのが断りの唯一の役目)。 📌 実例は marrow-hand: 動詞が無いので handoff を渡さず、文は「人に渡せ」で終わる。


この repo の成り立ち(2026-08-11)

Marrow から割って出た。理由は技術ではなく速度 —— SaaS(③)と同じ repo に居ると、 ②の実装が回らなかった。⚠️ 屋号は共有したまま(@marrowdev/ / marrow-browse の名前は残る)。 分けたのは製品の線であって、屋号ではない。

**運転手は Playwright のまま。**Marrow 側は chromiumoxide(Rust)を持っているが、 ②がそちらへ寄る予定は無い —— 🚨 客が買っているのは本人のプロファイルであって、 バイナリの数ではない。加えて connectOverCDP は bun でハングするので node が load-bearing。

src/ に 6 本しか居ないのはなぜか

Marrow の src/ は 20 本あったが、この面が実際に辿るのは 6 本だけだった(実測):

| | | |---|---| | affordance.ts / reveal.ts | 押せる物の地図と、開けられる物を開く仕事 —— ②の核 | | paginate.ts / wait.ts / dom.ts | 歩く・待つ・読む | | handoff.ts | 壁で人に手渡す |

残り 11 本(orchestrator / crawler / judge / store …)は Marrow に残った。 ⚠️ Marrow 側の deep 読みはこの 6 本のうち 5 本を使うので、あちらは @marrowdev/browse-core をパッケージとして引く(版を固定する側)。 🚨 ここは長く @marrowdev/browse-mcp と書いてあったが、2026-08-13 に Marrow の package.json を見たら @marrowdev/browse-core: ^0.1.0 だった —— bin と library は別物で、 ②の客が npx で入れるのが前者、③が引くのが後者。混ぜると「客に③の荷物を積まない」という 分け方の理由ごと消える。

⚠️ **履歴は持ってきていない。**②の経緯(Marrow #16 の手渡し / Marrow #51 の破壊的ガード / Marrow #69 の掃除 など)は Marrow の git log と HANDOFF.md に残っている。消えてはいない、こちらに無いだけ。


検査

🚨 browse-mcp/probes/e2e-lifecycle.ts は回さない。あれだけは共有プロファイルを使い browse_shutdown まで踏むので、走らせるとログインを失いうる(前科あり)。

bun run check                                        # 型検査(src + browse-mcp を全部)
bun run browse-mcp/probes/probe-doc-paths.ts         # 文書が指す物が実在するか(ブラウザを起こさない)
bun run browse-mcp/probes/probe-redact-notice.ts     # ロック画面のフィルタ: 秘密は消え、名前は残るか(同上)
bun run browse-mcp/probes/probe-handoff.ts           # 手渡し(偽の通知器)
bun run browse-mcp/probes/probe-paginate-wire.ts     # MCP の面
bun run browse-mcp/probes/probe-changed-contract.ts  # changed: の契約 + 語彙 + ref 表記
bun run browse-mcp/probes/probe-map-arrival.ts       # まだ届いていない地図が完成した顔をしていないか
bun run browse-mcp/probes/probe-keeper.ts            # keeper タブ(2 プロファイル・遅い)
bun run browse-mcp/probes/probe-chrome-missing.ts    # Chrome 不在が名前で止まるか
bun run browse-mcp/probes/probe-act-latency.ts       # 遅れて着いた効果を `no` と言わないか

# ── survey(判定を持たない台。⭐ 数を出すだけで、緑にも赤にもならない)────────────
bun run browse-mcp/probes/survey-page-adapter-acts.ts    # act() は playwright でない Page でも同じことをするか(marrow-hand#1 Q1b)
bun run browse-mcp/probes/survey-page-adapter-hard.ts    # 上の 2 つが測れなかった 3 点(marrow-hand#1 Q1c)
bun run browse-mcp/probes/survey-extension-transport.ts  # 拡張は MCP の面を運べるか、どう運ぶか(marrow-hand#1 Q2)
                                                         # ⭐ この 3 本の答えが marrow-hand になった
bun run browse-mcp/probes/survey-what-the-wall-reads.ts  # 壁は実際に何を読んでいるのか(#22 / #31・⚠️ esbuild で束ねてから走らせる)
bun run browse-mcp/probes/probe-hidden-controls.ts   # 見えない control を「押せる」と言わないか
bun run browse-mcp/probes/probe-destructive-guard.ts # 破壊的な control を名前で断るか
bun run browse-mcp/probes/probe-two-servers.ts       # 1 プロファイルに 2 サーバ同時(Marrow #6 の主題)
bun run browse-mcp/probes/probe-stdin-close.ts       # 客が去ったらサーバも去るか(attach 済みが本番・#2)
bun run browse-mcp/probes/probe-node-floor.ts        # 古い node を②の名前で断るか(無ければ exit 2)
bun run browse-mcp/probes/probe-server-version.ts    # 握手で名乗る版が、実際に走っている build の版か(#21)
# 起動時の掃除。⚠️ 2 本在るのは強さが違うから(#3)
bun run browse-mcp/probes/probe-sweep-older-selves.ts # 本物のサーバ 4 本で測る(node が要る)
bun run browse-mcp/probes/probe-sweep-portable.ts     # 囮で判定機構だけ測る(`ps` さえ在れば走る=macOS 可)

⚠️ bun run では走らない 3 本(node が要る= connectOverCDP が bun でハングするので、 bun で回すと probe 自身がその罠にかかる)。各ファイルの冒頭に esbuild で焼く 1 行が書いてある:

browse-mcp/probes/probe-cdp-attach.ts        # 誰の物でもないブラウザで②が成立するか
browse-mcp/probes/probe-emulation-fidelity.ts # 人が見ている画面を見ているか(playwright の再描画ではなく)
browse-mcp/probes/probe-keeper-offer.ts      # keeper が窓を奪わず新しい build を差し出すか

💭 この一覧が実物と揃っているかは probe-doc-paths.ts が測る(検査 3)—— HANDOFF が「README の probe 一覧は手で写した=腐る側」と言っていた所で、 実際 2026-08-13 の時点で 4 本が一覧から漏れていた。

⚠️ probe は実ブラウザを起こす(headless・使い捨てプロファイル)。

🚨 この一覧には「赤で正しい」probe が混ざりうる —— 直す前に検出器として書かれたもの。 赤の意味は probe 自身が最後の行で名乗る。逆に、そういう probe が理由なく緑になったら疑う。