Skip to main content
Glama
riseblyp

mobile_claude_connect

by riseblyp

mobile_claude_connect

一个手机到 PC 的桥接工具,让在你 PC 上运行的 Claude Code 会话能够访问你iPhone 的数据——照片、视频、实时位置、通讯录、日历、剪贴板——此外还有一个插件系统,让 Claude 可以编写并运行自己的浏览器自动化操作,针对已登录的 Web 服务。

手机只是一块屏幕。每一个字节都保留在你自己的机器上,并通过你自己的 Tailscale tailnet 传输。没有任何云端组件,没有第三方服务,也不会向任何地方上传任何内容。

三个部分:

组件

说明

server.py

运行在端口 8778 上的 Flask + waitress 应用。提供手机端 PWA,接受照片上传和共享表单(Share Sheet)投递的内容,并运行任务队列。

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 聚类(约 55 km),包含照片数量和首末日——“我在哪里,以及是什么时候”。

photos_open

将资产渲染成 Claude 真正能看的 JPEG:HEIC 会被缩小,视频会变成一张 6 帧的缩略图条(contact sheet)。

index_update

扫描 vault 和监视的文件夹以查找新文件,然后嵌入所有尚未嵌入的内容。

phone_actions

手机端 Shortcut 知道如何执行的操作名称。

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(可配置)进行嵌入。一张照片贡献一个图像嵌入;一个视频则在片段中间 70% 的范围内均匀采样三帧,这些帧的嵌入会被平均,然后重新归一化。每个向量都是经过 L2 归一化的 float32,并以原始 BLOB 形式存储在 SQLite 中,因此一次查询就是在按日期/地理位置过滤后的候选集上做一次 numpy matmul——在数万个资产上只需几十毫秒。

一次搜索的流程是:

  1. 在 SQL 中按 taken_at 范围和/或 [lat_min, lat_max, lon_min, lon_max] 边界框进行过滤。

  2. 对英文文本查询进行嵌入,与候选矩阵做 matmul,按余弦相似度排序,取前 k 个。

  3. 返回候选结果,而不是答案——Claude 随后会调用 photos_open,在说任何话之前查看这些结果。

以下是实际使用中总结出的两条设计说明:

  • 分数是相对的。 所有内容的余弦相似度大致落在 0.15–0.35 之间。排名重要,数字不重要。不存在一个阈值,一旦超过就能说某条命中“是”匹配。

  • 旅行类问题是地理问题,不是视觉问题。 “找到我三年前日本之旅的照片”不应该让 CLIP 判断日本长什么样。photos_places 将 GPS 标签聚类到 0.5° 网格(约 55 km)上,并报告每个聚类的坐标和日期跨度,因此 Claude 能找到你实际所在的地方,然后在该窗口内按内容缩小范围。在这里,一个粗糙的国家级边界框确实很危险:一个覆盖日本的矩形 [24, 46, 123, 146] 也会把韩国东南部吞进去。

视频会按正立方向保存:iPhone 拍摄竖屏视频时,会以 1920×1080 的横屏缓冲区外加一个显示矩阵旋转来记录,而 libav 在解码时不会应用这个旋转,因此 indexer._upright() 会读取 frame.rotation 并在嵌入前进行旋转。


安全模型

这会在一个 HTTP 端口上暴露你的整个照片库和几个已登录的账户。控制措施刻意保持简单,并且是分层的:

  • 仅限 Tailnet。 open_firewall.ps1 创建一条 TCP 8778 入站规则,限制为 -RemoteAddress 100.64.0.0/10,即 Tailscale 的 CGNAT 网段。流量永远不会触及公共互联网;它由 Tailscale 进行端到端的 WireGuard 加密。

  • 共享的 Bearer 令牌。 除 PWA 外壳、/manifest.json 和 /health 之外,每条路由都需要来自 config.json 的令牌,并使用 hmac.compare_digest 进行比较,因此检查是常数时间的。

  • 把令牌放在查询字符串中是刻意的妥协。 <img src> 无法携带请求头,而手机的 Shortcuts 操作使用请求头也很别扭。这之所以可以接受,仅仅是因为流量永远不会离开 tailnet。不要公开暴露此端口。

  • 路径隔离(Path containment)。 每个上传的文件名都会经过 safe_name()(它会去掉目录组成部分和 Windows 非法字符,但保留 Unicode,因此韩文和 emoji 文件名都能存活),并且在写入任何内容之前,会用 is_relative_to(VAULT) 检查解析后的目标路径。

  • 密码永远不会被记录。 /login/input 会显式过滤它转发的内容,而 login_session 会将键入的文本直接传给浏览器。

  • 手机端 PWA 将令牌存储在 localStorage 中,因此你只需输入一次。


任务队列

