Skip to main content
Glama

🖼️ vision-mcp

Самостоятельно размещаемый мультимодальный MCP-сервер распознавания изображений VLM

Вставьте изображение в TUI-терминал → AI-клиент автоматически распознает и возвращает результат · данные не покидают внутреннюю сеть

MCP TypeScript Node Tests Build License: MIT Transport

Claude Code · Codex · OpenCode · любой MCP-совместимый клиент


✨ Зачем это нужно

Преимущество

Описание

🔒

Приватное развёртывание, данные не покидают сеть

Прямое подключение к вашему самостоятельно размещённому VLM, изображения не проходят через сторонние облака

🔌

OpenAI-совместимый, бэкенд можно менять

vLLM / Ollama / GLM-4V / Qwen-VL на выбор — достаточно сменить base URL, без изменения кода

🖼️

Вставка изображения в TUI

Вставьте изображение в терминал — клиент автоматически вызовет инструмент распознавания, как в MCP распознавания изображений Zhipu

🧩

Четыре специализированных инструмента

Общее понимание / OCR / понимание диаграмм / UI-транскодирование, каждый с предустановленным system prompt и структурированным выводом

📥

Три способа ввода изображений

Локальный путь · http(s) URL · data: URI — клиент принимает любой

🛡️

Ошибки не утекают

Строки ошибок содержат только статику/коды состояния, тело ответа VLM или стек никогда не передаются клиенту

⚡

Лёгкий одиночный процесс

stdio, клиент поднимает дочерний процесс по мере необходимости, без постоянного запуска и состояния на сервере

🔁

Встроенная устойчивость

Автоматический повтор при 5xx/таймауте, без повтора при 4xx, таймаут запроса, лимит размера изображения

✅

Полное покрытие TDD

35 тестов + сквозной цикл (фейковый VLM + InMemoryTransport)

Related MCP server: openai-vision-mcp-server

📐 Архитектура

flowchart LR
    A["🖥️ TUI 客户端<br/>(Claude Code / Codex / OpenCode)"] -- stdio JSON-RPC --> B
    subgraph B["vision-mcp (Node, stdio)"]
        direction TB
        C["tools ×4<br/>analyze_image / extract_text /<br/>understand_diagram / ui_to_code"]
        C --> D["analyze()<br/>共享核心"]
        D --> E["imageSource<br/>路径/URL/data-URI → 归一化"]
        D --> F["vlmClient<br/>OpenAI 兼容 + 重试"]
    end
    F -- HTTPS chat/completions --> G["🧠 自托管 VLM<br/>(qwen-vl / glm-4v / ...)"]
    G -- JSON --> B
    B -- tool result --> A

🛠️ Инструменты

Все используют общий image_source (локальный путь | http(s) URL | data: URI).

Инструмент

Специфичные параметры

Вывод

analyze_image

prompt (обязательный)

Описание на естественном языке / ответы на вопросы

extract_text

prompt?, programming_language?

OCR-текст (для скриншотов кода с указанием языка)

understand_diagram

diagram_type? (опущен или auto), prompt?

Структурированное описание + воспроизведение в mermaid/markdown

ui_to_code

output_type (code/spec/description), framework? (html/react-tailwind), prompt?

Соответствующие code/spec/description

🚀 Быстрый старт

Клонирование и сборка

git clone https://github.com/skyone123/vision-mcp.git
cd vision-mcp
npm install
npm run build      # 产出 dist/index.js + dist/index.d.ts
npm test           # 可选:35/35 测试

Клиенту нужен только dist/index.js — запишите его абсолютный путь (далее $DIST), он понадобится в конфигурации.

Пример: Linux/macOS /home/you/vision-mcp/dist/index.js; Windows D:/git/vision-mcp/dist/index.js.

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

Переменная

По умолчанию

Обязательно

Описание

VLM_BASE_URL

—

✅

OpenAI-совместимый base, например http://localhost:8000/v1 (с /v1)

VLM_MODEL

qwen-vl-max

—

Название модели

VLM_API_KEY

""

—

Bearer token; заполняйте, только если бэкенд требует аутентификацию, при пустом значении заголовок Authorization не отправляется

VLM_TIMEOUT_MS

60000

—

Таймаут одного запроса

VLM_MAX_IMAGE_BYTES

10485760

—

Лимит изображения 10 МБ

VLM_MAX_TOKENS

2048

—

Лимит возвращаемых токенов

Без VLM_BASE_URL сервер завершится с ошибкой при запуске, без тихого сбоя.

🔧 Конфигурация

Шаг 1 · Определите, нужен ли бэкенду API-ключ

curl http://localhost:8000/v1/models
  • 200 + список моделей → ключ не нужен

  • 401/403 → ключ нужен, повторите с ключом: curl http://localhost:8000/v1/models -H "Authorization: Bearer ваш_токен"

