Skip to main content
Glama
riseblyp

mobile_claude_connect

by riseblyp

{"type": "text"}# mobile_claude_connect

Мост «телефон — ПК», который даёт сеансу Claude Code, работающему на вашем ПК, доступ к данным вашего iPhone — фото, видео, геолокации в реальном времени, контактам, календарю, буферу обмена — плюс систему плагинов, позволяющую Claude писать и запускать собственную автоматизацию браузера для веб-сервисов, где вы уже вошли в аккаунт.

Телефон — это только экран. Каждый байт остаётся на вашей собственной машине и передаётся через вашу собственную Tailscale сеть. Никакого облака, сторонних сервисов и загрузки куда-либо нет.

Три компонента:

Компонент

Что это такое

server.py

Приложение Flask + waitress на порту 8778. Обслуживает PWA на стороне телефона, принимает загрузку фото и отправку через «поделиться», а также запускает очередь заданий.

indexer.py

CLIP-эмбеддинги + семантический поиск по библиотеке фото/видео, хранящейся в SQLite.

mcp_server.py

MCP-сервер через stdio. Именно с ним на самом деле общается 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 — диапазон CGNAT Tailscale. Из публичного интернета ничего не доступно.


Related MCP server: whitelabel-fleet-mcp

Поверхность MCP-инструментов

Это инструменты, которые видит Claude Code после регистрации MCP-сервера.

Инструмент

Что делает

photos_stats

Размер индекса, диапазон дат, сколько элементов ещё не встроено, какие папки отслеживаются. Вызывайте это первым для любых вопросов, связанных с фото.

photos_search

Семантический поиск CLIP по фото и видео по короткой английской фразе, с фильтрацией по диапазону дат, ограничивающему прямоугольнику GPS и kind.

photos_by_date

Список ресурсов только по времени и/или месту, сначала новые, без ранжирования по содержимому.

photos_places

Грубые GPS-кластеры (~55 км) с количеством фото и первым/последним днём — «где я был и когда».

photos_open

Преобразует ресурсы в JPEG, которые Claude может реально посмотреть: HEIC уменьшается, видео превращается в контактный лист из 6 кадров.

index_update

Сканирует хранилище и отслеживаемые папки на наличие новых файлов, затем встраивает всё, что ещё не встроено.

phone_actions

Имена действий, которые умеет выполнять ярлык на телефоне.

phone_request

Ставит задание в очередь для телефона (текущее местоположение, контакты, календарь, буфер обмена, открыть deep link, уведомить).

phone_job_status

Результат поставленного в очередь задания телефона.

capability_list

Установленные плагины возможностей и выполнен ли вход в браузерный профиль каждого из них.

capability_howto

Контракт для написания новой возможности — возвращает capabilities/_TEMPLATE.py и правила.

capability_run

Запускает возможность по имени; args передаются напрямую в её run().

capability_login

Открывает одноразовый вход для человека: по умолчанию зеркалируется на телефон или открывается реальное окно на ПК.

records_query

Читает не-фото данные, отправленные телефоном: местоположение, контакты, календарь, буфер обмена, отправку через «поделиться».


Семантический поиск CLIP

Фото и видео встраиваются с помощью openai/clip-vit-large-patch14 (настраивается). Фото даёт одно встраивание изображения; видео сэмплируется по трём кадрам, распределённым по средним 70% клипа, а встраивания кадров усредняются, а затем повторно нормализуются. Каждый вектор нормализован по L2 как float32 и хранится в виде необработанного BLOB в SQLite, поэтому запрос — это одно numpy matmul по отфильтрованному по дате/гео набору кандидатов — десятки миллисекунд для десятков тысяч ресурсов.

Поиск выглядит так:

  1. Фильтрация по диапазону taken_at и/или ограничивающему прямоугольнику [lat_min, lat_max, lon_min, lon_max] в SQL.

  2. Встраивание текстового запроса на английском, matmul с матрицей кандидатов, сортировка по косинусному сходству, выбор верхних k.

  3. Возвращаются кандидаты, а не ответы — затем Claude вызывает photos_open и смотрит на них, прежде чем что-либо говорить.

