# Ollama Mcp Bridge

> Extend the Ollama API with dynamic AI tool integration from multiple MCP (Model Context Protocol) servers. Fully compatible, transparent, and developer-friendly, ideal for building powerful local LLM applications, AI agents, and custom chatbots

- **Type:** MCP server
- **Install:** `agentstack add mcp-jonigl-ollama-mcp-bridge`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [jonigl](https://agentstack.voostack.com/s/jonigl)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [jonigl](https://github.com/jonigl)
- **Source:** https://github.com/jonigl/ollama-mcp-bridge

## Install

```sh
agentstack add mcp-jonigl-ollama-mcp-bridge
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Provides an API layer in front of the Ollama API, seamlessly adding tools from multiple MCP servers so every Ollama request can access all connected tools transparently.

# Ollama MCP Bridge

[](https://pypi.org/project/ollama-mcp-bridge/)
[](https://github.com/jonigl/ollama-mcp-bridge/actions/workflows/ci.yml)
[](https://github.com/jonigl/ollama-mcp-bridge/actions/workflows/test-publish.yml)
[](https://github.com/jonigl/ollama-mcp-bridge/actions/workflows/publish.yml)
[](https://www.python.org/downloads/)

## Table of Contents

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
  - [Quick Start](#quick-start)
  - [Or, install from PyPI with pip](#or-install-from-pypi-with-pip)
  - [Or, run with Docker Compose](#or-run-with-docker-compose)
  - **✨NEW** [Or, run with Docker only](#or-run-with-docker-only)
  - [Or, install from source](#or-install-from-source)
- [How It Works](#how-it-works)
- [Configuration](#configuration)
  - [MCP Servers Configuration](#mcp-servers-configuration)
    - [Tool Filtering](#tool-filtering)
    - [Variable Expansion](#variable-expansion)
  - [CORS Configuration](#cors-configuration)
  - [Environment Variables](#environment-variables)
- [Usage](#usage)
  - [Start the Server](#start-the-server)
  - [CLI Options](#cli-options)
  - [API Usage](#api-usage)
  - [Example: Chat](#example-chat)
- [Development](#development)
  - [Key Dependencies](#key-dependencies)
  - [Testing](#testing)
- [Contributing](#contributing)
- [Related Projects](#related-projects)
- [Inspiration and Credits](#inspiration-and-credits)

## Features

- 🚀 **Pre-loaded Servers**: All MCP servers are connected at startup from JSON configuration
- 📝 **JSON Configuration**: Configure multiple servers with complex commands and environments
- 🌐 **Multiple Transport Types**: Connect to MCP servers via stdio (local processes), HTTP (StreamableHTTP), or SSE
- 🎯 **Tool Filtering**: Filter tools per server with include/exclude modes for fine-grained control
- 🧩 **Config Variable Expansion**: Supports `${env:VAR_NAME}` and `${workspaceFolder}` in config strings
- 🔗 **Tool Integration**: Automatic tool call processing and response integration
- 🔄 **Multi-Round Tool Execution**: Automatically loops through multiple rounds of tool calls until completion
- 🛡️ **Configurable Tool Limits**: Set maximum tool execution rounds to prevent excessive tool calls
- 🛠️ **All Tools Available**: Ollama can use any tool from any connected server simultaneously
- 🔌 **Complete API Compatibility**: `/api/chat` adds tools while all other Ollama API endpoints are transparently proxied
- 🔧 **Configurable Ollama**: Specify custom Ollama server URL via CLI (supports local and cloud models)
- 🔐 **Optional Upstream Headers**: Send fixed custom headers (e.g. an API key) with every request to the upstream server
- ☁️ **Cloud Model Support**: Works with Ollama cloud models
- 🔄 **Version Check**: Automatic check for newer versions with upgrade instructions
- 🌊 **Streaming Responses**: Supports incremental streaming of responses to clients
- 🤔 **Thinking Mode**: Proxies intermediate "thinking" messages from Ollama and MCP tools
- ⚡️ **FastAPI Backend**: Modern async API with automatic documentation
- 🏗️ **Modular Architecture**: Clean separation into CLI, API, and MCP management modules
- 💻 **Typer CLI**: Clean command-line interface with configurable options
- 📊 **Structured Logging**: Uses loguru for comprehensive logging
- 📦 **PyPI Package**: Easily installable via pip or uv from PyPI
- 🗣️ **System Prompt Configuration**: Allows setting a system prompt for the assistant's behavior
- 🐳 **Multi-Arch Docker Images** ✨ **NEW**: Pre-built `linux/amd64` and `linux/arm64` images published to GitHub Container Registry on every release

## Requirements

- Python >= 3.10.15
- Ollama server running (local or remote)
- MCP server configuration file with at least one MCP server defined (see below for example)

## Installation

You can install `ollama-mcp-bridge` in several ways, depending on your preference:

### Quick Start
Install instantly with [uvx](https://github.com/astral-sh/uv):
```bash
uvx ollama-mcp-bridge
```

### Or, install from PyPI with pip
```bash
pip install --upgrade ollama-mcp-bridge
```

### Or, run with Docker Compose

```bash
docker compose up
```

This uses the included [docker-compose.yml](./docker-compose.yml) file which:
- Builds the bridge from source using the [Dockerfile](./Dockerfile)
- Connects to Ollama running on the host machine (`host.docker.internal:11434`)
- Maps the configuration file from [./mcp-config.json](./mcp-config.json) (includes mock [weather server for demo](./mock-weather-mcp-server))
- Exposes port `8000` on the host
- Allows all CORS origins (configurable via `CORS_ORIGINS` environment variable)
- Supports configurable Ollama request timeouts via `OLLAMA_PROXY_TIMEOUT`

> [!TIP]
> To skip the local build and use the pre-built image from GitHub Container Registry instead, replace the `build:` block in `docker-compose.yml` with:
> ```yaml
> image: ghcr.io/jonigl/ollama-mcp-bridge:latest
> ```

### Or, run with Docker only

> [!NOTE]
> ✨ **NEW**: Pre-built multi-arch Docker images (`linux/amd64` and `linux/arm64`) are now published automatically to the GitHub Container Registry on every release. No local build required!

Pre-built multi-arch images (`linux/amd64` and `linux/arm64`) are published to the [GitHub Container Registry](https://github.com/jonigl/ollama-mcp-bridge/pkgs/container/ollama-mcp-bridge) on every release. Available tags:
- `latest` — most recent stable release
- `vX.Y.Z` — specific version (e.g. `v0.10.0`)
- `sha-` — exact commit SHA build

```bash
docker run -p 8000:8000 \
  -e OLLAMA_URL=http://host.docker.internal:11434 \
  -v "$PWD/mcp-config.json:/mcp-config.json" \
  -v "$PWD/mock-weather-mcp-server:/mock-weather-mcp-server" \
  -w / \
  ghcr.io/jonigl/ollama-mcp-bridge:latest
```

Key flags:
- `-p 8000:8000` — exposes the bridge on your host at port `8000`
- `-e OLLAMA_URL=http://host.docker.internal:11434` — routes Ollama traffic to the host machine (required on macOS and Windows; on Linux use `--network host` or the host's IP instead)
- `-v "$PWD/mcp-config.json:/mcp-config.json"` — mounts your local config into the container
- `-v "$PWD/mock-weather-mcp-server:/mock-weather-mcp-server"` — mounts the mock MCP server **without** `:ro` so `uv` can create its `.venv` inside the directory
- `-w /` — sets the working directory to `/` so relative paths in `mcp-config.json` resolve correctly

> [!NOTE]
> On Linux, `host.docker.internal` may not resolve automatically. Use `--network host` and keep `OLLAMA_URL=http://localhost:11434`, or replace it with your host's LAN IP.

### Or, install from source

```bash
# Clone the repository
git clone https://github.com/jonigl/ollama-mcp-bridge.git
cd ollama-mcp-bridge

# Start Ollama (if not already running)
ollama serve

# Run the bridge
uv run ollama-mcp-bridge
```

If you want to install the project in editable mode (for development):

```bash
# Install the project in editable mode
uv tool install --editable .
# Run it like this:
ollama-mcp-bridge
```

## How It Works

1. **Startup**: All MCP servers defined in the configuration are loaded and connected
2. **Version Check**: At startup, the bridge checks for newer versions and notifies if an update is available
3. **Tool Collection**: Tools from all servers are collected and made available to Ollama
4. **Chat Completion Request (`/api/chat` endpoint only)**: When a chat completion request is received on `/api/chat`:
   - The request is forwarded to Ollama (local or cloud) along with the list of all available tools
   - If Ollama chooses to invoke any tools, those tool calls are executed through the corresponding MCP servers
   - Tool responses are fed back to Ollama
   - The process repeats in a loop until no more tool calls are needed
   - Responses stream to the client in real-time throughout the entire process
   - The final response (with all tool results integrated) is returned to the client
   - **This is the only endpoint where MCP server tools are integrated.**
5. **Other Endpoints**: All other endpoints (except `/api/chat`, `/health`, and `/version`) are fully proxied to the underlying Ollama server with no modification.
6. **Logging**: All operations are logged using loguru for debugging and monitoring

## Configuration

### MCP Servers Configuration

You can configure MCP servers in three ways:
- **Local process (stdio)**: `{"command": "...", "args": [...], "env": {...}}`
- **Remote endpoint (StreamableHTTP)**: `{"url": "https://..."}` - Uses StreamableHTTP by default
- **Remote endpoint (SSE)**: `{"url": "https://.../sse"}` - If the URL ends with `/sse`, the bridge connects via Server-Sent Events

Create an MCP configuration file at `mcp-config.json` with your servers:

```json
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "./mock-weather-mcp-server",
        "run",
        "main.py"
      ],
      "env": {
        "MCP_LOG_LEVEL": "ERROR"
      },
      "toolFilter": {
        "mode": "include",
        "tools": ["get_current_temperature", "get_forecast"]
      }
    },
    "remote_streamable_http": {
      "url": "https://example.com/mcp"
    },
    "remote_sse": {
      "url": "https://example.com/sse"
    },
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/tmp"
      ],
      "toolFilter": {
        "mode": "exclude",
        "tools": ["delete_file", "write_file"]
      }
    }
  }
}
```

#### Tool Filtering

You can filter which tools from an MCP server are made available to Ollama using the optional `toolFilter` configuration:

- **`toolFilter`** (optional): Object with filtering options
  - **`mode`**: Either `"include"` (allow-list) or `"exclude"` (deny-list). Defaults to `"include"` if not specified.
  - **`tools`**: Array of exact tool names to include or exclude

**Behavior:**
- If `toolFilter` is not set or `tools` array is empty, all tools from the server are loaded (default behavior)
- **Include mode** (allow-list): Only the tools listed in the `tools` array are made available. If a listed tool is not found on the server, a warning is logged but the server connection continues.
- **Exclude mode** (deny-list): All tools except those listed in the `tools` array are made available. Listed tools are filtered out.
- Tool names must match exactly (case-sensitive)
- Invalid `mode` values cause the application to exit with an error message

**Example with include mode (default):**
```json
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["--directory", "./mock-weather-mcp-server", "run", "main.py"],
      "toolFilter": {
        "tools": ["get_current_temperature", "get_forecast"]
      }
    }
  }
}
```

**Example with explicit modes:**
```json
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": ["--directory", "./mock-weather-mcp-server", "run", "main.py"],
      "toolFilter": {
        "mode": "include",
        "tools": ["get_current_temperature"]
      }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
      "toolFilter": {
        "mode": "exclude",
        "tools": ["delete_file", "write_file"]
      }
    }
  }
}
```

#### Variable Expansion

The config also supports simple expansion in any string value:
- `${workspaceFolder}` resolves to the directory containing the config file
- `${env:VAR_NAME}` resolves to the corresponding environment variable

Example:

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "${workspaceFolder}/data"
      ]
    },
    "remote_with_headers": {
      "url": "https://example.com/mcp",
      "headers": {
        "X-Client-Name": "ollama-mcp-bridge",
        "X-Request-Tag": "${env:MCP_REQUEST_TAG}"
      }
    }
  }
}
```

> [!WARNING]
> **Docker Command Limitations**: When running in Docker, MCP servers should use commands available in the container:
> - ✅ `npx` for Node.js-based MCP servers
> - ✅ `uvx` for Python-based MCP servers
> - ✅ Direct executables in the container
> - ❌ `docker` commands (unless Docker-in-Docker is configured)
> - ❌ Local file paths from your host machine

### CORS Configuration

Configure Cross-Origin Resource Sharing (CORS) to allow requests from your frontend applications:

```bash
# Allow all origins (default, not recommended for production)
ollama-mcp-bridge

