ollama-vision-mcp
by wzul
README.md
# Ollama Vision MCP
A Python [MCP](https://modelcontextprotocol.io) server that gives vision
capabilities to a text-only LLM. It exposes a single tool, `analyze_image`,
that sends a local image to a vision-capable Ollama model and returns the
model's textual description.
Works with Claude Code, Cursor, and any MCP client that can launch a stdio
command.
## Motivation
`deepseek-v4-flash:0731` is fast and capable, but it is a **text-only** model
ā it has no vision capability, so it can't look at screenshots, UI bugs, or
diagrams on its own. Rather than switch to a heavyweight vision model for
every task, this server bridges the gap: when the text-only LLM needs to
"see" an image, `analyze_image` sends it to a vision-capable Ollama model
(`kimi-k2.6` by default ā served by Ollama Cloud or a local instance) and
returns the visual details as text the text-only model can then reason about.
## Prerequisites
- **Python 3.10+** with [uv](https://docs.astral.sh/uv/) (recommended) or pip
- **Access to an Ollama instance serving a vision model** ā either:
- **Ollama Cloud** (no local daemon): export `OLLAMA_HOST=https://ollama.com`
and `OLLAMA_API_KEY=<your key>` in your shell profile, or
- a **local Ollama** with a vision model pulled:
```bash
ollama serve &
ollama pull kimi-k2.6
```
## Quick start
```bash
# 1. Get the code
git clone https://github.com/wzul/ollama-vision-mcp.git
cd ollama-vision-mcp
# 2. Install dependencies
uv sync
# 3. Test it standalone
uv run python tests/test_e2e.py
```
Then register the server in your MCP client. For Claude Code, the CLI registers
it at **user scope** (available in every project):
```bash
claude mcp add --scope user ollama-vision-mcp -- /absolute/path/to/ollama-vision-mcp/.venv/bin/ollama-vision-mcp
```
> **Scope gotcha:** without `--scope user`, `claude mcp add` registers at the
> project-local scope only ā the tool silently won't load from other directories.
Or add this to the top-level `mcpServers` object in `~/.claude.json` (the
top-level object *is* the user scope; see
[Registering](#registering-in-claudejson)):
```json
"ollama-vision-mcp": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/ollama-vision-mcp", "ollama-vision-mcp"]
}
```
> š” **Easiest install:** if you have Claude Code, just ask it to run the
> **`install-ollama-vision-mcp`** skill (ships in `.claude/skills/` in this
> repo) ā it checks prerequisites, writes the config, and verifies the
> connection for you.
## Running as an MCP server (stdio)
```bash
uv run ollama-vision-mcp
```
or directly from source:
```bash
.venv/bin/python ollama_vision_mcp/server.py
```
## Tool: `analyze_image`
| Argument | Type | Required | Default |
| ------------ | ------ | -------- | -------------------------------------------------------------- |
| `image_path` | string | yes | ā (absolute or relative path; PNG, JPG, WebP, ā¦) |
| `prompt` | string | no | `Describe this image in detail for a coding context.` |
| `model` | string | no | `kimi-k2.6` |
Logic: validates the path exists ā opens the image with Pillow (normalized to
RGB/PNG) ā sends it base64-encoded alongside the prompt via `ollama.chat()` ā
returns the model's text response.
## Registering in `~/.claude.json`
Add an `mcpServers` entry for this server (replace
`/path/to/ollama-vision-mcp` with your actual clone location). Two options:
### Option A ā `uvx` (runs in an isolated ephemeral environment)
```json
{
"mcpServers": {
"ollama-vision-mcp": {
"command": "uvx",
"args": [
"--from",
"/path/to/ollama-vision-mcp",
"ollama-vision-mcp"
]
}
}
}
```
`uvx` builds the local project each launch (cached). If the package is
published to PyPI, `"--from", "ollama-vision-mcp"` works instead.
### Option B ā standard Python execution (existing project venv)
```json
{
"mcpServers": {
"ollama-vision-mcp": {
"command": "/path/to/ollama-vision-mcp/.venv/bin/python",
"args": [
"/path/to/ollama-vision-mcp/ollama_vision_mcp/server.py"
]
}
}
}
```
For a system-wide Python instead of the project venv, install the package
first (`uv tool install --from . ollama-vision-mcp` or `pip install .`) and
point `command` at the `ollama-vision-mcp` executable.
> **JSON gotcha:** `~/.claude.json` is a single big JSON object. The
> `mcpServers` block already exists ā add the server as a new key *inside* it,
> and make sure you don't leave a trailing comma after the last entry.
> **Scope gotcha:** the top-level `mcpServers` object is the **user** scope
> (available in every project). If you register via the CLI instead, pass
> `--scope user` ā `claude mcp add` defaults to the project-local scope, which
> only loads when Claude Code starts from that project's directory.
> **Ollama Cloud:** the server reads `OLLAMA_HOST` (default
> `http://localhost:11434`) and `OLLAMA_API_KEY` from the environment. For the
> cloud, export `OLLAMA_HOST=https://ollama.com` in your shell profile ā no
> local daemon or `ollama pull` needed. The default model is `kimi-k2.6` (the
> `:cloud` tag does not exist on the cloud catalog).
After editing, restart Claude Code (or reload MCP servers). The
`analyze_image` tool will then be available to the text-only LLM.
## Testing
```bash
uv run python tests/test_e2e.py
```
Spawns the server over stdio via `mcp.client.stdio`, verifies tool
registration, runs `analyze_image` against a locally generated test image with
both the default and a custom prompt, and checks error handling for a missing
file.
## License
MIT
TDQS
A3.9/5.0
Scored across 1 tool
Disambiguation5/5
Only one tool exists, so there is no possibility of confusion or overlap with other tools.
Naming Consistency5/5
The tool name follows a clear verb_noun pattern (analyze_image), which is consistent and descriptive.
Tool Count3/5
With only one tool, the server feels thin and on the borderline of being too minimal, though the focus is narrow.
Completeness4/5
The core image analysis use case is covered, but the absence of features like model selection, batch processing, or multi-image comparison represents minor gaps.
Maintenance
ActivityMaintained
ResponsivenessSyncing