vision-mcp
This server adds vision understanding to MCP-connected agents, letting them hand images to vision models and get back text.
Analyze images (
analyze_image): send 1–9 images (local path, URL, data URI, or base64; mixable) with an optional custom prompt, provider, or model.Describe images (
describe_image): get a default detailed description of image content.OCR (
ocr_image): transcribe text from images inauto/zh/en/zh-en, preserving reading order.List providers (
list_providers): view registered providers, default models, and configuration status.Multi-image workflows: compare, diff, or combine up to 9 images per call, order preserved.
Extensive provider support: OpenAI, Anthropic, Gemini, DashScope, Zhipu, Doubao, ERNIE, StepFun, Ollama, Bailian, SiliconFlow, OpenRouter, and custom OpenAI-compatible endpoints, with configurable retries and fallbacks.
Enables image analysis, description, and OCR using Baidu Qianfan's ERNIE vision models.
Enables image analysis, description, and OCR using Google Gemini's vision models.
Enables image analysis, description, and OCR using local Ollama vision models.
Enables image analysis, description, and OCR using OpenAI's vision models.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vision-mcp Describe the image at https://example.com/photo.jpg"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Vision MCP Server
A Model Context Protocol (MCP) server that gives vision understanding to agents connected to non-multimodal models (DeepSeek, older GPT-4, local small models, etc.): the agent hands an image to the MCP tool, the server calls a vision model, and returns text.
Supports major providers in China and the US plus any OpenAI-compatible endpoint. Official SDKs first, abstraction before implementation, zero-intrusion provider additions.
中文文档见 README.zh-CN.md
Features
4 tools:
analyze_image/describe_image/ocr_image/list_providers, all returning plain Markdown text13 built-in providers: OpenAI / Anthropic / Google Gemini / Qwen (DashScope) / Zhipu / Doubao (Volcengine) / ERNIE (Qianfan) / StepFun / Ollama / Alibaba Bailian / SiliconFlow / OpenRouter / custom OpenAI-compatible endpoint
Up to 9 images per call (configurable via
VISION_MCP_MAX_IMAGES): local path / http(s) URL / base64 (data URI or raw base64), auto-sniffed, types mixableThree-tier fallback chain: official SDK → OpenAI-compatible endpoint → native fetch (see SPEC §1)
Stateless: every call is independent; images and results are never cached; keys are read from environment variables only
Related MCP server: vision-mcp
Quick start
Option A: npx (published to npm, no repo needed)
npx -y @inferai/vision-mcpOption B: local build
git clone <repo> && cd vision-mcp
pnpm install
pnpm build
node dist/index.jsMCP configuration examples (stdio)
The server speaks the stdio transport: the MCP client spawns the process and exchanges JSON-RPC messages over stdin/stdout. Configure it wherever your client defines MCP servers:
Claude Code: project-level
.mcp.jsonor user-level~/.claude.json(mcpServerskey)Claude Desktop:
claude_desktop_config.jsonAny MCP client (Cursor, self-built agents, etc.): same structure
Windows
On Windows npx resolves to npx.cmd, and MCP clients that spawn processes without a shell can't run it directly — wrap it in cmd /c:
{
"mcpServers": {
"vision-mcp": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@inferai/vision-mcp"],
"env": {
"OPENAI_API_KEY": "sk-...",
"DASHSCOPE_API_KEY": "sk-..."
}
}
}
}Local development (adjust the path; --env-file-if-exists=.env loads .env natively):
{
"mcpServers": {
"vision-mcp": {
"command": "node",
"args": [
"--env-file-if-exists=.env",
"C:\\path\\to\\vision-mcp\\dist\\index.js"
],
"env": {
"OPENAI_API_KEY": "sk-..."
}
}
}
}Linux / macOS
npx runs directly:
{
"mcpServers": {
"vision-mcp": {
"command": "npx",
"args": ["-y", "@inferai/vision-mcp"],
"env": {
"OPENAI_API_KEY": "sk-...",
"DASHSCOPE_API_KEY": "sk-..."
}
}
}
}Local development (adjust the path; --env-file-if-exists=.env loads .env natively):
{
"mcpServers": {
"vision-mcp": {
"command": "node",
"args": [
"--env-file-if-exists=.env",
"/absolute/path/to/vision-mcp/dist/index.js"
],
"env": {
"OPENAI_API_KEY": "sk-..."
}
}
}
}With startup arguments (override provider defaults via argv, see below; on Windows prefix the command/args with cmd /c):
{
"mcpServers": {
"vision-mcp": {
"command": "npx",
"args": [
"-y",
"@inferai/vision-mcp",
"--default-provider=dashscope",
"--siliconflow-api-key=sk-...",
"--siliconflow-model=Qwen/Qwen2.5-VL-7B-Instruct"
],
"env": {
"DASHSCOPE_API_KEY": "sk-..."
}
}
}
}stdio notes:
stdout carries the MCP protocol only — the server never prints logs there; diagnostics go to stderr
the client manages the process lifecycle (spawn on start, kill on exit); no daemon needed
first
npxrun downloads the package and may take a few secondsenv variables can also come from the shell environment if the client inherits it (no
envblock needed)
Debug with MCP Inspector:
pnpm dlx @modelcontextprotocol/inspector node dist/index.js --xxx-api-key=xxx --xxx2-api-key=xxxSetting variables
MCP config
envblock (recommended, most reliable across platforms) — write the variables into theenvobject above.envfile (local development) — copy.env.exampleto.env, fill it in, thennode --env-file-if-exists=.env dist/index.js(Node 22 native, no dotenv needed)Shell export —
export OPENAI_API_KEY=sk-xxxthen run
Providers without keys show as unavailable in list_providers and report the missing variable when called.
Publishing (before npx works)
pnpm publish # or pnpm release (changeset flow)Environment variables
Every provider's API_KEY, BASE_URL, and MODEL support environment overrides (convention: <PROVIDER_PREFIX>_API_KEY / <PROVIDER_PREFIX>_BASE_URL / <PROVIDER_PREFIX>_MODEL):
Provider | Environment variables | Default model |
OpenAI |
|
|
Anthropic |
|
|
Google Gemini |
|
|
Alibaba DashScope |
|
|
Zhipu |
|
|
Volcengine Doubao |
|
|
Baidu Qianfan |
|
|
StepFun |
|
|
Ollama (local) |
| — (no built-in default; endpoint and model must be set) |
Alibaba Bailian |
|
|
SiliconFlow |
|
|
OpenRouter |
|
|
Custom compatible |
| — |
?= optional (has a built-in default);*= required.
Global configuration:
Environment variable | Default | Description |
| first available | Default provider |
| provider default | Default model |
| table order | Provider priority (comma-separated, high first, e.g. |
| 0 (off) | Per-provider retry count before falling back |
| 0 (off) | Max provider fallbacks before giving up |
| 20 MB | Image size limit |
| 9 | Max images per tool call |
| 60000 | Download & request timeout (ms) |
Fallback chain
When multiple providers are available, calls walk the priority chain: configured default → VISION_MCP_PROVIDER_PRIORITY list → table order (unavailable providers are skipped).
each provider is retried up to
VISION_MCP_MAX_RETRIEStimes on provider errors (upstream failures, timeouts)after a provider exhausts its retries, the next available provider in the chain is tried, up to
VISION_MCP_MAX_FALLBACKSfallbacksonly provider errors trigger retry/fallback; config or image errors fail fast
an explicitly requested
providerargument is tried alone (no fallback)when everything fails, the error lists every provider attempted and its last error
Also available as argv: --provider-priority=..., --max-retries=N, --max-fallbacks=N (beat env vars).
MCP startup arguments (argv)
Every provider's apiKey / baseUrl / model can be overridden via startup arguments (higher priority than environment variables), format --<provider>-<field>:
node dist/index.js \
--openai-api-key=sk-xxx \
--openai-base-url=https://my-gateway.example.com/v1 \
--openai-model=gpt-4o-mini \
--dashscope-api-key=sk-xxx \
--default-provider=dashscopeGlobal:
--default-provider <name>/--default-model <name>Per provider:
--<provider>-api-key,--<provider>-base-url,--<provider>-model(equals or space form both work)Any OpenAI-compatible third-party service: wire it up in one line with
--openai-compat-base-url+--openai-compat-api-key+--openai-compat-model; or point any built-in provider'sbase-urlat a mirror/proxy
Priority: tool args provider/model > startup args (per-provider > global default) > environment variables > provider built-in defaults.
Tools
Tool | Arguments | Description |
|
| General image analysis |
|
| Describe image content (default instruction) |
|
| OCR, preserving layout |
| — | Provider list and configuration status |
images accepts a single image or an array (up to VISION_MCP_MAX_IMAGES, default 9): local path / http(s):// URL / data: URI / raw base64, auto-sniffed. Multiple images are seen by the model in the given order (compare, diff, or combine them).
Security note: URL downloads are SSRF-protected — every hop (including redirects) is validated and URLs resolving to loopback, private, or link-local addresses are blocked (hint in the error explains why).
Provider integration (three-tier fallback chain)
provider | Integration | Notes |
| OpenAI-compatible adapter (openai SDK) | One adapter, configurable baseURL |
| Official SDK @anthropic-ai/sdk | messages + image content block |
| Official SDK @google/generative-ai | generateContent + inlineData |
| Native fetch | official npm package has no vision; direct multimodal-generation API |
| Native fetch | official SDK accepts string content only; direct v4 API |
| Native fetch | official openapi is a management plane; direct Ark API |
| Native fetch | official SDK is string-only; AK/SK → token → v2 API |
Adding a provider: for OpenAI-compatible endpoints, add one row to RULES in src/core/config.ts plus one mapping in the factory table in src/index.ts — zero new code. Official SDK or native fetch implementations: see SPEC §1.
Development
pnpm check # biome checks
pnpm test # rstest unit tests (injected mocks, no network)
pnpm build # rslib buildReal-call smoke tests (only run against providers whose keys are configured; skipped otherwise):
OPENAI_API_KEY=sk-... pnpm exec rstest tests/e2eArchitecture
src/
├── index.ts # Entry: composition root, stdio startup
├── core/ # Abstraction: interfaces / image loading / config / registry
├── providers/ # Adapters: official SDK or compatible endpoints, protocol conversion only
└── server/tools.ts # MCP tool layer: zod validation + error mappingFull spec: SPEC.md.
Available Tools
4 toolsanalyze_imageA
Analyze one or more images with a vision model and return the text result. Accepts 1 to 9 images (local path, URL, data URI, or base64; types can be mixed). Pass several images to compare, diff, or combine them — the model sees them in the given order. Use for reading screenshots, photos, charts, UI states, document pages, etc.
Inputs: images (required), model, prompt, provider.
describe_imageA
Describe the image content: subject, layout, text, details. Accepts 1 to 9 images; each image is described in the given order. Equivalent to analyze_image with the default description instruction.
Inputs: images (required), model, provider.
list_providersA
List all registered vision model providers, their default models, and configuration status. Providers without keys will error when called.
Inputs: no named parameters.
ocr_imageA
OCR: transcribe all text in the image(s), preserving reading order and paragraph structure. Accepts 1 to 9 images; transcripts follow the given order. Suitable for screenshots, scans, invoices, slides, etc.
Inputs: images (required), model, language, provider.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
analyze_image, describe_image, and ocr_image all accept the same input and return text results. describe_image is explicitly described as equivalent to analyze_image with a default instruction, and ocr_image is just a specialized prompt variant. This creates significant overlap and makes it unclear when to choose one over another. Only list_providers is clearly distinct.
All tool names use snake_case with a verb-first pattern: analyze_image, list_providers, describe_image, ocr_image. The only minor deviation is ocr_image using an acronym instead of a plain verb, but it still fits the pattern. Overall, naming is predictable and consistent.
With only 4 tools, the server is on the low end of the typical range. However, 3 of the 4 tools essentially perform the same task with different prompt variations, so the effective functionality is even more limited. The count feels padded rather than well-scoped, and could be reduced to just analyze_image and list_providers without loss.
The server covers the core functionality of image analysis, including general analysis, description, and OCR, plus provider list management. Since analyze_image is generic and accepts multiple images for comparison, it covers most basic vision tasks. Minor gaps include lack of explicit model management or configuration tools, but list_providers partially addresses this.
Maintenance
Related MCP Connectors
OCR, transcription, file extraction, and image generation for AI agents via MCP.
MCP server exposing the YourImageShare upload API (upload/list/delete) as tools for AI agents.
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA versatile MCP server that adds vision capabilities (image analysis, OCR, image/video generation) to AI models lacking native vision, with support for multiple providers and automatic task routing.-
- AlicenseAqualityDmaintenanceMCP server that provides an analyze_image tool using OpenAI-compatible vision LLMs to describe images from file paths, URLs, or base64 data.121 npm1MIT
- FlicenseAqualityDmaintenanceOpenAI-compatible vision MCP server with 14 provider presets that enables MCP clients to analyze images, including screenshots, text, and UI mockups, via a single analyze_image tool.2-
- AlicenseNot gradedqualityDmaintenanceMCP server for analyzing images using multiple vision LLM providers (OpenCode, OpenAI, Anthropic, Google, and custom OpenAI-compatible endpoints). Provides tools to analyze single or multiple images, list providers, and test vision capabilities.MIT