_
_ __ ___ ___ _ __ __ _| |_ __ ___ ___ ___ _ __
| '_ ` _ \ / __| '_ \ _____ / _` | | '_ ` _ \ _____ / _ \ / __| '__|
| | | | | | (__| |_) |_____| (_| | | | | | | |_____| (_) | (__| |
|_| |_| |_|\___| .__/ \__, |_|_| |_| |_| \___/ \___|_|
|_| |___/
Free OCR & vision for any AI coding client, powered by GLM-4.6V-Flash.
mcp-glm-ocr is an MCP server that gives
OCR and image-understanding capabilities to AI clients that cannot process
images themselves (Claude Code, Claude Desktop, Cursor, Cline, OpenCode, and
any other MCP-compatible client).
Under the hood it sends the image to GLM-4.6V-Flash, z.ai's vision-language model, which is completely free (input and output). The model reads the image and returns text, so your text-only client gets full vision capabilities at zero cost.
Why this exists: z.ai's official vision MCP server is exclusive to paid GLM Coding Plan subscribers. This one works with a plain free z.ai account.
| Tool | Description |
|---|---|
ocr_image(image) |
Extract all text from an image (screenshots, photos, receipts, document pages). |
describe_image(image) |
Detailed description of what an image shows. |
analyze_image(image, prompt) |
Answer a custom question about an image (charts, tables, diagrams, UI screenshots, math...). |
All tools accept:
- a local file path (absolute, or relative to the client's working directory), e.g.
demo.png - an http(s) URL, e.g.
https://example.com/photo.jpg - a
file://URL or adata:URL
- Python 3.10+ (or just
uv) - A free z.ai API key
- Go to https://z.ai/model-api and create an account (or log in).
- Create an API key at https://z.ai/manage-apikey/apikey-list.
- GLM-4.6V-Flash costs nothing to use.
claude mcp add glm-ocr --env ZAI_API_KEY=your_key -- uvx mcp-glm-ocrThen in any conversation:
> what does demo.png say?
> read the text from receipt.jpg
> describe this image: ~/Pictures/screenshot.png
> analyze this chart: chart.png — what is the trend?
Add to claude_desktop_config.json:
{
"mcpServers": {
"glm-ocr": {
"command": "uvx",
"args": ["mcp-glm-ocr"],
"env": { "ZAI_API_KEY": "your_key" }
}
}
}In .cursor/mcp.json at the root of your project:
{
"mcpServers": {
"glm-ocr": {
"command": "uvx",
"args": ["mcp-glm-ocr"],
"env": { "ZAI_API_KEY": "your_key" }
}
}
}In Cline settings → MCP servers:
{
"mcpServers": {
"glm-ocr": {
"command": "uvx",
"args": ["mcp-glm-ocr"],
"env": { "ZAI_API_KEY": "your_key" }
}
}
}{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"glm-ocr": {
"type": "local",
"command": ["uvx", "mcp-glm-ocr"],
"environment": { "ZAI_API_KEY": "your_key" }
}
}
}pip install mcp-glm-ocr
mcp-glm-ocr # requires ZAI_API_KEY env vardocker run --rm -i -e ZAI_API_KEY=your_key mcp-glm-ocr| Variable | Default | Description |
|---|---|---|
ZAI_API_KEY |
— | Required. Your z.ai API key. Z_AI_API_KEY is also accepted. |
ZAI_MODEL |
glm-4.6v-flash |
Model to use. Switch to glm-4.6v for higher quality (paid), or glm-ocr for a dedicated cheap OCR model. |
ZAI_BASE_URL |
https://api.z.ai/api/paas/v4/ |
API base URL. Lets you point at a proxy or self-hosted gateway. |
ZAI_TIMEOUT |
120 |
HTTP timeout in seconds. |
ZAI_MAX_TOKENS |
4096 |
Max output tokens per call. |
ZAI_MAX_IMAGE_MB |
15 |
Max local image size in MB (larger files are rejected). |
uv sync --all-groups # install deps + dev deps
uv run pytest -q # unit tests (no network, no API key)
uv run python scripts/smoke_stdio.py # boots the real stdio MCP server, lists tools
uv run mcp-glm-ocr # run the server locally (needs ZAI_API_KEY)
uv run mcp-glm-ocr --version
uv run python scripts/banner.py # print the banner in color (terminal)
# real end-to-end call against the z.ai API (needs a real key).
# Omitting the image uses the bundled test fixture (tests/fixtures/test_image.png):
ZAI_API_KEY=your_key uv run python scripts/live_test.py
ZAI_API_KEY=your_key uv run python scripts/live_test.py path/to/your/image.png- The client model calls
ocr_image/describe_image/analyze_image. - The server resolves the image (local file → base64
data:URL, or passthrough for URLs). - It calls
POST /chat/completionson the z.ai OpenAI-compatible API with modelglm-4.6v-flash. - The text answer is returned to the client model.
- Images only (no video). Video is out of scope for this free model.
- Free tier has rate limits set by z.ai; check the rate limits docs.
- Very large images are rejected by default (
ZAI_MAX_IMAGE_MB=15).
Option A: tag a version and let GitHub Actions build and publish automatically:
git tag v0.1.0 && git push --tagsPrerequisite: create a PyPI API token at https://pypi.org/manage/account/token/
and store it as the PYPI secret in the GitHub repo settings.
Option B: publish manually:
uv build # build sdist + wheel
uv publish # push to PyPI (requires a PyPI token)After publishing, users install with uvx mcp-glm-ocr or pip install mcp-glm-ocr.
Remember to bump version in pyproject.toml and src/mcp_glm_ocr/__init__.py
for each release.
MIT