Skip to main content
Glama

mcp-qmedia

Самописный MCP-сервер, который позволяет текстовым агентам задавать вопросы о медиа — изображениях, аудио, видео. Агент передаёт пути к файлам (или URL) и вопрос; сервер отправляет их на Xiaomi MiMo-V2.5 (изначально омнимодальная: текст/изображение/аудио/видео на вход, текст на выход) через конечные точки OpenCode Zen и возвращает ответ в виде текста. Используется как из opencode, так и из Claude Code.

Провайдеры

Один и тот же код для всех (совместимый с OpenAI /chat/completions, части контента в base64). Два встроены; можно добавлять, удалять и менять провайдера по умолчанию в веб-интерфейсе (ниже) — или редактируя хранилище ~/.config/mcp-qmedia/providers.json (0600, вне репозитория; может содержать ключи). Для каждого вызова: backend="<name>"; QMEDIA_BACKEND переопределяет сохранённое значение по умолчанию.

провайдер

конечная точка

модель

стоимость/ограничения

запись ключа в opencode's auth.json

mimo-v2.5 - opencode go (по умолчанию)

https://opencode.ai/zen/go/v1

mimo-v2.5

~$0.14/М на вход, 1М контекст

opencode-go

mimo-v2.5-free - opencode zen

https://opencode.ai/zen/v1

mimo-v2.5-free

бесплатно, 200k контекст, ограничение по частоте (429 FreeUsageLimitError при исчерпании)

opencode

Related MCP server: Vision MCP Server

Ключи API — никогда в этом репозитории

Для каждого провайдера порядок разрешения: собственный ключ провайдера в хранилище (устанавливается через UI) → QMEDIA_API_KEY → OPENCODE_API_KEY → ~/.local/share/opencode/auth.json (QMEDIA_AUTH_JSON): auth_entry провайдера, затем любая другая запись с ключом. Поэтому если вы вошли в opencode go / zen (opencode auth login), настраивать ничего не нужно. deploy/env.example содержит только несекретные настройки; хранилище записывается с правами 0600 и находится в ~/.config, а не в каком-либо репозитории.

Мастер настройки + пробник (по запросу, не демон)

mcp-qmedia ui (= server.py ui [port]) обслуживает http://127.0.0.1:8938 пока работает — запустите, настройте, закройте (как мастер настройки mcp-imap): список провайдеров (отмечен по умолчанию, статус ключа + откуда берётся ключ — сам ключ никогда не отправляется в браузер), добавить/изменить/удалить (встроенные можно сбросить, но не удалить), сделать по умолчанию, и панель пробника: вставьте http(s) URL или локальные пути (по одному на строку), вопрос (пусто = подсказка describe), выберите провайдера, Спросить — ответ + время + история на странице. JSON API за ним: GET/POST /api/providers, DELETE /api/providers/<name>, POST /api/default, POST /api/ask {files, question, provider}, и GET /api/status (CORS *, той же формы, что статус демонов обмена сообщениями — страница хаба (ai-agent-setup mcp-hub.service, http://127.0.0.1:8930/) опрашивает его; тот же набор полей, что у демонов — но qmedia не демон и не имеет карточки хаба; он отображается в карточке Bridge хаба). Страница ссылается на "Все демоны ↗" (http://127.0.0.1:8930/); сама страница — web/page.html. MCP-сервер читает то же хранилище при каждом вызове, поэтому изменения применяются немедленно без перезапуска.

Инструменты (префикс qmedia_ в opencode, mcp__qmedia__ в Claude Code)

  • ask(files, question, backend="", system="") — основной инструмент. files — список абсолютных локальных путей (~/… допустимо; сервер — общий демон, его рабочая директория не является вашим проектом) или http(s):// URL; несколько файлов в одном вызове, чтобы модель могла их сопоставить. Возвращает короткий заголовок ([mimo-v2.5 - opencode go/mimo-v2.5 · 2 file(s) · 8.8s] + тип/размер каждого файла) и ответ.

  • describe(files, backend="") — вопрос не нужен: подробное описание; изображения включают весь видимый текст дословно, аудио — дословная расшифровка, видео — покадрово с временными метками + расшифровка.

  • backends() — провайдеры: конечные точки, модели, какой по умолчанию, разрешается ли ключ для каждого (ключ никогда не выводится), наличие ffmpeg, ограничения, путь к хранилищу.

Разрешения: все три инструмента только для чтения и дешёвые → allow в обоих агентах. Примечание: ask/describe загружают указанные файлы на настроенного провайдера (для провайдера по умолчанию это платный API) — wildcard в списке разрешённых означает, что агент может делать это без запроса, включая режим планирования; оставьте по умолчанию бесплатного провайдера, если это для вас важно.

