Skip to main content
Glama
wzul
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