Skip to main content
Glama

🖼️ vision-mcp

セルフホスト型マルチモーダル VLM 画像認識 MCP サーバー

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 で画像を貼り付けるだけですぐ使える

端末で画像を貼り付けると、クライアントが自動的にツールを呼び出して認識。体験は智譜(Zhipu)の画像認識 MCP に準拠

🧩

4つの専用ツール

汎用理解 / OCR / 図表理解 / UI コード変換。それぞれにプリセットの system prompt と構造化出力を搭載

📥

3種類の画像入力

ローカルパス · http(s) URL · data: URI。クライアントが渡した形式をそのまま受け取る

🛡️

エラーを漏らさない

エラーメッセージは静的テキスト/ステータスコードのみ。VLM のレスポンス本文やスタックをクライアントに漏らすことは絶対にない

⚡

軽量シングルプロセス

stdio。クライアントが必要に応じて子プロセスを起動。常駐なし、サーバー側の状態なし

🔁

組み込みの耐障害性

5xx/タイムアウトは自動で1回リトライ、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 トークン。バックエンドが認証を要求する場合のみ設定。空の場合は Authorization ヘッダーを付けない

VLM_TIMEOUT_MS

60000

—

1回のリクエストのタイムアウト

VLM_MAX_IMAGE_BYTES

10485760

—

画像サイズ上限 10MB

VLM_MAX_TOKENS

2048

—

返答トークン上限

VLM_BASE_URL がない場合は起動時にエラーで終了する。静かに失敗することはない。

🔧 設定

ステップ 1 · バックエンドが API key を必要とするか確認

curl http://localhost:8000/v1/models
  • 200 + モデルリスト → key 不要

  • 401/403 → key 必要。key を付けて再試行:curl http://localhost:8000/v1/models -H "Authorization: Bearer 你的token"

モデル名は返答からビジョンモデルを選ぶ:

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"

key が必要な場合は --env VLM_API_KEY=你的token の行を追加。

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

key が必要な場合は env に "VLM_API_KEY": "你的token" を追加。

{
  "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

各ファイルは単一責任で、独立してテスト可能。4つのツールは 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