Два замечания по дизайну, возникшие в результате активного использования:

  • Оценки относительны. Косинусное сходство для всего попадает примерно в диапазон 0,15–0,35. Важен ранг; число — нет. Не существует порога, при котором совпадение «является» совпадением.

  • Вопросы о поездках — это география, а не зрение. «Найди фотографии из моей поездки в Японию три года назад» не должно спрашивать CLIP, как выглядит Япония. photos_places кластеризует GPS-метки по сетке 0,5° (~55 км) и сообщает координаты и диапазон дат каждого кластера, так что 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 — диапазоном CGNAT Tailscale. Трафик никогда не выходит в публичный интернет; он зашифрован WireGuard от начала до конца через Tailscale.

  • Общий токен-носитель. Каждый маршрут, кроме оболочки PWA, /manifest.json и /health, требует токен из config.json, сравниваемый с помощью hmac.compare_digest, чтобы проверка была константной по времени.

  • Токен в строке запроса — осознанный компромисс. <img src> не может передавать заголовок, а действия Shortcuts на телефоне делают заголовки неудобными. Это приемлемо только потому, что трафик не покидает tailnet. Не открывайте этот порт публично.

  • Изоляция путей. Каждое загружаемое имя файла проходит через safe_name() (которая удаляет компоненты каталога и недопустимые для Windows символы, но сохраняет Unicode, поэтому имена файлов на корейском и с эмодзи выживают), а разрешённый путь назначения проверяется с помощью is_relative_to(VAULT) перед любой записью.

  • Пароли никогда не записываются в журнал. /login/input явно фильтрует то, что пересылает, а login_session передаёт введённый текст прямо в браузер.

  • PWA на телефоне хранит токен в localStorage, поэтому вы вводите его один раз.


Очередь заданий

В iOS нет способа разбудить телефон с ПК. Поэтому поток инвертирован:

  1. Claude вызывает phone_request("location.current"), который вставляет строку в jobs со статусом pending и немедленно возвращает идентификатор задания.

  2. Телефон запускает ярлык Claude Bridge — по нажатию, из кнопки PWA или по автоматизации по расписанию. Он выполняет GET на /job/next, который атомарно помечает одно задание как taken. Если в очереди ничего нет, сервер отвечает 204, и ярлык просто завершается.

  3. Ярлык переключается по имени action, собирает данные и отправляет их через POST на /records?job=<id> или /job/<id>/done.

  4. Claude опрашивает phone_job_status.

Задание, помеченное как taken, но не завершённое, возвращается в pending через job_ttl_min минут, так что ярлык, убитый на полпути, не теряет запрос.

Claude должен сказать вам запустить ярлык, а не молча опрашивать — это записано в docstring инструмента.


Плагины возможностей

