agent-vision-mcp
# agent-vision-mcp (hardened)
A hardened fork of [`@kitlau/agent-vision-mcp`](https://github.com/kitlau86/agent-vision-mcp)
— an MCP server that gives non-vision LLMs the ability to analyze images via any
OpenAI-compatible vision API (Claude Code, DeepSeek, etc.).
This build fixes intermittent **empty / truncated** image-analysis results and request
hangs that affect long outputs (e.g. high-resolution 3D render screenshots) against
self-hosted Qwen VLMs and similar backends.
## What was broken upstream
The upstream package:
- defaulted output `max_tokens` to **1024** and never grew it, so long analyses hit
`finish_reason: length` and were cut off mid-sentence — and intermittently returned
**empty** `content`, surfacing as `❌ 视觉 API 返回的内容为空`;
- only read `message.content`, ignoring `message.reasoning_content` used by Qwen3.x
thinking-style models;
- had **no retry** on empty / 5xx / 429 / transient network errors;
- set **no client timeout**, so slow high-res inference could hang and get killed
(`MCP error -32001: user-cancel`).
## What this build changes
`dist/vision-client.js`:
- Grows `max_tokens` on truncation (`finish_reason === "length"`) and retries, so a low
ceiling can never silently produce a partial/empty answer (grow ceiling: 32768).
- Falls back to `message.reasoning_content` when `content` is empty (Qwen thinking mode).
- Retries on empty results, 5xx, 429, and network/timeout errors with exponential backoff
(default 3 retries).
- Sets an explicit client timeout (default 300000 ms) to prevent hangs.
`dist/config.js`:
- Adds `VISION_MAX_TOKENS` (default 16384), `VISION_TIMEOUT_MS` (default 300000),
`VISION_MAX_RETRIES` (default 3) env vars, exposed on the config object.
## Install as an MCP server
Point your MCP client at this repo. Example `claude_desktop_config.json` /
`.mcp.json` / global `~/.claude.json` entry:
```json
{
"mcpServers": {
"agent-vision": {
"type": "stdio",
"command": "node",
"args": ["path/to/this/repo/dist/index.js"]
}
}
}
```
For a drop-in remote install, clone this repo and `npm install`, then run `node dist/index.js`.
Or add it as a dependency with `npm install github:aabbccddwasd/agent-vision-mcp`.
### Environment variables
| Variable | Default | Description |
| ---------------------- | ---------------------------- | ---------------------------------------------- |
| `VISION_API_KEY` | *(required)* | API key for the OpenAI-compatible endpoint |
| `VISION_BASE_URL` | `https://api.openai.com/v1` | OpenAI-compatible base URL |
| `VISION_MODEL_NAME` | `gpt-4o` | The vision model, e.g. `Qwen3.6-35B-A3B` |
| `VISION_MAX_TOKENS` | `16384` | Output token budget (was 1024 upstream) |
| `VISION_TIMEOUT_MS` | `300000` | Per-request client timeout |
| `VISION_MAX_RETRIES` | `3` | Retries for empty / 5xx / 429 / network errors |
| `VISION_CACHE_ENABLED` | `false` | Optional disk response cache |
| `VISION_CACHE_DIR` | `<tmp>/agent-vision-cache` | Cache directory (when enabled) |
| `VISION_MAX_IMAGE_SIZE`| `20971520` | Max image bytes (20 MB) |
## License
MIT. Original author: kitlau86.
TDQS
Scored across 1 tool
There is only one tool, so there is no possibility of ambiguity or misselection. The tool's purpose is clearly distinct and singular.
With a single tool named 'analyze_image', the naming follows a clear and consistent verb_noun pattern. There are no other tools to introduce inconsistency.
The server has only one tool, which is below the typical 3-15 range, but it is a narrow-purpose server focused on image analysis. The single tool is well-scoped and earns its place, making the count slightly under but reasonable.
The single tool covers a wide range of image analysis needs—description, OCR, UI element detection, chart reading, etc. There are no obvious gaps for the stated purpose of giving a non-vision model the ability to see.