# Allow specific origins
CORS_ORIGINS="http://localhost:3000,https://myapp.com" ollama-mcp-bridge

# Allow multiple origins with different ports
CORS_ORIGINS="http://localhost:3000,http://localhost:8080,https://app.example.com" ollama-mcp-bridge
```

**CORS Logging:**
- The bridge logs CORS configuration at startup
- Shows warning when using `*` (all origins)
- Shows allowed origins when properly configured

> [!WARNING]
> Using `CORS_ORIGINS="*"` allows all origins and is not recommended for production. Always specify exact origins for security.

### Environment Variables
- `CORS_ORIGINS`: Comma-separated list of allowed origins (default: `*`)
  - `*` allows all origins (shows warning in logs)
  - Example: `CORS_ORIGINS="http://localhost:3000,https://myapp.com" ollama-mcp-bridge`
- `MAX_TOOL_ROUNDS`: Maximum number of tool execution rounds (default: unlimited)
  - Can be overridden with `--max-tool-rounds` CLI parameter (CLI takes precedence)
  - Example: `MAX_TOOL_ROUNDS=5 ollama-mcp-bridge`
- `OLLAMA_URL`: URL of the Ollama server (default: `http://localhost:11434`)
  - Can be overridden with `--ollama-url` CLI parameter
  - Useful for Docker deployments and configuration management
  - Example: `OLLAMA_URL=http://192.168.1.100:11434 ollama-mcp-bridge`
