vision-mcp
by forloopcodes
README.md
# vision-mcp
An MCP server that helps non-vision models extract and understand images and screenshots via OpenRouter multimodal models.
## Features
- **`analyze_image`** — Send an image (local file or URL) with a text prompt to any OpenRouter vision model and get a natural-language response.
- **`screen`** — Capture a screenshot of an application window by PID or process name (Windows only, uses `PrintWindow` via PowerShell).
## Prerequisites
- [Node.js](https://nodejs.org/) 18+ (ESM)
- An [OpenRouter](https://openrouter.ai/) API key with access to a vision-capable model
## Setup
```bash
# Clone and install
git clone <your-repo>
cd vision-mcp
npm install
# Configure environment
cp .env.example .env
```
Edit `.env` and set your OpenRouter key and preferred model:
```env
OPENROUTER_API_KEY=sk-or-v1-...
OPENROUTER_MODEL=google/gemini-2.0-flash-lite-preview-02-05:free
```
### Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `OPENROUTER_API_KEY` | Yes | — | Your OpenRouter API key |
| `OPENROUTER_MODEL` | Yes | — | Model identifier (e.g. `google/gemma-4-31b-it:free`) |
| `OPENROUTER_BASE_URL` | No | `https://openrouter.ai/api/v1` | API base URL override |
| `MAX_IMAGE_MB` | No | `20` | Maximum allowed image size in MB |
## Build & Run
```bash
npm run build
npm start
```
The server uses stdio transport and is designed to be launched by an MCP-enabled host (e.g. Claude, OpenCode). Example configuration block for your MCP client:
```json
{
"mcpServers": {
"vision-mcp": {
"command": "npx",
"args": ["-y", "@forloopcodes/visionmcp"],
"env": {
"OPENROUTER_API_KEY": "sk-or-v1-...",
"OPENROUTER_MODEL": "google/gemma-4-31b-it:free"
}
}
}
}
```
## Tools
### `analyze_image`
Analyze an image using a vision model.
**Arguments:**
| Name | Type | Required | Description |
|---|---|---|---|
| `prompt` | `string` | Yes | Instruction for the vision model |
| `image` | `string` | Yes | Local file path or `http`/`https` URL |
Local images are loaded, validated (size, path scope), and sent as base64 data URIs. Remote URLs are passed through directly.
### `screen`
Capture a screenshot of a running application window (Windows only).
**Arguments:**
| Name | Type | Required | Description |
|---|---|---|---|
| `action` | `"capture"` | Yes | The capture action |
| `target` | `string` | No | Process name to find and capture (e.g. `wezterm`, `notepad`) |
| `pid` | `number` | No | Process ID to capture |
Provide either `target` or `pid`. The server uses `PrintWindow` via a compiled C# snippet invoked through PowerShell. Supports `PW_RENDERFULLCONTENT` for DPI-aware captures.
> [!NOTE]
> Screen capture requires the `System.Drawing` assembly and works on Windows only. The captured PNG is written to the system temp directory.
## Architecture
```
src/
├── server.ts # MCP server entry point, tool routing
├── image.ts # Image loading, validation, base64 encoding
├── openrouter.ts # OpenRouter API client (multimodal chat completions)
├── types.ts # Shared TypeScript interfaces for API payloads
└── screen/
├── index.ts # Platform abstraction for screen capture
└── windows.ts # PowerShell + Win32 implementation (PrintWindow)
```
The server runs on the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk) with stdio transport. Image analysis requests are forwarded to OpenRouter's `/chat/completions` endpoint with a 60-second timeout. Security boundaries are enforced at the image loader — only files within the working directory are accepted.
## Security
- Local image paths are checked against the project root to prevent directory traversal.
- Screen captures are written to the OS temp directory (`$TMPDIR`).
- The PowerShell execution uses `-ExecutionPolicy Bypass` for the embedded C# script; no external `.ps1` files are written to disk.
## License
MIT
TDQS
A3.5/5.0
Scored across 2 tools
Disambiguation5/5
The two tools have clearly distinct purposes: analyze_image sends an image to a vision model, while screen captures a screenshot. No overlap in functionality.
Naming Consistency4/5
Both tool names follow a simple pattern, but 'screen' is a single noun used as a verb, while 'analyze_image' is verb_noun. The inconsistency is minor given only two tools.
Tool Count2/5
For a vision-related server, two tools are very minimal. Typical vision servers have at least 5-10 tools for different operations (list models, describe, compare, etc.).
Completeness2/5
The server lacks essential operations like listing available models, configuring parameters, or handling multiple image inputs. The surface is too narrow for a comprehensive vision tool.
Maintenance
ActivityInactive
ResponsivenessNo issues