Content
# Vision MCP Server
MCP server that provides image recognition capabilities for Claude Code, along with an HTTP image interception proxy, allowing pure text models like GLM to accept image inputs, currently only supporting Kimi for visual capabilities.
## Features
This project consists of two parts that can be used independently or in combination:
### 1. MCP Tool (default)
Supports two image sources:
| Tool | Input | Example |
|------|------|------|
| `kimi_describe_image` | Local image file | `C:/Users/me/screenshot.png` |
| `kimi_describe_image` | Network image URL | `https://example.com/img.png` |
Identifies through Moonshot Kimi visual models (e.g., `kimi-k2.6`), supporting local file paths and http(s):// image URLs.
### 2. HTTP Image Interception Proxy (optional)
- Users can directly `Ctrl+V` paste images in Claude Code
- Acts as a proxy between Claude Code and the upstream LLM API
- Automatically intercepts images in requests, identifies with Moonshot, and replaces them with text descriptions
- Allows pure text models like GLM to normally handle image inputs without 400 errors
## Working Principle
```
┌─────────────────────────────────────────────────────────────────┐
│ Claude Code │
│ ├─ Calls MCP tool kimi_describe_image → Moonshot API │
│ └─ Sends message (with image) → http://127.0.0.1:8787 (this proxy) │
│ ↓ │
│ Proxy intercepts image → Calls Moonshot → Replaces with text │
│ ↓ │
│ Forwards pure text request → Upstream LLM API (e.g., GLM) │
└─────────────────────────────────────────────────────────────────┘
```
The MCP tool and proxy share the same process and Moonshot configuration, and the proxy automatically starts when the MCP server is launched.
## Prerequisites
- Node.js >= 18
- Moonshot API Key (apply on [platform.moonshot.cn](https://platform.moonshot.cn))
## Configuration
### 1. Basic Configuration (enabling MCP tool)
Edit `~/.claude.json`, add MCP server configuration, default supports local file / URL image recognition:
```json
{
"mcpServers": {
"vision-mcp": {
"command": "npx",
"args": ["-y", "image-vision-mcp"],
"env": {
"MOONSHOT_API_KEY": "sk-your-moonshot-api-key",
"MOONSHOT_BASE_URL": "https://api.kimi.com/coding/v1"
}
}
}
}
```
Restart Claude Code, then say "Recognize C:/xxx.png" to Claude, and Claude will automatically call the image recognition tool.
### 2. Advanced Configuration (enabling image proxy, optional)
**When needed**: You use pure text models like GLM and want to directly `Ctrl+V` paste images in Claude Code (without saying "Recognize image"). The proxy will automatically intercept images, identify with Moonshot, and forward to the upstream model.
| Usage | How to recognize |
|------|----------|
| Only use MCP tool (default) | Say "Recognize C:/xxx.png" or network image URL |
| Enable image proxy | Directly `Ctrl+V` paste image to Claude |
#### Configuration Steps
**Step 1**: Edit `~/.claude.json`, configure MCP server (add `UPSTREAM_BASE_URL` on top of basic configuration):
```json
{
"mcpServers": {
"vision-mcp": {
"command": "npx",
"args": ["-y", "image-vision-mcp"],
"env": {
"MOONSHOT_API_KEY": "sk-your-moonshot-key",
"MOONSHOT_BASE_URL": "https://api.kimi.com/coding/v1",
"UPSTREAM_BASE_URL": "https://your-upstream-llm-api-address"
}
}
}
}
```
**Step 2**: Edit `~/.claude/settings.json`, configure Claude Code to use the proxy:
```json
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:8787",
"ANTHROPIC_AUTH_TOKEN": "your-upstream-llm-api-token"
}
}
```
> The two `env` configurations have different effects:
> - `~/.claude/settings.json`'s `env`: Read by Claude Code itself (using proxy + upstream authentication)
> - `~/.claude.json`'s `mcpServers.vision-mcp.env`: Read by MCP server process (Moonshot key + upstream pure text model request address)
**Step 3**: Restart Claude Code, directly `Ctrl+V` paste image.
#### Environment Variable Reference
**Claude Code side** (`~/.claude/settings.json`'s `env`):
| Environment Variable | Required | Description |
|---------|------|------|
| `ANTHROPIC_BASE_URL` | Yes | `http://127.0.0.1:8787`, proxy listening port parsed from this URL |
| `ANTHROPIC_AUTH_TOKEN` | Yes | Upstream LLM API authentication token, reused by proxy |
**MCP server side** (`~/.claude.json`'s `mcpServers.vision-mcp.env`):
| Environment Variable | Required | Default | Description |
|---------|------|--------|------|
| `UPSTREAM_BASE_URL` | Yes | - | Upstream LLM API address, if not set, proxy will not start (MCP tool still available) |
| `UPSTREAM_AUTH_TOKEN` | No | Taken from `ANTHROPIC_AUTH_TOKEN` | Upstream authentication token |
| `MOONSHOT_API_KEY` | Yes | - | Moonshot API key (shared by MCP tool and proxy) |
| `MOONSHOT_BASE_URL` | Yes | - | Moonshot API endpoint (e.g., `https://api.kimi.com/coding/v1`) |
| `MOONSHOT_MODEL` | No | `kimi-k2.6` | Moonshot visual model name |
| `IMAGE_DESC_PROMPT` | No | Built-in Chinese prompt | Proxy's prompt to Moonshot when identifying images |
| `ALLOW_PRIVATE_NETWORK_IMAGES` | No | - | Set to `1` or `true` to allow accessing private network image URLs (default deny, prevent SSRF) |
## Usage Examples
### Using MCP Tool for Image Recognition
Default prompt is **"Please describe the content of this image in detail."** You can also specify other instructions in the conversation, such as "Extract all text in the image", "Analyze chart data", "Describe UI interface layout".
Say to Claude:
```
Recognize this image: C:/Users/me/screenshot.png
```
```
Describe this network image: https://example.com/chart.png
```
Claude will automatically call the `kimi_describe_image` tool.
### Using Proxy to Paste Image (after configuring proxy)
Directly `Ctrl+V` paste image in Claude Code input box, then enter question and press Enter:
```
[Paste image] What's in this image?
```
The proxy automatically identifies the image, and sends the description and your question to the upstream model.
## Tool Parameters
### `kimi_describe_image`
| Parameter | Type | Required | Default | Description |
|------|------|------|------|------|
| `image` | string | Yes | - | Local file path or http(s):// image URL |
| `prompt` | string | No | "Please describe the content of this image in detail." | Image recognition instruction, max 4000 characters |
| `max_tokens` | number | No | 2048 | Maximum token number of returned description, 1-8192 |
## Limitations
- Image size upper limit 20MB (applies to both URL download and local file reading)
- Request timeout 60s (Moonshot API), 30s (image download)
- Output text truncated if exceeding 25000 characters
- Supported formats: JPEG / JPG / PNG / GIF / WebP / BMP
## Troubleshooting
| Error | Solution |
|------|----------|
| `MOONSHOT_API_KEY environment variable not set` | Check MCP configuration's `env.MOONSHOT_API_KEY` |
| `Moonshot API authentication failed (401)` | API key incorrect or expired |
| `Moonshot API model not found (404)` | Model name incorrect (currently using `kimi-k2.6`) |
| `Moonshot API rate limited (429)` | Request too frequent, try again later |
| `Unable to access local file` | Path incorrect or no permission |
| `Failed to download image` | URL inaccessible or timed out |
| `listen EADDRINUSE 127.0.0.1:8787` | Port occupied, change `ANTHROPIC_BASE_URL`'s port or kill occupying process |
| Proxy failed to start but MCP tool available | Does not affect MCP tool functionality, only proxy unavailable |
## Development
```bash
npm run dev # Development mode (tsx watch, hot reload)
npm run build # Compile TypeScript → dist/
npm run clean # Clean build artifacts
```
## Contribution
Welcome to raise issues and PRs. Currently only supports Moonshot Kimi, planned to extend other visual models (OpenAI, Gemini, Tongyi Qianwen, etc.), with reserved architecture for extension.
## License
[MIT](LICENSE)