Выберите визуальную модель из возвращённого списка:

curl -s http://localhost:8000/v1/models | grep '"id"'

Проверьте, что модель действительно принимает изображения (самое важное):

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer 你的token" \
  -d '{
    "model": "qwen-vl-max",
    "messages": [{"role":"user","content":[
      {"type":"text","text":"一句话描述这张图"},
      {"type":"image_url","image_url":{"url":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/640px-PNG_transparency_demonstration_1.png"}}
    ]}]
  }'

Возвращается обычный текст → конечная точка работает, перенесите эти значения в env.

Шаг 2 · Пропишите в клиенте

Замените $DIST ниже на абсолютный путь к dist/index.js, записанный на предыдущем шаге, command — node.

claude mcp add vision-mcp --scope user \
  --env VLM_BASE_URL=http://localhost:8000/v1 \
  --env VLM_MODEL=qwen-vl-max \
  -- node "$DIST"

Если нужен ключ, добавьте строку --env VLM_API_KEY=ваш_токен.

{
  "command": "node",
  "args": ["/absolute/path/to/vision-mcp/dist/index.js"],
  "env": {
    "VLM_BASE_URL": "http://localhost:8000/v1",
    "VLM_MODEL": "qwen-vl-max"
  }
}

С ключом добавьте "VLM_API_KEY": "ваш_токен" в env.

{
  "mcpServers": {
    "vision-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/vision-mcp/dist/index.js"],
      "env": { "VLM_BASE_URL": "http://localhost:8000/v1", "VLM_MODEL": "qwen-vl-max" }
    }
  }
}
[mcp_servers.vision-mcp]
command = "node"
args = ["/absolute/path/to/vision-mcp/dist/index.js"]
env = { VLM_BASE_URL = "http://localhost:8000/v1", VLM_MODEL = "qwen-vl-max" }
{
  "mcp": {
    "vision-mcp": {
      "type": "local",
      "command": ["node", "/absolute/path/to/vision-mcp/dist/index.js"],
      "environment": {
        "VLM_BASE_URL": "http://localhost:8000/v1",
        "VLM_MODEL": "qwen-vl-max"
      }
    }
  }
}

В разных версиях OpenCode имена полей могут немного отличаться; если инструмент не появляется, сверьтесь с официальной документацией MCP.

Шаг 3 · Проверка

claude mcp list          # 应看到 vision-mcp,状态 connected

MCP-сервер не нужно держать запущенным вручную — клиент поднимает дочерний процесс по мере необходимости. Затем вставьте изображение в диалог и спросите «что на картинке» — клиент автоматически вызовет analyze_image; или явно:

Посмотрите это изображение инструментом analyze_image: <вставьте изображение>

💻 Разработка

npm run dev              # tsx 直接跑源码(开发期)
npm run build            # tsup 打包 dist/index.js
npm test                 # vitest,35/35
npx tsc --noEmit         # 类型检查

Структура исходного кода:

src/
  config.ts          # env → VlmConfig
  imageSource.ts     # loadImage: 路径/URL/data-URI 归一化
  vlmClient.ts       # complete: 调 OpenAI 兼容端点 + 重试/超时
  analyze.ts         # 共享核心: loadImage + complete
  server.ts          # McpServer 注册 + stdio + main
  index.ts           # #!/usr/bin/env node 入口
  tools/
    analyzeImage.ts
    extractText.ts
    understandDiagram.ts
    uiToCode.ts

Каждый файл имеет одну ответственность и может тестироваться независимо; четыре инструмента — тонкие обёртки над analyze(), каждый со своим встроенным system prompt.

🗺️ Дорожная карта (опциональные расширения)

Текущий охват: только stdio · один бэкенд · одно изображение · без персистентности. Ниже — расширения по мере необходимости:

Кандидат

Ценность

Рекомендация

Потоковый вывод

Вывод ui_to_code может быть длинным, потоковый режим позволяет видеть результат по мере генерации

👍 Стоит сделать, улучшение UX

Предобработка изображений

Масштабирование/сжатие по длинной стороне перед отправкой — экономия токенов, меньше таймаутов

👍 Стоит сделать, снижение затрат

Структурированный вывод

extract_text/understand_diagram возвращают JSON

🤔 Смотреть по ситуации

HTTP/SSE транспорт

Общий доступ для нескольких клиентов, удалённое развёртывание

🤔 Сейчас stdio достаточно, по мере необходимости

Маршрутизация по нескольким бэкендам

Маршрутизация разных задач на разные VLM

❌ YAGNI

Видео/пакетная обработка нескольких изображений

—

❌ Вне текущего позиционирования

Кэш на сервере

Повторное распознавание одинаковых изображений

❌ YAGNI

📄 Лицензия

MIT © 2026 luyuxin


Related MCP Connectors

Related MCP Servers