iOS 没有提供让 PC 唤醒手机的方式。因此流程是反向的:

  1. Claude 调用 phone_request("location.current"),这会向 jobs 表中插入一行状态为 pending 的记录,并立即返回一个任务 id。

  2. 手机运行 Claude Bridge Shortcut——通过点按、PWA 的按钮或定时自动化来触发。它会 GET /job/next,该端点会原子性地将一个任务标记为 taken。如果队列中没有任何任务,服务器返回 204,Shortcut 直接退出。

  3. Shortcut 根据 action 名称进行分支,收集数据,然后将其 POST 到 /records?job=<id> 或 /job/<id>/done。

  4. Claude 轮询 phone_job_status。

被标记为 taken 但从未完成的任务会在 job_ttl_min 分钟后回到 pending 状态,因此一个在运行中途被终止的 Shortcut 不会丢失请求。

Claude 必须告诉你运行 Shortcut,而不是默默地轮询——这一点已经写进了该工具的 docstring 中。


能力插件

一个能力就是 capabilities/ 目录下的一个 Python 文件,它暴露了 run(**kwargs) -> dict。它的模块 docstring 就是规范——Claude 读取它来决定是否调用该能力,因此其中会记录参数、返回结构,以及是否需要登录。

模块在每次调用时都会重新导入(importlib.util.spec_from_file_location + exec_module),因此 Claude 三十秒前编写或编辑过的能力会立即生效。无需重启 MCP,也无需重启服务器。

这样设计的意图是:缺失的集成不是死胡同。Claude 在这台机器上拥有 Write 和 Bash:它可以调用 capability_howto,编写 capabilities/<name>.py,然后运行它。它编写的内容会持久保存并不断积累。

仓库自带两个能力:webpage.py(在真实浏览器中渲染任意 URL,并返回其可读文本,可选地以已登录用户身份运行)和 naver_mail.py(一个内容充实的完整示例——它拦截 Web 客户端自身的 JSON XHR,而不是去猜测某个 API)。

编写一个能力

