mcp-vision-server
by RuyimgByCN
README.md
# mcp-vision-server
[](https://pypi.org/project/RuyimgBy-mcp-vision-server/)
[](https://www.python.org/)
[](LICENSE)
[](https://modelcontextprotocol.io/)
One MCP server for every OpenAI-compatible vision model.
Configure once and use the same `analyze_image` tool across OpenAI, OpenRouter, Zhipu, Bailian, SiliconFlow and other compatible providers. It works with Claude Code, Codex, Cursor, Zed and any other MCP client.
## Why use mcp-vision-server?
- ✅ **Works with any MCP client** – Claude Code, Codex, Cursor, Zed and more.
- ✅ **Works with many providers** – switch providers without changing prompts or tool calls.
- ✅ **One unified API** – one tool (`analyze_image`) for every OpenAI-compatible vision endpoint.
- ✅ **Flexible image input** – URL, local file or Base64 are detected automatically.
- ✅ **Override anywhere** – configure globally with environment variables or per request.
## Quick Start
1. Install the server.
2. Set your provider and API key.
3. Add the MCP server to your client.
4. Ask:
```text
Describe this screenshot.
```
If everything is configured correctly, your MCP client will automatically call `analyze_image` and return the vision model's response.
## Features
- Single `analyze_image` tool with a consistent interface.
- Supports URL, local file and Base64 image inputs.
- Supports 13 built-in provider presets.
- Provider selection via `VISION_PROVIDER` or the `provider` parameter.
- Environment-level and request-level configuration overrides.
## Example
Ask your MCP client to analyze an image:
```text
Analyze this screenshot and tell me what UI is shown.
```
The client calls the MCP tool:
```json
{
"tool": "analyze_image",
"arguments": {
"image": "/path/to/screenshot.png",
"prompt": "Analyze this screenshot and tell me what UI is shown."
}
}
```
The server normalizes the image input, sends it to the selected OpenAI-compatible vision provider, and returns a plain text answer to your MCP client.
## Providers
Built-in presets make common OpenAI-compatible vision endpoints easy to use:
| Provider | Preset |
|---|---|
| Zhipu | `zhipu` |
| Bailian / DashScope | `bailian` |
| OpenAI | `openai` |
| SiliconFlow | `siliconflow` |
| OpenRouter | `openrouter` |
| Ark / Volcengine | `ark` |
| StepFun | `stepfun` |
| Kimi / Moonshot | `kimi` |
| MiniMax | `minimax` |
| ModelScope | `modelscope` |
| NVIDIA NIM | `nvidia` |
| Novita AI | `novita` |
You can also use any other OpenAI-compatible vision endpoint by setting `VISION_BASE_URL`, `VISION_API_KEY`, and `VISION_MODEL` manually.
## Install & Run
Requires Python ≥ 3.10 and [uv](https://docs.astral.sh/uv/).
```bash
cd mcp-vision-server
uv sync # install deps
uv run pytest -v # run tests
uv run ruff check . # lint
uv run mcp-vision-server # start stdio server
```
## Configuration
### Option 1: Provider preset (recommended)
```bash
export VISION_PROVIDER=zhipu # default
export VISION_API_KEY=your_key
```
See [Providers](#providers) for the full preset list.
You can also use provider-specific env vars (e.g. `DASHSCOPE_API_KEY`, `OPENAI_API_KEY`) as fallback.
### Option 2: Manual
| Variable | Required | Description |
|---|---|---|
| `VISION_API_KEY` | Yes | API key |
| `VISION_BASE_URL` | No | OpenAI-compatible endpoint |
| `VISION_MODEL` | No | Model name |
Tool params (override env per call): `image`, `prompt`, `image_type`, `provider`, `base_url`, `api_key`, `model`, `temperature`, `max_tokens`.
## MCP Client Setup
### Claude Code (`.mcp.json`)
```json
{
"mcpServers": {
"vision": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp-vision-server", "mcp-vision-server"],
"env": {
"VISION_PROVIDER": "zhipu",
"VISION_API_KEY": "your_key"
}
}
}
}
```
### Claude Code Plugin
```bash
# After PyPI publish
claude plugins install RuyimgByCN/mcp-vision-server
# Local test
claude plugins install /path/to/mcp-vision-server
```
The repo includes a [`.claude-plugin.json`](.claude-plugin.json) manifest — `claude plugins install` reads it automatically.
### Codex (OpenAI Codex CLI)
Edit `~/.codex/config.toml`:
```toml
[mcp_servers.vision]
command = "uvx"
args = ["mcp-vision-server"]
env = { VISION_PROVIDER = "zhipu", VISION_API_KEY = "your_key" }
```
Or for local dev:
```toml
[mcp_servers.vision]
command = "uv"
args = ["run", "--directory", "/path/to/mcp-vision-server", "mcp-vision-server"]
env = { VISION_PROVIDER = "zhipu", VISION_API_KEY = "your_key" }
```
### Cursor / other `uvx` clients
Replace `command` with `uvx`, `args` with `["--from", "/path/to/mcp-vision-server", "mcp-vision-server"]`, same `env`.
## Provider Examples
```json
// Bailian
"env": { "VISION_PROVIDER": "bailian", "VISION_API_KEY": "your_key" }
// OpenAI
"env": { "VISION_PROVIDER": "openai", "VISION_API_KEY": "sk-xxx" }
// Fully custom
"env": {
"VISION_BASE_URL": "https://your-endpoint/v1",
"VISION_API_KEY": "your_key",
"VISION_MODEL": "your-model"
}
```
## Architecture
```text
MCP Client (Claude Code / Codex / Cursor / Zed)
│
▼
mcp-vision-server
│
├── mcp_vision_server/server.py # MCP tool entrypoints
├── mcp_vision_server/config.py # env/provider/parameter resolution
├── mcp_vision_server/image.py # URL/file/base64 normalization
└── mcp_vision_server/providers.py # provider presets
│
▼
OpenAI-compatible Vision API
│
▼
Vision model response
```
## FAQ
### Why not call the vision provider directly?
This server gives MCP clients a single, reusable vision tool. You can switch providers without changing client prompts, MCP tool names, or client-side integration code.
### Can I use a provider that is not listed?
Yes. Use manual configuration with `VISION_BASE_URL`, `VISION_API_KEY`, and `VISION_MODEL` for any OpenAI-compatible vision endpoint.
### Can I override the provider per request?
Yes. Use the `provider`, `base_url`, `api_key`, or `model` tool parameters to override environment-level configuration for a single call.
### What image formats are supported?
The server accepts image URLs, local file paths, and Base64 strings. Input type can be auto-detected or specified with `image_type`.
## Development
```bash
uv sync --all-groups
uv run ruff check .
uv run ruff format .
uv run pytest -v
uv build
uv run twine check dist/*
```
## Release checklist
1. Update the version in `pyproject.toml`.
2. Run `uv run ruff check .`, `uv run pytest -v`, `uv build`, and `uv run twine check dist/*`.
3. Create and push a version tag, for example `v0.1.2`.
4. Let GitHub Actions publish to PyPI through trusted publishing.
## Roadmap
- Add more provider presets when stable OpenAI-compatible vision endpoints are available.
- Add richer examples for Claude Code, Codex, Cursor, and other MCP clients.
- Add optional streaming response support if MCP client UX benefits from it.
- Split provider-specific behavior into plugins only when providers require custom request logic.
## About
**Author:** [RuyimgByCN](https://github.com/RuyimgByCN)
**License:** Personal use only. Commercial use is prohibited — see [LICENSE](LICENSE) for details. Contact the author for commercial licensing.
**中文说明:** 个人使用免费,禁止商用。商业授权请联系作者。详见 [README_ZH.md](README_ZH.md)。
TDQS
A3.6/5.0
Scored across 2 tools
Disambiguation5/5
The two tools have entirely distinct purposes: analyze_image for image understanding and list_providers for listing provider presets. No overlap or ambiguity.
Naming Consistency5/5
Both tools follow a consistent verb_noun pattern (analyze_image, list_providers), making naming predictable and clear.
Tool Count3/5
Only two tools for a vision server feels slightly thin. While the count is not extreme, it borders on insufficient for typical vision tasks.
Completeness2/5
The server covers only basic image analysis and a provider listing, missing common vision operations like generation, manipulation, or filtering. The tool surface is significantly incomplete.
Maintenance
ActivitySlowing
ResponsivenessNo issues