Обработка медиа

тип

отправляется как

примечания

изображение (png/jpg/gif/webp/heic/avif…)

image_url data URI

> QMEDIA_MAX_BYTES → уменьшено до ≤2000 px jpeg через ffmpeg

аудио (wav/mp3 напрямую; m4a/ogg/opus/flac/… перекодировано)

input_audio {data, format}

не wav/mp3 или превышает размер → mp3 моно 16 кГц 48 кбит/с через ffmpeg

видео (mp4/webm напрямую; mov/mkv/avi/… перекодировано)

video_url data URI + input_audio звуковой дорожки

конечная точка смотрит только на кадры video_url, поэтому аудиодорожка извлекается (ffprobe/ffmpeg) и отправляется как вторая часть; превышение размера/другие контейнеры → 480p/15 кадров/с h264

всё остальное (pdf, docx…)

—

ошибка с перечислением поддерживаемого

Определение типа: таблица расширений → mimetypes → HTTP Content-Type → магические байты. ffmpeg необязателен, но настоятельно рекомендуется (dnf install ffmpeg); без него работают только файлы, не требующие перекодирования.

Проверено 2026-08-17 на mimo-v2.5 - opencode go: OCR изображения, транскрипция wav (образец espeak), 3-секундный mp4 с сигналом (кадры + звуковая дорожка), и изображение+аудио в одном вызове.

Настройка

Структура: server.py (stdio MCP-сервер + режим мастера ui), web/page.html (страница мастера), deploy/bin/mcp-qmedia (запускатель), deploy/env.example (необязательные несекретные настройки). Нет systemd-юнита: на одной машине с несколькими сессиями агентов запустите один раз через mcp-proxy (ai-agent-setup's mcp-bridge.service) или позвольте каждому клиенту запускать его. Подключите с помощью симлинков, чтобы git pull обновлял машину.

git clone git@github.com:spookysys/mcp-qmedia.git ~/.local/src/mcp-qmedia
cd ~/.local/src/mcp-qmedia
uv venv .venv --python 3.14 && uv pip install --python .venv/bin/python 'mcp>=1.9,<2' httpx
ln -s "$PWD/deploy/bin/mcp-qmedia" ~/.local/bin/          # launcher
# setup: mcp-qmedia ui   -> http://127.0.0.1:8938 (close it when done)
# optional: mkdir -p ~/.config/mcp-qmedia && cp deploy/env.example ~/.config/mcp-qmedia/env

opencode (opencode.jsonc):

"qmedia": { "type": "local", "command": ["/home/YOU/.local/bin/mcp-qmedia"], "enabled": true }
// or, shared through mcp-bridge: { "type": "remote", "url": "http://127.0.0.1:8939/servers/qmedia/sse" }
// permission: "qmedia_*": "allow"

Claude Code (user scope):

claude mcp add -s user qmedia --transport stdio -- ~/.local/bin/mcp-qmedia
# or, shared through mcp-bridge: claude mcp add -s user qmedia --transport sse http://127.0.0.1:8939/servers/qmedia/sse
# settings.json permissions.allow: "mcp__qmedia__*"

Переменные окружения

переменная

по умолчанию

значение

QMEDIA_BACKEND

по умолчанию в хранилище (mimo-v2.5 - opencode go)

переопределение провайдера по умолчанию; неизвестное имя — ошибка (никогда не происходит тихого отката к платному встроенному)

QMEDIA_STORE

~/.config/mcp-qmedia/providers.json

хранилище провайдеров (0600, может содержать ключи)

QMEDIA_UI_PORT

8938

порт мастера настройки по запросу (mcp-qmedia ui, 127.0.0.1)

QMEDIA_API_KEY, OPENCODE_API_KEY

—

переопределение ключа для провайдеров без сохранённого ключа (иначе собственный auth_entry провайдера в opencode's auth.json — никогда ключ другой записи)

QMEDIA_AUTH_JSON

~/.local/share/opencode/auth.json

где opencode хранит ключи провайдеров

QMEDIA_MAX_BYTES

20000000

предел на файл перед перекодированием ffmpeg

QMEDIA_TIMEOUT

300

тайм-аут вызова модели, секунды

MCP_QMEDIA_PYTHON

.venv/bin/python в рабочей копии

запускатель: переопределение интерпретатора

MCP_QMEDIA_ENV

~/.config/mcp-qmedia/env

запускатель: файл настроек для source (необязательно)

MCP_QMEDIA_DIR

рабочая копия

systemd-юнит: где находится server.py

Related MCP Connectors

Related MCP Servers