- `UPSTREAM_HEADERS`: Optional JSON object of headers to send to the upstream server (e.g. for API key authentication)
  - These headers are not consumed by Ollama itself, but by whatever sits between the bridge and Ollama (reverse proxy / gateway / auth layer) — the upstream
  - Can be extended/overridden per-header with the repeatable `--upstream-header` CLI parameter (CLI takes precedence)
  - Useful for Docker deployments where headers shouldn't appear in the process list
  - Example: `UPSTREAM_HEADERS='{"Authorization": "Bearer token123", "X-API-Key": "secret"}' ollama-mcp-bridge`
- `OLLAMA_PROXY_TIMEOUT`: Timeout for HTTP requests sent to Ollama, in **milliseconds** (default: unset)
  - When **unset**, the bridge keeps its existing behavior (some requests use library defaults; `/api/chat` is not timed out)
  - When set to a value **> 0**, the timeout is applied to Ollama-bound HTTP requests
  - When set to **0**, timeouts are disabled for Ollama HTTP requests (the bridge logs a warning)
  - Streaming chat responses always use no timeout, even when this variable is set
  - Example (10 minutes): `OLLAMA_PROXY_TIMEOUT=600000 ollama-mcp-bridge`
- `SYSTEM_PROMPT`: Optional system prompt to prepend to all forwarded `/api/chat` requests
  - Can be set via the `SYSTEM_PROMPT` environment variable or `--system-prompt` CLI flag
  - If provided, the bridge will prepend a system message (role: `system`) to the beginning of the `messages` array for `/api/chat` requests unless the request already starts with a system message.
  - Example: `SYSTEM_PROMPT="You are a concise assistant." ollama-mcp-bridge`

## Usage

> [!NOTE]
> An example MCP server script is provided at [mock-weather-mcp-server/main.py](mock-weather-mcp-server/main.py).

### Start the Server
```bash
# Start with default settings (config: ./mcp-config.json, host: 0.0.0.0, port: 8000)
ollama-mcp-bridge

# Start with custom configuration file
ollama-mcp-bridge --config /path/to/custom-config.json

# Custom host

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [jonigl](https://github.com/jonigl)
- **Source:** [jonigl/ollama-mcp-bridge](https://github.com/jonigl/ollama-mcp-bridge)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-jonigl-ollama-mcp-bridge
- Seller: https://agentstack.voostack.com/s/jonigl
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