Возможность — это один Python-файл в capabilities/, который предоставляет 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 (объёмный проработанный пример — он перехватывает собственные 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. По умолчанию на ПК запускается headless Chromium, и его экран зеркалируется на ваш телефон на /login — кадры JPEG со скоростью ~3 кадра в секунду, касания и нажатия клавиш отправляются обратно. На экране ПК ничего не появляется, поэтому он не может украсть фокус у игры. Передайте on_pc=True для аккаунтов, которые вы предпочли бы не вводить через мост.

  3. Вы сами вводите пароль один раз.

  4. Файлы cookie сохраняются, и все последующие запуски используют их повторно.

Устойчивость тоньше, чем «использовать постоянный профиль». Chromium отбрасывает сессионные файлы cookie — те, у которых нет срока действия, — при закрытии контекста, и для многих сервисов (например, Naver NID_AUT / NID_SES) именно они и есть вход. Каталог профиля может выглядеть полностью заполненным, но при этом быть вышедшим из системы. Поэтому caps.browser() вызывает load_state() при открытии и save_state() при закрытии, прогоняя файлы cookie через profiles/<service>/storage_state.json, а login_session делает их снимки каждые ~10 секунд на случай, если телефон отойдёт на середине входа.

caps.launch_kwargs() предпочитает channel="chrome" (ваш реальный установленный Chrome) встроенному Chromium Playwright, потому что Google, в частности, помечает встроенную сборку при входе в систему.


Требования

  • Windows (код использует ctypes.windll для приоритета процесса и CREATE_NO_WINDOW)

  • Python 3.10+ (используется синтаксис типов X | Y и Path.is_relative_to)

  • Tailscale на ПК и телефоне, в одной tailnet-сети

  • Наличие GPU NVIDIA необязательно, но настоятельно рекомендуется. 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() будет использовать его (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 для 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 ГБ VRAM для CLIP освобождаются между запусками, а не удерживаются всё время жизни сервера. Холостой проход только проверяет дерево файлов и не трогает 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.

Использование

Из сессии Claude Code на ПК (включая ту, которой вы управляете с телефона через Remote Control в приложении 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 ГБ.

  • vault/ — загруженные фотографии, видео и сбросы из шер-шита.

  • preview/ — JPEG, созданные photos_open.

  • profiles/ — профили браузера Playwright, т.е. живые сессии входа. Вы входите сами, один раз для каждого сервиса, через capability_login.

  • config.json — содержит bearer-токен. Скопируйте config.example.json.

Всё это находится в .gitignore. Оставьте их там.

Известные ограничения

  • История звонков и SMS не могут быть получены. iOS не предоставляет API для этого ни одному приложению. Нативное приложение не помогло бы; единственный путь — извлечение из локальной резервной копии, что требует lockdown-сопряжения.

  • ПК должен быть включён. Телефон — это экран, а не равноправный узел.

  • Зеркало /login — это ~3 кадра/с JPEG при 1366×900 — подходит для формы входа, но не для просмотра.

  • PWA-интерфейс на стороне телефона на корейском (static/index.html, static/login.html). Сервер, MCP-инструменты и всё, что читает Claude, — на английском.

Лицензия

Это репозиторий только с исходным кодом. Код здесь — MIT — см. LICENSE — и это единственное, что этот репозиторий фактически распространяет. Всё остальное попадает на ваш компьютер откуда-то ещё: pip install -r requirements.txt тянет колёса из PyPI, веса CLIP приходят с Hugging Face, а браузер — из playwright install. Никакие сторонние бинарники здесь не перераспространяются. Обязательства по копилефту привязаны к перераспределению, поэтому для обычного случая — клонировать, установить, запустить на своём ПК — почти ничего из нижеперечисленного делать не нужно, а остальное записано на тот день, когда вы упакуете это во что-то, что передадите другому.

Запуск из исходников (что делает почти каждый)

Соблюдать нечего. Разрешительные лицензии в таблице требуют только сохранения уведомлений, если вы копируете код из зависимости в свой проект. Две вещи всё же стоит знать, прежде чем строить планы, и ни одна из них не является вопросом копилефта.

Веса CLIP не имеют лицензии, и это не то же самое, что разрешительная лицензия. Это единственный пункт, который может повлиять на то, что вы делаете с этим, просто запуская его. Библиотека transformers — Apache-2.0, но веса — это отдельный артефакт с отдельными условиями. В репозитории Hugging Face openai/clip-vit-large-patch14 нет файла LICENSE и не объявлено поле license в метаданных карточки модели. Исходный репозиторий openai/CLIP — MIT (© 2021 OpenAI), но этот текст лицензии покрывает код в этом репозитории и ничего не говорит о контрольных точках. Итак: разрешено ли коммерческое использование этих весов — не подтверждено. Карточка модели также прямо заявляет свою позицию: «Любой случай использования модели в продакшене — коммерческий или нет — в настоящее время выходит за рамки», при этом модель предназначена для исследований в области устойчивости и обобщения, а слежка и распознавание лиц названы навсегда вне области применения. Это заявленное намерение авторов, а не лицензионное разрешение или запрет, но если вы решаете, строить ли продукт на этом, это самое прямое, что они сказали. Замена clip_model на модель с явными лицензионными метаданными (существует несколько открыто лицензированных вариантов CLIP) — чистый выход.

Автоматизация стороннего сайта регулируется условиями этого сайта, а не этой лицензией. Плагины capability управляют веб-сессиями с входом — naver_mail.py — поставляемый пример, а очевидные следующие (Coupang Eats, Gmail) имеют ту же форму. Можно ли скриптовать вашу собственную учётную запись — вопрос к условиям использования этого сервиса и применимому законодательству о компьютерном доступе; лицензия MIT на этот код не даёт вам здесь ничего. То же касается любого стороннего MCP-сервера, который вы регистрируете вместе с этим: он несёт свою собственную лицензию и свои условия обслуживания.

Лицензии зависимостей

Стек в основном разрешительный, но два колеса содержат копилефт-бинарники, одно — проприетарные библиотеки NVIDIA, а один компонент вообще не имеет объявленной лицензии. Каждое «см. ниже» в правой колонке — это обязательство при перераспределении, а не при запуске.

Зависимость

Лицензия (SPDX)

Что она обязывает вас делать

mcp (Python SDK для Model Context Protocol)

MIT

Сохраняйте уведомление.

Flask и его цепочка Werkzeug / Jinja2 / Click / itsdangerous / MarkupSafe / Blinker

везде BSD-3-Clause, кроме Blinker — MIT

Сохраняйте уведомление.

waitress

ZPL-2.1

Сохраняйте уведомление; помечайте любые файлы, которые вы изменяете, как изменённые (пункт 5 ZPL); лицензия не предоставляет прав на товарные знаки.

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 (лицензия PIL в стиле HPND; идентификатор SPDX изменился с HPND в Pillow 11.0.0 без изменения текста — полезно знать, если список разрешённых SBOM всё ещё ожидает HPND)

Сохраняйте уведомление.

transformers, huggingface_hub, tokenizers, safetensors

Apache-2.0

Сохраняйте уведомление и файл NOTICE; Apache-2.0 также просит указывать существенные изменения.

PyTorch

BSD-3-Clause — но CUDA-wheel также включает среду выполнения CUDA и cuDNN от NVIDIA, объявленные как 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; ядро FFmpeg в wheel-файле — 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-образ или любой другой артефакт, который вы передаёте кому-то ещё, — вот что превращает отмеченные выше строки в работу.

Wheel-файл PyAV — это LGPL FFmpeg с лежащими рядом GPL-кодировщиками — различие тоньше, чем кажется. FFmpeg по умолчанию имеет лицензию LGPL-2.1-or-later и становится GPL при сборке с --enable-gpl, который апстрим требует для x264 и x265. Wheel-файлы PyAV не собраны с этим флагом: встроенный avutil сообщает libavutil license: LGPL version 3 or later, а его строка configure показывает --enable-version3 --enable-libx264 --enable-libx265 без --enable-gpl. Это возможно потому, что PyAV пропатчивает configure FFmpeg, перемещая libx264 и libx265 из списка GPL в список версии 3. Поэтому ядро FFmpeg — LGPL-3.0-or-later, но сами x264 и x265 — GPL-2.0-or-later, и av.libs/ поставляет их как libx264-165.dll и libx265.dll. Так что pip install av всё равно помещает GPL-код в ваш граф зависимостей, что бы ни говорило ядро FFmpeg. Этот проект только читает длительность видео, поворот и отдельные кадры и никогда не обращается к кодировщику, поэтому практическое решение при распространении — удалить эти две DLL или собрать из sdist (pip install --no-binary av av) с собственным FFmpeg. Ещё два небольших пробела, о которых стоит знать: каталог licenses/ в wheel-файле содержит только собственный текст BSD-3-Clause от PyAV и ни одного уведомления FFmpeg, x264 или x265, а delvewheel переименовывает DLL FFmpeg, добавляя хэш-суффиксы, что противоречит собственному контрольному списку соответствия FFmpeg.

pillow-heif имеет ту же форму, плюс патентный вопрос. Его Python-код имеет лицензию BSD-3-Clause, но двоичный wheel-файл включает libheif и libde265 под LGPL-3.0 и кодировщик x265 под GPL-2.0 — именно поэтому его классификатор PyPI гласит «GNU General Public License v2», хотя в поле объявленной лицензии указано BSD-3-Clause. Этот проект только декодирует HEIC с телефона, так что GPL-кодировщик никогда не вызывается, но он всё равно находится в wheel-файле. Отдельно и независимо от авторского права: HEVC/H.265, кодек внутри HEIC, покрыт патентными пулами, администраторы которых заявляют, что продуктам с функциональностью кодирования или декодирования HEVC обычно нужна лицензия. Это патентный вопрос, а не вопрос лицензии на ПО, и он нацелен на продукты, которые коммерчески поставляют декодеры, — личный сервер не является целью, — но это реальное обязательство, которое никакая лицензия с открытым исходным кодом за вас не решает.

Playwright имеет лицензию Apache-2.0, и на x64 загружаемый им браузер — не открытый Chromium. Собственный исходный код Chromium — BSD-3-Clause поверх большого набора сторонних лицензий (Blink под BSD/LGPL, код, производный от Mozilla, под MPL/GPL/LGPL, и ещё несколько сотен, собранных на chrome://credits). Но playwright install chromium больше не загружает это на x64. browsers.json в Playwright называет загрузку «Chrome for Testing», а cdn.playwright.dev перенаправляет на собственный бакет Google chrome-for-testing-public. Артефакт собран и брендирован Google и включает Widevine CDM, лицензия которого прямо гласит, что он «не является программным обеспечением с открытым исходным кодом» и не может распространяться без отдельного соглашения с Google. Только сборка linux-arm64 по-прежнему является собственным обычным Chromium от Playwright. Публичная документация Playwright всё ещё описывает вариант по умолчанию как открытый Chromium; поставляемый код говорит об обратном. Отдельно caps.launch_kwargs() предпочитает channel="chrome" — ваш реально установленный Google Chrome, регулируемый Условиями предоставления услуг Google Chrome, а не какой-либо лицензией с открытым исходным кодом. Итог для распространения: не включайте ни то, ни другое. Пусть пользователь сам установит свой браузер — этот репозиторий уже так и делает. Не проверено: освобождает ли Google Chrome for Testing от потребительских условий Chrome.

Сборка PyTorch с CUDA — не чисто BSD. Сам PyTorch имеет лицензию BSD-3-Clause, но CUDA-wheel, который рекомендует шаг установки в этом README, — тот, что с download.pytorch.org/whl/cu128, а не с PyPI, чей Windows-wheel содержит только CPU, — поставляет двоичные файлы среды выполнения CUDA и cuDNN от NVIDIA. При проверке установленного torch ...+cu128 в torch/lib обнаруживается 22 таких файла (cuBLAS, cuDNN, cuFFT, cuRAND, cuSOLVER, cuSPARSE и другие). Метаданные их wheel-файлов объявляют LicenseRef-NVIDIA-Proprietary, а EULA CUDA разрешает распространение среды выполнения только на своих условиях: ваше приложение должно добавлять существенную функциональность, двоичные файлы не должны изменяться, они должны быть доступны только вашему приложению, и вы не можете использовать SDK способом, который подчинил бы его лицензии с открытым исходным кодом. cuDNN добавляет дополнение, которое отменяет базовые условия в случае конфликта. Ничто из этого не BSD. Локальный запуск не затрагивается ничем из этого; wheel только с CPU полностью обходит этот вопрос.

Ничто здесь не является юридической консультацией.

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