"""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. 默认情况下,PC 上会启动一个无头(headless) Chromium,其屏幕会镜像到你的手机,地址为 /login——以约 3 fps 的帧率输出 JPEG 帧,点按和按键会回传。PC 屏幕上不会出现任何内容,因此不会从游戏中抢走焦点。对于你不想通过这条桥接输入密码的账户,请传入 on_pc=True。

  3. 你自己输入一次密码。

  4. Cookie 会持久保存,之后每次运行都会复用它们。

这种持久化比“使用持久化配置文件”更微妙。Chromium 在上下文关闭时会丢弃会话 cookie——也就是那些没有过期时间的 cookie,而对许多服务(例如 Naver 的 NID_AUT / NID_SES)来说,这些 cookie 就是登录状态。一个配置文件目录可能看起来内容齐全,却仍然处于未登录状态。因此 caps.browser() 在打开时调用 load_state(),在关闭时调用 save_state(),让 cookie 通过 profiles/<service>/storage_state.json 往返保存;login_session 则每隔约 10 秒对它们做一次快照,以防手机在登录中途断连。

caps.launch_kwargs() 更倾向于使用 channel="chrome"(你实际安装的 Chrome),而不是 Playwright 自带的 Chromium,因为 Google 在登录时尤其会对自带构建发出警告。


环境要求

  • Windows(代码使用 ctypes.windll 设置进程优先级,并使用 CREATE_NO_WINDOW)

  • Python 3.10+(使用 X | Y 类型语法和 Path.is_relative_to)

  • 在 PC 和手机上都安装 Tailscale,并处于同一个 tailnet 中

  • NVIDIA GPU 是可选的,但强烈推荐。 CLIP 可以在 CPU 上运行(设置 "device": "cpu")——只是首次完整索引时会慢得多。

  • 一部 iPhone。手机端的一切就是内置的 Shortcuts App 加一个主屏幕 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() 会优先使用它(channel="chrome"),而不是自带的 Chromium,这样 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

这仅向 100.64.0.0/10 开放 TCP 8778,并打印要在手机上打开的 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 仍在下载大型图库时非常有用。不要与自动索引同时运行它;两个 CLIP 进程会争夺 VRAM。

注册 MCP 服务器

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

注意: MCP 服务器在会话启动时加载。通过 claude mcp add 添加的服务器不会出现在你当前所在的会话中。请启动一个新会话。

手机端设置——PWA、批量照片导入和 Shortcut 配方——见 SETUP.md。

使用方式

在 PC 上的 Claude Code 会话中(包括你通过 Claude 应用的 Remote Control 从手机驱动的会话):

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 — 保存 bearer token。复制 config.example.json。

所有这些都在 .gitignore 中。请保持它们在那里。

已知限制

  • 通话记录和短信无法获取。 iOS 不向任何应用公开这两者的 API。原生应用也无济于事;唯一途径是本地备份提取,这需要 lockdown 配对。

  • PC 必须处于开启状态。 手机只是一块屏幕,而不是对等节点。

  • /login 镜像约为 1366×900 的 3 fps JPEG——适合登录表单,不适合浏览。

  • 手机端 PWA 界面是韩语的(static/index.html、static/login.html)。服务器、MCP 工具以及 Claude 读取的所有内容都是英语的。

许可证

这是一个仅包含源代码的仓库。这里的代码采用 MIT 许可证——见 LICENSE——这也是本仓库实际分发的唯一内容。其他一切都会从别处到达你的机器:pip install -r requirements.txt 从 PyPI 拉取 wheel 包,CLIP 权重来自 Hugging Face,浏览器来自 playwright install。这里不重新分发任何第三方二进制文件。Copyleft 义务与再分发相关,因此对于普通情况——克隆、安装、在自己的 PC 上运行——下面几乎没有任何你需要做的事情,其余内容则是为将来你把这个打包成交给别人的东西而写下的。

从源码运行(几乎所有人都是这样)

无需遵守任何事项。表格中的宽松许可证只要求:如果你从某个依赖中复制代码到自己的项目,版权声明需要保留。在制定计划之前,仍有两点值得了解,而它们都不是 copyleft 问题。

CLIP 权重没有许可证,这并不等同于宽松许可。 这是这里唯一会在你仅仅运行它时就影响你如何使用它的项目。transformers 库是 Apache-2.0,但权重是带有独立条款的独立工件。Hugging Face 仓库 openai/clip-vit-large-patch14 不包含 LICENSE 文件,也没有在其模型卡元数据中声明 license 字段。上游 openai/CLIP 代码仓库是 MIT(© 2021 OpenAI),但该许可证文本涵盖的是该仓库中的代码,对检查点只字未提。因此:这些权重是否允许商业使用尚未验证。 模型卡也明确陈述了自己的立场——“模型的任何部署用例——无论商业与否——目前都不在范围内”,并表明该模型旨在用于鲁棒性和泛化研究,且监控和人脸识别被列为永久超出范围。这是作者声明的意图,而非许可证授予或禁止,但如果你正在决定是否基于此构建产品,这是他们说过的最直接的话。将 clip_model 换成一个具有明确许可证元数据的模型(存在多个开放许可的 CLIP 变体)是干净的出路。

自动化第三方网站受该网站条款的约束,而非本许可证。 能力插件驱动已登录的 Web 会话——naver_mail.py 是随附示例,显而易见的后续插件(Coupang Eats、Gmail)也是同样的形态。你是否可以编写脚本操作自己持有的账户,取决于该服务的服务条款和任何适用的计算机访问法律;本代码的 MIT 许可证在这方面不授予你任何权利。任何你同时注册的第三方 MCP 服务器也是如此:它带有自己的许可证和自己的服务条款。

依赖许可证

技术栈大多是宽松许可的,但其中两个 wheel 包带有 copyleft 二进制文件,一个带有专有 NVIDIA 库,还有一个组件完全没有声明许可证。右栏中每一处“见下文”都是再分发义务,而非运行时义务。

依赖项

许可证 (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 标识在 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 的形式提供它们。所以无论 FFmpeg 核心怎么说,pip install av 仍然会把 GPL 代码放进你的依赖图中。本项目只读取视频时长、旋转角度和采样帧,从不触碰编码器,因此如果你要再分发,实际的做法是去掉这两个 DLL,或从 sdist(pip install --no-binary av av)针对你自己的 FFmpeg 构建。还有两个较小的缺口值得了解: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 编码器——这就是为什么它的 PyPI 分类器显示为 "GNU General Public License v2",尽管其声明的许可证字段写的是 BSD-3-Clause。本项目只解码手机传来的 HEIC,因此 GPL 编码器永远不会被调用,但它仍然在 wheel 中。与版权无关的另一件事:HEIC 内部的编解码器 HEVC/H.265 受专利池保护,其管理者声明,具有 HEVC 编码或解码功能的产品通常需要许可证。这是专利问题,不是软件许可证问题,其针对的是商业性提供解码器的产品——个人服务器不是目标——但这是一项真实义务,没有任何开源许可证能替你解决。

Playwright 是 Apache-2.0,在 x64 上它获取的浏览器不是开源 Chromium。 Chromium 自身的源码是 BSD-3-Clause,其上还有一大套第三方许可证(Blink 为 BSD/LGPL,Mozilla 衍生代码为 MPL/GPL/LGPL,以及另外数百个,汇总在 chrome://credits)。但在 x64 上,playwright install chromium 不再下载那个。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——来自 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