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에 직접 연결, 이미지가 제3자 클라우드를 거치지 않음

🔌

OpenAI 호환, 백엔드 교체 가능

vLLM / Ollama / GLM-4V / Qwen-VL 중 선택, base URL만 바꾸면 됨, 코드 수정 불필요

🖼️

TUI 붙여넣기 즉시 사용

터미널에 이미지 붙여넣기, 클라이언트가 자동으로 도구 호출, 지푸(Zhipu) 이미지 인식 MCP와 동일한 경험

🧩

전용 도구 4개

일반 이해 / OCR / 차트 이해 / UI 코드 변환, 각각 사전 설정된 system prompt와 구조화된 출력 포함

📥

세 가지 이미지 입력 방식

로컬 경로 · 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 token; 백엔드가 인증을 요구할 때만 입력, 비워두면 Authorization 헤더 미포함

VLM_TIMEOUT_MS

60000

—

단일 요청 타임아웃

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 내토큰"

모델명은 응답에서 비전 모델을 선택:

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=내토큰 한 줄을 추가.

{
  "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": "내토큰" 추가.

{
  "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 server는 수동으로 상주시킬 필요가 없습니다 — 클라이언트가 필요 시 하위 프로세스를 실행합니다. 그런 다음 대화에 이미지를 붙여넣고 "이미지에 뭐가 있나요?"라고 물어보면 클라이언트가 자동으로 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