Skip to main content
Glama
riseblyp

mobile_claude_connect

by riseblyp

mobile_claude_connect

PC上のClaude Codeセッションに、iPhoneのデータ(写真、ビデオ、現在地、連絡先、カレンダー、クリップボード)へのアクセスを与える、電話とPCを橋渡しするものです。さらに、Claudeがログイン済みのWebサービスに対して独自のブラウザ自動化を記述・実行できるプラグインシステムも含みます。

電話は単なる画面です。すべてのバイトは自分のマシンに留まり、自分のTailscaleテイルネットを経由して転送されます。クラウドコンポーネントもサードパーティのサービスもなく、どこにもアップロードされません。

3つの要素:

要素

説明

server.py

ポート8778で動作するFlask + waitressアプリ。電話側のPWAを提供し、写真のアップロードや共有シートからのドロップを受け付け、ジョブキューを実行します。

indexer.py

写真・ビデオライブラリに対するCLIP埋め込みとセマンティック検索。SQLiteに保存されます。

mcp_server.py

stdio上のMCPサーバー。これがClaude Codeが実際に通信する対象です。


アーキテクチャ

        iPhone                      Tailscale                    Windows PC
 ┌────────────────────┐            ┌───────────┐      ┌──────────────────────────────┐
 │ Claude app         │            │           │      │  Claude Code                 │
 │  (Remote Control)  │───────────────────────────────>│      │                       │
 │                    │            │           │      │      │ stdio                  │
 │ Bridge PWA :8778   │  upload    │  100.x    │      │  mcp_server.py  ── MCP tools  │
 │  - photo picker    │───────────>│ WireGuard │─────>│      │                       │
 │  - run Shortcut    │            │  CGNAT    │      │  server.py  :8778             │
 │  - /login mirror   │            │  range    │      │   /ingest  ──> vault/         │
 │                    │            │           │      │   /drop    ──> vault/drop/    │
 │ Shortcuts app      │  location  │           │      │   /records ──> records table  │
 │  - Claude Bridge   │  contacts  │           │      │   /job/*   ──> job queue      │
 │  - Send to Claude  │───────────>│           │      │   /login/* ──> login_session  │
 └────────────────────┘            └───────────┘      │                              │
                                                      │  indexer.py ── CLIP ── GPU    │
   iCloud for Windows                                 │  caps.py ── Playwright ──┐    │
   photo library  ─────────────────────────────────────> watch_dirs             │    │
                                                      │  bridge.db (SQLite)     │    │
                                                      └─────────────────────────┼────┘
                                                                                │
                                                                  profiles/<service>/
                                                                  (persistent cookies)

ファイアウォールは100.64.0.0/10(TailscaleのCGNATレンジ)のみ許可します。パブリックインターネットからは何も到達できません。


Related MCP server: whitelabel-fleet-mcp

MCPツールサーフェス

MCPサーバーが登録されると、Claude Codeが利用できるツールです。

ツール

説明

photos_stats

インデックスのサイズ、日付範囲、未埋め込みのアイテム数、監視中のフォルダー。写真関連の操作では最初に呼び出してください。

photos_search

短い英語フレーズによる写真およびビデオのCLIPセマンティック検索。日付範囲、GPS境界ボックス、kindでフィルタリング可能。

photos_by_date

時間と場所のみでアセットを一覧表示(新しい順)。コンテンツのランキングはありません。

photos_places

粗いGPSクラスター(約55km)と写真数、最初/最後の日付を表示 —「いつどこにいたか」を把握できます。

photos_open

Claudeが実際に見られるJPEGにアセットをレンダリング: HEICは縮小され、ビデオは6フレームのコンタクトシートになります。

index_update

ボールトと監視フォルダーをスキャンして新しいファイルを探し、まだ埋め込まれていないものを埋め込みます。

phone_actions

電話側のショートカットが実行できるアクション名。

phone_request

電話向けのジョブをキューに追加(現在地、連絡先、カレンダー、クリップボード、ディープリンクを開く、通知)。

phone_job_status

キューされた電話ジョブの結果。

capability_list

インストール済みのケイパビリティプラグインと、各プラグインのブラウザプロファイルがログイン済みかどうか。

capability_howto

新しいケイパビリティを作成するための契約 — capabilities/_TEMPLATE.pyとルールを返します。

capability_run

名前でケイパビリティを実行。argsはそのrun()に直接渡されます。

capability_login

一回限りの人間によるログインを開きます。デフォルトでは電話にミラーリングされ、PC上で実際のウィンドウを開くこともできます。

records_query

電話がプッシュした写真以外のペイロードを読み取ります: 位置情報、連絡先、カレンダー、クリップボード、共有シートからのドロップ。


CLIPセマンティック検索

写真とビデオは**openai/clip-vit-large-patch14(設定可能)で埋め込まれます。写真は1つの画像埋め込みを生成し、ビデオはクリップの中央70%にわたってサンプリングされた3フレームの埋め込みを平均**し、再正規化します。すべてのベクトルはL2正規化されたfloat32で、SQLiteの生BLOBとして保存されるため、クエリは日付/地理でフィルタリングされた候補セットに対する1回のnumpy行列積で済みます — 数万アセットに対して数十ミリ秒です。

  1. SQLでtaken_at範囲および/または[lat_min, lat_max, lon_min, lon_max]境界ボックスでフィルタリングします。

  2. 英語のテキストクエリを埋め込み、候補行列と行列積を計算し、コサイン類似度でソートして上位kを取得します。

  3. 回答ではなく候補を返します — その後Claudeはphotos_openを呼び出し、何かを言う前にそれらを見ます。

実際に使い込んだ結果明らかになった2つの設計上の注意点:

  • スコアは相対的です。 コサイン類似度はすべてのアイテムでおおよそ0.15〜0.35に収まります。ランクが重要で、数値は重要ではありません。一致と見なすしきい値はありません。

  • 旅行の質問は地理であって視覚ではありません。 「3年前の日本旅行の写真を見つけて」という質問にCLIPに日本がどんな姿か問い合わせるべきではありません。photos_placesはGPSタグを0.5°グリッド(約55km)にクラスタリングし、各クラスタの座標と日付範囲を報告するため、Claudeは実際にいた場所を見つけ、その時間枠内のコンテンツで絞り込むことができます。ここで単純な国サイズの境界ボックスを使うのは本当に危険です。日本の矩形[24, 46, 123, 146]は韓国南東部も飲み込んでしまいます。

ビデオは正しい向きで保存されます。iPhoneは縦向きを1920×1080の横向きバッファと、libavがデコード時に適用しないディスプレイ行列回転として記録するため、indexer._upright()はframe.rotationを読み取り、埋め込み前に回転させます。


セキュリティモデル

これはHTTPポート上で写真ライブラリ全体といくつかのログイン済みアカウントを公開します。制御は意図的にシンプルで多層的です:

  • Tailnet限定。 open_firewall.ps1は、TailscaleのCGNATレンジである-RemoteAddress 100.64.0.0/10に制限されたTCP 8778のインバウンドルールを作成します。トラフィックがパブリックインターネットに触れることはありません。TailscaleによりWireGuardでエンドツーエンドに暗号化されています。

  • 共有ベアラートークン。 PWAシェル、/manifest.json、/healthを除くすべてのルートでconfig.jsonのトークンが必要です。hmac.compare_digestで比較されるため、チェックは定数時間です。

  • クエリ文字列にトークンを入れるのは意図的な妥協です。 <img src>はヘッダーを運べず、電話のショートカット操作ではヘッダーが扱いにくいためです。これはトラフィックがテイルネットから出ない場合にのみ許容されます。このポートを公開してはいけません。

  • パス制限。 アップロードされたすべてのファイル名はsafe_name()(ディレクトリコンポーネントとWindowsで不正な文字を除去しますが、Unicodeは保持するため、韓国語や絵文字のファイル名も残ります)に通され、解決された保存先がis_relative_to(VAULT)でチェックされてから書き込みます。

  • パスワードは決してログに記録されません。 /login/inputは転送する内容を明示的にフィルタリングし、login_sessionは入力されたテキストをブラウザに直接渡します。

  • 電話側のPWAはトークンをlocalStorageに保存するため、一度だけ入力すればよいです。


ジョブキュー

iOSではPCから電話を起こす方法がありません。そのためフローは逆転しています:

  1. Claudeがphone_request("location.current")を呼び出すと、jobsテーブルにステータスpendingの行が挿入され、即座にジョブIDが返されます。

  2. 電話はClaude Bridgeショートカットを実行します — タップ、PWAのボタン、またはスケジュールされた自動化から。/job/nextをGETし、これが1つのジョブを原子的にtakenにマークします。キューに何もない場合はサーバーは204を返し、ショートカットは終了します。

  3. ショートカットはaction名に応じて分岐し、データを収集して/records?job=<id>または/job/<id>/doneにPOSTします。

  4. Claudeがphone_job_statusをポーリングします。

takenとマークされたが完了しなかったジョブは、job_ttl_min分後にpendingに戻されます。実行中にショートカットが終了してもリクエストが失われません。

Claudeは黙ってポーリングするのではなく、ショートカットを実行するようユーザーに伝える必要があります — これはツールのdocstringに明記されています。


ケイパビリティプラグイン

ケイパビリティは、capabilities/内の単一のPythonファイルで、run(**kwargs) -> dictを公開します。モジュールのdocstringが仕様です — これがClaudeが呼び出すかどうかを判断するために読むもので、引数、戻り値の形状、ログインが必要かどうかを文書化します。

モジュールは毎回の呼び出しで再インポートされるため(importlib.util.spec_from_file_location + exec_module)、Claudeが30秒前に作成または編集したケイパビリティが即座に有効になります。MCPの再起動もサーバーの再起動も不要です。

欠けている統合が行き止まりにならないようにという意図があります。Claudeはマシン上でWriteとBashを持っています。capability_howtoを呼び出し、capabilities/<name>.pyを書き、実行します。書かれたものは永続化され蓄積されます。

リポジトリには2つ同梱されています。webpage.py(任意のURLを実ブラウザでレンダリングし、その可読テキストを返す。ログイン済みユーザーとしてオプションで実行)とnaver_mail.py(本格的な動作例 — APIを推測するのではなく、Webクライアント自身のJSON XHRを傍受します)。

作成方法

"""One line saying what this does - this line is what Claude sees in the list.

Args:
    since (str): 'YYYY-MM-DD'. Optional, defaults to 30 days ago.
    limit (int): max rows. Optional, default 20.

Returns:
    {"orders": [{"date","title","price","url"}], "count": int}

Notes:
    Requires a one-time manual login (PROFILE below).
"""

PROFILE = "example"                       # omit for capabilities needing no login
LOGIN_URL = "https://example.com/login"


def run(since: str = "", limit: int = 20) -> dict:
    from caps import browser

    with browser(PROFILE) as page:
        page.goto("https://example.com/orders", wait_until="domcontentloaded")
        if "login" in page.url:
            return {"error": "logged out",
                    "fix": f"call capability_login('{PROFILE}', '{LOGIN_URL}')"}
        rows = page.query_selector_all("li.order")
        if not rows:
            return {"error": "no rows matched 'li.order' - selector likely stale",
                    "url": page.url}
        ...

capabilities/_TEMPLATE.pyに完全な注釈版があります。capability_howtoがそのまま返すルール:

  • 常にcaps.browser(PROFILE)を使用します。 Playwrightを直接起動しないでください。

  • 大声で失敗します。 サイトリニューアル後の空のリストは「何もありません」と読まれ、ユーザーがそれに基づいて行動してしまいます。外したセレクタを指定して{"error": ...}を返します。

  • 支払い、注文確認、送金を自動化してはいけません。 収集、判断、画面準備を行い、最後のボタンは人間がタップします。

  • ログインを自動化してはいけません(下記)。

ログインは意図的に手動

サインインの自動化は2FAやキャプチャに敗れ、失敗の連続はあなた自身のアカウントをロックします。そのためサポートされていません。代わりに:

  1. Claudeがcapability_login(profile, login_url)を呼び出します。

  2. デフォルトではヘッドレスのChromiumがPC上で起動し、その画面が/loginで電話にミラーリングされます — JPEGフレームが約3fpsで送信され、タップとキー入力が返されます。PC画面には何も表示されないため、ゲームのフォーカスを奪うことはありません。ブリッジ経由で入力したくないアカウントにはon_pc=Trueを渡します。

  3. パスワードは自分で一度入力します。

  4. Cookieは永続化され、以降の実行で再利用されます。

永続化は「永続プロファイルを使う」よりも微妙です。Chromiumはコンテキストが閉じるとセッションCookie(有効期限のないもの)を破棄します。多くのサービス(例: NaverのNID_AUT / NID_SES)では、それらがログインそのものです。プロファイルディレクトリが完全に埋まっているように見えても、ログアウトされていることがあります。そのためcaps.browser()はオープン時にload_state()を、クローズ時にsave_state()を呼び出し、profiles/<service>/storage_state.json経由でCookieを往復させます。またlogin_sessionは、ログイン途中で電話が離れてしまった場合に備えて、約10秒ごとにスナップショットを取ります。

caps.launch_kwargs()はPlaywrightに同梱のChromiumよりもchannel="chrome"(実際にインストールされているChrome)を優先します。特にGoogleはサインイン時に同梱版をフラグするためです。


要件

  • Windows(コードはctypes.windllを使用してプロセス優先度とCREATE_NO_WINDOWを処理します)

  • Python 3.10+(X | Y型構文とPath.is_relative_toを使用)

  • PCと電話の両方に**Tailscale**がインストールされ、同じテイルネットに属していること

  • NVIDIA GPUはオプションですが、強く推奨されます。 CLIPはCPUでも動作します("device": "cpu"を設定)— ただし、最初のフルインデックスはかなり遅くなります。

  • iPhone。電話側はすべて組み込みのショートカットアプリとホーム画面のPWAで完結します。アプリのインストール、ペアリング、脱獄は不要です。

インストール

git clone <this repo>
cd mobile_claude_connect

# CUDA build of torch first, if you have an NVIDIA GPU:
pip install torch --index-url https://download.pytorch.org/whl/cu128

pip install -r requirements.txt

# Browser engine for the capability plugins. Separate step - pip does not do this.
playwright install chromium

Google Chromeがインストールされている場合、caps.launch_kwargs()は同梱のChromiumではなくそれ(channel="chrome")を使用し、playwright install chromiumはオプションになります。

設定

copy config.example.json config.json
python -c "import secrets; print(secrets.token_urlsafe(24))"

config.json を編集します:

  • token — 生成したシークレットを貼り付けます。スマートフォンにも同じ値を設定します。

  • vault_dir — スマートフォンからのアップロードが保存される絶対パス。

  • watch_dirs — その場で写真をスキャンするフォルダ(何もコピーされません)。これを iCloud for Windows ライブラリに指定します。例: C:\Users\YOUR_USERNAME\Pictures\iCloud Photos\Photos。

  • device — cuda または cpu。

config.json なしで実行すると、スタックトレースではなく手順を示すメッセージを表示して終了します。

ファイアウォール

# Run as Administrator
powershell -ExecutionPolicy Bypass -File open_firewall.ps1

これにより、TCP 8778 が 100.64.0.0/10 のみに開放され、スマートフォンで開く URL が表示されます。 .ps1 ファイルは ASCII のみにしてください — Windows PowerShell 5.1 はシステムの ANSI コードページで読み取るため、非 ASCII 文字は破損します。

実行

run_bridge.bat をダブルクリックします(または python server.py)。ウィンドウを閉じると ブリッジが停止し、停止中はスマートフォンからは何も動作しません。

ブリッジが起動している間、インデックスは自動的に維持されます: auto_index_minutes(デフォルト 15)ごとに サーバーは indexer.py を短命なサブプロセスとして起動するため、約 2 GB の CLIP VRAM は サーバーの稼働中ずっと保持されるのではなく、実行間で解放されます。アイドル時のパスは ファイルツリーの統計のみを行い、GPU には触れません。出力は autoindex.log に記録されます。

最初の一括インポートには、python backfill.py がソースフォルダの増加が止まるまでスキャンと埋め込みを繰り返します — iCloud が大規模なライブラリをまだダウンロードしている場合に便利です。自動インデックスと同時に実行しないでください。2 つの CLIP プロセスが VRAM を奪い合います。

MCP サーバーの登録

claude mcp add phone -s user -- python C:\path\to\mobile_claude_connect\mcp_server.py

注意: MCP サーバーはセッション開始時に読み込まれます。claude mcp add で追加したサーバーは 現在のセッションには表示されません。新しいセッションを開始してください。

スマートフォン側の設定 — PWA、一括写真インポート、ショートカットレシピ — は SETUP.md にあります。

使用方法

PC 上の Claude Code セッションから(スマートフォンから Claude アプリのリモートコントロールで操作している場合も含む):

Find the photos from my trip three years ago that show a pump machine.

動作の流れ: photos_stats でカバレッジを確認 → photos_places で実際にいた場所と時間を特定 → photos_search("a pump machine", date_from=..., date_to=...) で候補をランク付け → 上位ヒットに対して photos_open → Claude が JPEG を確認し、見た内容から回答します。CLIP が絞り込み、Claude が判断します。

韓国語(またはその他の非英語)のクエリは、検索前に短い英語のフレーズに翻訳されます。CLIP のテキストエンコーダーは英語のみ対応のためです。


含まれないもの

このリポジトリはコードのみです。実行中のインスタンスを有用にしていたものはすべて個人データであり、 ここには含まれません:

  • bridge.db — 写真インデックス。空のインデックスから始めます。watch_dirs を写真フォルダに指定し、python indexer.py を実行(または自動インデックスに任せる)して自分で構築します。 初回実行時に CLIP モデル(約 1.7 GB)をダウンロードします。

  • vault/ — アップロードされた写真、ビデオ、共有シートのドロップ。

  • preview/ — photos_open によってレンダリングされた JPEG。

  • profiles/ — Playwright ブラウザプロファイル、つまりログイン済みのライブセッション。各サービスに 自分で一度ログインします(capability_login を使用)。

  • config.json — ベアラートークンを保持します。config.example.json をコピーしてください。

これらはすべて .gitignore に含まれています。そのままにしておいてください。

既知の制限

  • 通話履歴と SMS は取得できません。 iOS はどちらに対しても、どのアプリにも API を公開していません。 ネイティブアプリでも解決できません。唯一の方法はローカルバックアップの抽出であり、それには lockdown ペアリングが必要です。

  • PC がオンである必要があります。 スマートフォンは画面であり、ピアではありません。

  • /login ミラーは約 3 fps の JPEG(1366×900)です — ログインフォームには十分ですが、ブラウジングには不向きです。

  • スマートフォン側の PWA UI は韓国語です(static/index.html、static/login.html)。サーバー、 MCP ツール、Claude が読み取るものはすべて英語です。

ライセンス

これはソースのみのリポジトリです。ここにあるコードは MIT ライセンスです — LICENSE を参照 — そして これがこのリポジトリが実際に配布する唯一のものです。その他はすべて、別の場所からあなたのマシンに届きます: pip install -r requirements.txt は PyPI からホイールを取得し、CLIP の重みは Hugging Face から、 ブラウザは playwright install から取得します。ここでサードパーティのバイナリが再配布されることはありません。 コピーレフトの義務は再配布に付随するため、通常のケース — クローンしてインストールし、自分の PC で実行する — では、以下で行う必要があることはほとんどなく、残りは、これを誰かに渡すパッケージにする日のために書き留められています。

ソースからの実行(ほとんどの人が行う方法)

遵守すべきことはありません。表にある寛容なライセンスは、依存関係からコードを自分のプロジェクトにコピーする場合に 通知を保持することだけを求めています。計画を立てる前に知っておくべきことが 2 つありますが、どちらもコピーレフトの問題ではありません。

CLIP の重みにはライセンスがなく、それは寛容であることと同じではありません。 これは、単に実行するだけで あなたが行うことに影響を与える可能性がある唯一の項目です。transformers ライブラリは Apache-2.0 ですが、 重みは別の条項を持つ別の成果物です。Hugging Face リポジトリ openai/clip-vit-large-patch14 には LICENSE ファイルがなく、モデルカードのメタデータにも license フィールドが宣言されていません。 上流の openai/CLIP コードリポジトリは MIT(© 2021 OpenAI)ですが、そのライセンス文はそのリポジトリのコードを 対象としており、チェックポイントについては何も述べていません。つまり: これらの重みの商用利用が許可されているかどうかは未確認です。 モデルカードも自身の立場を明確に述べています — 「モデルの展開されたユースケース(商用かどうかを問わず)は現在スコープ外」であり、 モデルは堅牢性と一般化に関する研究を目的としており、監視と顔認識は恒久的にスコープ外とされています。 これは著者の表明された意図であり、ライセンスの付与や禁止ではありませんが、これに基づいて製品を構築するかどうかを 決定する場合、彼らが述べた最も直接的なものです。clip_model を明示的なライセンスメタデータを持つモデル (オープンライセンスの CLIP バリアントがいくつか存在します)に交換することが、クリーンな解決策です。

サードパーティのサイトを自動化することは、そのサイトの利用規約に準拠します。このライセンスではありません。 機能プラグインはログイン済みのウェブセッションを操作します — naver_mail.py が同梱の例であり、 明らかな次のもの(Coupang Eats、Gmail)も同じ形です。自分が保有するアカウントをスクリプト化できるかどうかは、 そのサービスの利用規約と適用されるコンピュータアクセス法の問題です。このコードの MIT ライセンスはそこでは何も許可しません。 これと一緒に登録するサードパーティの MCP サーバーについても同様です: それ自体のライセンスとサービス利用規約があります。

依存関係のライセンス

スタックはほとんど寛容ですが、2 つのホイールにはコピーレフトのバイナリが含まれ、1 つはプロプライエタリな NVIDIA ライブラリを 同梱し、1 つのコンポーネントにはライセンスが一切宣言されていません。右列の「下記参照」はすべて再配布の義務であり、実行時の義務ではありません。

依存関係

ライセンス (SPDX)

あなたが負う義務

mcp (Model Context Protocol Python SDK)

MIT

通知を保持すること。

Flask、およびその Werkzeug / Jinja2 / Click / itsdangerous / MarkupSafe / Blinker チェーン

BSD-3-Clause(全体)、ただし Blinker は MIT

通知を保持すること。

waitress

ZPL-2.1

通知を保持すること。変更したファイルには変更した旨を明記すること(ZPL 第5条)。このライセンスは商標権を付与しない。

NumPy

BSD-3-Clause(ベンダリングされたコードの完全な表現は BSD-3-Clause AND 0BSD AND MIT AND Zlib AND CC0-1.0)

通知を保持すること。その wheel には OpenBLAS も同梱されており、Linux では libgfortran(GPL-3.0-or-later WITH GCC-exception-3.1。この例外があるおかげで、あなたのコードには影響が及ばない)と libquadmath(LGPL-2.1-or-later)も同梱される。

Pillow

MIT-CMU(HPND 形式の PIL ライセンス。SPDX ID は Pillow 11.0.0 で HPND から変更されたが、条文自体に変更はない。SBOM の許可リストがまだ HPND を想定している場合に知っておく価値がある)

通知を保持すること。

transformers、huggingface_hub、tokenizers、safetensors

Apache-2.0

通知と NOTICE ファイルを保持すること。Apache-2.0 はまた、重要な変更を明記することも求めている。

PyTorch

BSD-3-Clause — ただし CUDA wheel には NVIDIA の CUDA ランタイムと cuDNN も同梱されており、LicenseRef-NVIDIA-Proprietary と宣言されている

後述を参照。これらはプロプライエタリであり、BSD ではない。

pillow-heif

ソースは BSD-3-Clause だが、wheel には libheif と libde265(LGPL-3.0)、および x265(GPL-2.0) が同梱されている

後述を参照。PyPI はこの理由から、パッケージ自体を GPLv2 として分類している。

PyAV(av)

バインディングは BSD-3-Clause。wheel の FFmpeg コアは LGPL-3.0-or-later だが、wheel には x264 と x265(GPL-2.0-or-later) も同梱されている

後述を参照。

Playwright

Apache-2.0 — ただし x64 では、ダウンロードされるブラウザは オープンソースの Chromium ではない

後述を参照。

CLIP の重み、openai/clip-vit-large-patch14

ダウンロードする成果物にはライセンスが宣言されていない

前述を参照 — 唯一の真の未知数であり、実行時に問題となる唯一の項目。

バイナリをビルドして再配布する場合

これをインストーラ、Docker イメージ、その他他人に渡す成果物にパッケージングすることこそが、上記の強調表示された行を実際の作業に変えるものである。

PyAV の wheel は LGPL の FFmpeg と、その隣に置かれた GPL エンコーダで構成されており、その区別は見た目よりも微妙である。 FFmpeg はデフォルトでは LGPL-2.1-or-later であり、--enable-gpl 付きでビルドされると GPL になる。上流は x264 と x265 のためにこのフラグを要求している。PyAV の wheel は そのフラグなしで ビルドされている。同梱の avutil は libavutil license: LGPL version 3 or later と報告し、その configure 行は --enable-version3 --enable-libx264 --enable-libx265 を示しており、--enable-gpl は含まれない。これは PyAV が FFmpeg の configure にパッチを当て、libx264 と libx265 を GPL リストから version-3 リストへ移動させているため可能になっている。したがって FFmpeg コアは LGPL-3.0-or-later である — しかし x264 と x265 自体は GPL-2.0-or-later であり、av.libs/ には libx264-165.dll と libx265.dll として同梱されている。つまり pip install av は、FFmpeg コアが何と言おうと、依然として GPL コードを依存関係グラフに含めることになる。このプロジェクトは動画の長さ、回転、サンプルフレームを読み取るだけで、エンコーダには一切触れないため、再配布する場合の現実的な対処は、これら2つの DLL を削除するか、独自の FFmpeg に対して sdist からビルドする(pip install --no-binary av av)ことである。知っておく価値のある小さなギャップが2つある:wheel の licenses/ ディレクトリには PyAV 自身の BSD-3-Clause の条文のみが含まれ、FFmpeg、x264、x265 の通知は一切含まれていない。また、delvewheel は FFmpeg の DLL をハッシュ接尾辞付きにリネームするため、FFmpeg 自身のコンプライアンスチェックリストに反することになる。

pillow-heif は同じ構造に加え、特許の問題がある。 その Python コードは BSD-3-Clause だが、バイナリ wheel には LGPL-3.0 の libheif と libde265、および GPL-2.0 の x265 エンコーダが同梱されている — これが、宣言されたライセンス欄が BSD-3-Clause であるにもかかわらず、PyPI の分類子が「GNU General Public License v2」と読める理由である。このプロジェクトはスマートフォンからの HEIC を デコード するだけなので、GPL エンコーダが呼び出されることは決してないが、それでも wheel には含まれている。著作権とは別に、独立して:HEIC 内部のコーデックである HEVC/H.265 は特許プールの対象であり、その管理者は HEVC のエンコードまたはデコード機能を持つ製品は通常ライセンスを必要とすると述べている。これはソフトウェアライセンスの問題ではなく特許の問題であり、デコーダを商業的に出荷する製品を対象としている — 個人サーバーは対象ではない — だが、オープンソースライセンスが代わりに解決してくれるわけではない、現実の義務である。

Playwright は Apache-2.0 であり、x64 では取得されるブラウザはオープンソースの Chromium ではない。 Chromium 自身のソースは、大規模なサードパーティライセンス群(Blink は BSD/LGPL、Mozilla 由来のコードは MPL/GPL/LGPL、その他数百件が chrome://credits に集約されている)の上に成り立つ BSD-3-Clause である。しかし playwright install chromium は x64 ではもはやそれをダウンロードしない。Playwright の browsers.json はそのダウンロードを 「Chrome for Testing」 と名付けており、cdn.playwright.dev は Google 自身の chrome-for-testing-public バケットにリダイレクトする。その成果物は Google 製で Google ブランドであり、Widevine CDM を同梱している。そのライセンスは「オープンソースソフトウェアではない」と明記し、Google との別個の契約なしに配布してはならないとしている。linux-arm64 ビルドのみが、依然として Playwright 自身の素の Chromium である。Playwright の公開ドキュメントは依然としてデフォルトをオープンソースの Chromium と説明しているが、出荷されるコードはそうではないと述べている。別途、caps.launch_kwargs() は channel="chrome" を優先する — つまり、オープンソースライセンスではなく Google Chrome 利用規約に準拠する、ユーザーの実際にインストールされた Google Chrome である。再配布に関する結論:どちらも同梱しないこと。ユーザー自身にブラウザをインストールさせること。これはこのリポジトリがすでに行っていることである。未検証: Google が Chrome for Testing を一般消費者向け Chrome の利用規約から除外しているかどうか。

CUDA PyTorch ビルドは純粋な BSD ではない。 PyTorch 自体は BSD-3-Clause だが、この README のインストール手順が推奨する CUDA wheel — PyPI ではなく download.pytorch.org/whl/cu128 からのもの(PyPI の Windows wheel は CPU 専用)— には NVIDIA の CUDA ランタイムと cuDNN バイナリが同梱されている。インストールされた torch ...+cu128 を調べると、torch/lib に22個(cuBLAS、cuDNN、cuFFT、cuRAND、cuSOLVER、cuSPARSE など)が存在する。それらの wheel メタデータは LicenseRef-NVIDIA-Proprietary と宣言しており、CUDA EULA はランタイムの再配布を独自の条件でのみ許可している:アプリケーションは実質的な機能を追加しなければならず、バイナリは変更してはならず、アプリケーションからのみ到達可能でなければならず、SDK をオープンソースライセンスの対象となる方法で使用してはならない。cuDNN は、基本条項と矛盾する場合にそれを上書きする補足条項を追加している。そのどれも BSD ではない。ローカルでの実行はそのいずれにも影響されない。CPU 専用 wheel はこの問題を完全に回避する。

ここに記載されている内容は法的助言ではない。

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI services like Claude and Cursor to remotely control a Mac by executing shell commands, managing files, and running AppleScript for UI automation. Access is secured through OAuth 2.0 authentication and encrypted tunnels to protect remote interactions.
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to access and search local messages and contacts across multiple platforms (iMessage, Discord, Gmail, Slack) via a local-first datastore, ensuring data never leaves the Mac.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude or any MCP client to read Apple Mail, Calendar, Photos, and create Apple Notes locally on macOS, without any data leaving the machine.
    MIT