glm-vision-mcp
<div align="right">
English · [中文](README-zh.md)
</div>
<h1 align="center">glm-vision-mcp</h1>
<p align="center">
<strong>A drop-in MCP vision server for Zhipu GLM Coding Plan — same tools, more advanced vision model.</strong>
<br />
<em>glm-5v-turbo · 8 Vision Tools · 3 Endpoint Modes · Smart Retry · Local Cache</em>
</p>
<p align="center">
<a href="#quick-start"><img src="https://img.shields.io/badge/Quick_Start-4CAF50?style=for-the-badge" alt="Quick Start" /></a>
<a href="#license"><img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License" /></a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/TypeScript-3178C6?style=flat&logo=typescript&logoColor=white" alt="TypeScript" />
<img src="https://img.shields.io/badge/Node.js-339933?style=flat&logo=nodedotjs&logoColor=white" alt="Node.js" />
<img src="https://img.shields.io/badge/MCP-black?style=flat&logo=i18next&logoColor=white" alt="MCP" />
<img src="https://img.shields.io/badge/Zod-3E67B1?style=flat&logo=zod&logoColor=white" alt="Zod" />
</p>
<p align="center">
<a href="https://docs.anthropic.com/en/docs/claude-code"><img src="https://img.shields.io/badge/Claude_Code-D97757?style=flat&logo=claude&logoColor=white" alt="Claude Code" /></a>
<a href="https://opencode.ai"><img src="https://img.shields.io/badge/OpenCode-000000?style=flat&logo=openai&logoColor=white" alt="OpenCode" /></a>
<a href="https://github.com/features/copilot"><img src="https://img.shields.io/badge/GitHub_Copilot-000000?style=flat&logo=github&logoColor=white" alt="GitHub Copilot" /></a>
</p>
---
## Features
| Feature | Description |
|---|---|
| 8 tools, same names | Identical tool names and parameter schemas as `@z_ai/mcp-server` — no prompt changes needed |
| Next-gen model by default | Uses glm-5v-turbo — improved accuracy and reasoning over the official glm-4.6v |
| Smart retry | 429 / 5xx / network errors retried with exponential backoff; 4xx fails immediately — saves quota |
| Local result cache | LRU memory cache + optional disk persistence; same image + prompt skips the API call |
| `.env` support | `dotenv` loads your key from `.env` — no need to pass it through environment variables in development |
| Extended formats | Images: jpg, png, webp, gif, bmp, tiff. Video: mp4, mov, m4v, avi, mkv, webm, flv |
## Quick Start
```bash
# 1. Copy and edit .env
cp .env.example .env
# Set Z_AI_API_KEY=your_coding_plan_key
# 2. Add to your MCP client
claude mcp add glm-vision-mcp \
--env Z_AI_API_KEY=YOUR_KEY \
-- npx -y glm-vision-mcp
```
## Usage
The server exposes 8 vision tools through stdio. Your MCP client handles tool discovery and invocation automatically.
### Claude Code
```bash
claude mcp add glm-vision-mcp \
--env Z_AI_API_KEY=YOUR_KEY \
-- npx -y glm-vision-mcp
```
### OpenCode
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"glm-vision-mcp": {
"type": "local",
"command": ["npx", "-y", "glm-vision-mcp"],
"environment": { "Z_AI_API_KEY": "YOUR_KEY", "Z_AI_MODE": "ZHIPU" }
}
}
}
```
### Cline / Roo Code
```json
{
"mcpServers": {
"glm-vision-mcp": {
"command": "npx",
"args": ["-y", "glm-vision-mcp"],
"env": { "Z_AI_API_KEY": "YOUR_KEY", "Z_AI_MODE": "ZHIPU" }
}
}
}
```
## Architecture
```mermaid
flowchart LR
Client["MCP Client\n(Claude Code / OpenCode / Cline)"]
Server["glm-vision-mcp\n(stdio transport)"]
Cache["Result Cache\n(LRU + disk)"]
Vision["VisionService\n(unified handler)"]
Chat["ChatService\n(retry + backoff)"]
API["GLM Vision API\n(ZHIPU / ZAI)"]
Client --> Server
Server --> Cache
Cache -->|"miss"| Vision
Cache -->|"hit"| Server
Vision --> Chat
Chat --> API
API --> Vision
```
## Configuration
| Variable | Default | Description |
|---|---|---|
| `Z_AI_API_KEY` | **Required** | Zhipu API key (Coding Plan key or pay-as-you-go key) |
| `ZAI_MCP_API_KEY` | — | Fallback alias (auto-mapped) |
| `Z_AI_MODE` | `ZHIPU` | Endpoint mode — see [Billing Modes](#billing-modes) |
| `Z_AI_VISION_MODEL` | `glm-5v-turbo` | Vision model ID |
| `Z_AI_VISION_MODEL_TEMPERATURE` | `0.8` | Sampling temperature |
| `Z_AI_VISION_MODEL_TOP_P` | `0.6` | Nucleus sampling |
| `Z_AI_VISION_MODEL_MAX_TOKENS` | `32768` | Max output tokens |
| `Z_AI_TIMEOUT` | `300000` | Request timeout (ms) |
| `Z_AI_RETRY_COUNT` | `2` | Max retries (retryable errors only) |
| `GLM_VISION_CACHE` | `true` | Enable result caching |
| `GLM_VISION_CACHE_TTL` | `604800` | Cache TTL in seconds (7 days) |
| `GLM_VISION_CACHE_MAX` | `100` | Max LRU cache entries |
| `GLM_IMAGE_MAX_SIZE_MB` | `5` | Max image file size |
| `GLM_VIDEO_MAX_SIZE_MB` | `8` | Max video file size |
## Billing Modes
Choose the endpoint via `Z_AI_MODE`:
| `Z_AI_MODE` | Endpoint | Billing |
|---|---|---|
| `ZHIPU` (default) | `https://open.bigmodel.cn/api/coding/paas/v4/` | GLM Coding Plan subscription quota |
| `ZHIPU_API` | `https://open.bigmodel.cn/api/paas/v4/chat/completions` | Pay-as-you-go API billing |
| `ZAI` | `https://api.z.ai/api/paas/v4/` | International z.ai platform |
Use the key that matches your billing plan: a Coding Plan key with `ZHIPU`, or a pay-as-you-go API key with `ZHIPU_API`.
## Directory Structure
```
src/
├── core/ # Environment, chat, vision, file, cache services
│ ├── environment.ts # Dotenv + multi-endpoint + key fallback
│ ├── chat-service.ts # GLM API calls with smart retry
│ ├── vision-service.ts # Unified analysis orchestration
│ ├── file-service.ts # Validation, base64 encoding, fingerprinting
│ └── cache.ts # LRU + disk cache
├── tools/
│ ├── definitions.ts # 8-tool data-driven definitions
│ └── registry.ts # Tool registration on MCP server
├── prompts/ # 8 specialized system prompts
├── types/ # Error type hierarchy
└── utils/ # Logger, sanitization, validation
tests/
scripts/
└── smoke.ts # End-to-end verification with real key
```
## Tech Stack
| Layer | Technology |
|---|---|
| Runtime | Node.js ≥ 18 |
| Language | TypeScript 5 |
| Protocol | `@modelcontextprotocol/sdk` |
| Validation | Zod |
| Config | dotenv |
| Build | TypeScript compiler (`tsc`) |
| Dev | tsx (hot-reload), vitest (64 tests) |
## Contributing
Fork → branch → commit → open a pull request. Run `npm test` before pushing.
## License
Released under the [MIT License](LICENSE).
TDQS
Scored across 8 tools
Each tool targets a distinct visual input type (UI, text, error, diagram, data viz, diff, generic, video) with explicit 'do not use for' boundaries. The generic analyze_image is clearly positioned as a fallback, preventing overlap with specialized tools.
All names use snake_case, but verb-first pattern is inconsistent: ui_to_artifact and ui_diff_check are noun-first while others are verb-first. Still, the style is uniform and readable.
8 tools is well-scoped for a vision analysis server, covering major categories of visual understanding without unnecessary bloat.
The tool surface covers UI conversion, OCR, error diagnosis, diagrams, data visualization, diff checking, generic image analysis, and video analysis—a comprehensive set for the domain. The fallback analyze_image ensures no dead ends.