A Dockerized proxy that sits between AI coding assistants (Cline, KiloCode, Roo-Code) and LM Studio, fixing vision-model image encoding errors automatically.
Fork of amitrathiesh/lmstudio-proxy — rebuilt as a standalone Docker container with configurable ports, a web admin UI, and auto-restart.
When Cline and similar tools send screenshots to LM Studio, you often get:
[Server Error] 'url' field must be a base64 encoded image
Three root causes:
| Issue | What tools send | What LM Studio expects |
|---|---|---|
| File paths | /tmp/screenshot.png |
data:image/png;base64,... |
| WebP format | data:image/webp;base64,... |
PNG or JPEG data URIs |
| Malformed structure | "image_url": "data:..." (string) |
"image_url": { "url": "data:..." } |
This proxy intercepts /v1/chat/completions requests, transforms images in-place, and forwards the corrected payload to LM Studio.
Requirements: Docker Desktop (or Docker Engine + Compose)
git clone https://github.com/Dri-water/lmstudio-proxy.git
cd lmstudio-proxy
docker compose up -d --buildThe container starts automatically and restarts if it crashes or when Docker starts (restart: unless-stopped).
| Service | Default URL |
|---|---|
| Proxy — point Cline/KiloCode here | http://localhost:1235 |
| Admin UI — change settings in browser | http://localhost:8090 |
| LM Studio — unchanged | http://localhost:1234 |
Set the OpenAI-compatible base URL to the proxy, not LM Studio directly:
http://localhost:1235
LM Studio itself stays on port 1234. The proxy listens on 1235 (LM Studio + 1) and forwards requests after fixing images.
- Start the proxy on the host:
docker compose up -d - Join your devcontainer to the
lmstudio-proxynetwork — see devcontainer.example.json - Point Cline at one of:
http://lmstudio-proxy:1235(recommended — uses the shared Docker network)http://host.docker.internal:1235(works once port conflicts are cleared — see below)
For an already running devcontainer:
docker network connect lmstudio-proxy <your-devcontainer-name>Then set Cline base URL and restart the Cline panel.
Note: LM Studio only loads a model into memory when a chat/completions request arrives — listing models or a failed connection will not show a loaded model.
| Variable | Default | Description |
|---|---|---|
PROXY_PORT |
1235 |
Port the proxy listens on |
ADMIN_PORT |
8090 |
Port for the web admin UI |
LMSTUDIO_URL |
http://localhost:1234 |
LM Studio API endpoint (see note below) |
DEBUG |
false |
Verbose request logging |
CONFIG_DIR |
/data |
Persistent config directory |
Open http://localhost:8090 to change settings at runtime:
- Proxy port — where your AI tool connects
- Target URL — where requests are forwarded (default LM Studio on
:1234) - Debug logging — applied immediately without restart
Port changes require a container restart:
docker compose restartSettings persist in the proxy-data Docker volume across restarts.
Note on localhost: The default target is http://localhost:1234 because that's where LM Studio runs on your host. Inside the Docker container, localhost would normally mean the container itself — so the proxy automatically rewrites localhost / 127.0.0.1 to host.docker.internal when forwarding. You can keep localhost:1234 in the admin UI.
services:
lmstudio-proxy:
build: .
ports:
- "1235:1235"
- "8090:8090"
environment:
PROXY_PORT: 1235
ADMIN_PORT: 8090
LMSTUDIO_URL: http://localhost:1234
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stoppedOn Linux, host.docker.internal:host-gateway lets the container reach LM Studio running on the host.
The container uses restart: unless-stopped in docker-compose.yml:
- Restarts on crash — Docker brings the container back up automatically
- Starts with Docker — runs again when Docker Desktop/engine starts (unless you ran
docker compose down) - Survives reboots — as long as Docker is set to start on login
To stop permanently:
docker compose downnpm install
npm start # run locally
npm run dev # watch mode
npm test # run testsTests verify all three original bugs are fixed:
npm test- Bug 1: Local file paths → base64 data URIs
- Bug 2: WebP data URIs → PNG
- Bug 3: String
image_url→ proper object structure - Integration: End-to-end proxy forwarding with a mock LM Studio server
Verifies normal passthrough and the vision fix (WebP rejected on :1234, accepted via proxy on :1235):
npm run test:e2eCovers:
GET /healthon the proxyGET /v1/modelsthrough the proxy- Text-only
POST /v1/chat/completionson:1234and:1235 - WebP image conversion through the proxy
Cline / KiloCode
│
▼ POST /v1/chat/completions
┌──────────────────┐ ┌─────────────┐
│ Proxy :1235 │────▶│ LM Studio │
│ (image fix) │ │ :1234 │
└──────────────────┘ └─────────────┘
▲
┌──────────────────┐
│ Admin UI :8090 │
└──────────────────┘
Port 1235 is commonly used by the original VSCode extension and by VS Code Dev Containers auto-forwarding. If something else binds 127.0.0.1:1235, requests from devcontainers via host.docker.internal:1235 will never reach this Docker proxy — LM Studio won't load a model and nothing appears in proxy logs.
Two known conflicts:
| Conflict | What happens | How to fix |
|---|---|---|
Old VSCode extension (webzler.lmstudio-proxy) |
Extension process holds 127.0.0.1:1235 even after uninstall until VS Code fully quits |
Uninstall extension, quit all VS Code windows (not just Cursor), reopen |
| VS Code Dev Containers port forward | VS Code binds 127.0.0.1:1235 and forwards to devcontainer :1234 — shows in Ports tab as 1234 → 1235 |
VS Code → Ports tab → right-click the 1235 forward → Stop Forwarding |
Diagnose on Windows (PowerShell):
# Who is listening on 1235?
Get-NetTCPConnection -LocalPort 1235 -State Listen | Select-Object LocalAddress, OwningProcess
Get-Process -Id <OwningProcess>
# Does the Docker proxy respond?
Invoke-RestMethod http://127.0.0.1:1235/health # should return {"status":"ok",...}Expected when healthy: only Docker (com.docker.backend) on 0.0.0.0:1235, and 127.0.0.1:1235/health returns OK. If 127.0.0.1:1235 times out but localhost:1235 works, VS Code is still squatting on the IPv4 address.
Alternative: change the Docker proxy port to avoid all conflicts:
PROXY_PORT=1236 docker compose up -dProxy won't start — port in use
# Use a different proxy port
PROXY_PORT=1236 docker compose up -dImages still failing
- Confirm your AI tool points to
http://localhost:1235, not:1234 - Enable debug logging in the admin UI or set
DEBUG=true - Check logs:
docker compose logs -f
Cline in devcontainer — model never loads
- Check port 1235 conflicts above first
- Use
http://lmstudio-proxy:1235orhttp://host.docker.internal:1235(after conflicts cleared) - Run
docker network connect lmstudio-proxy <devcontainer-name>if not on the shared network - Enable debug in admin UI and watch
docker compose logs -f— you should see requests when Cline sends a message - LM Studio only loads the model when a chat request succeeds — check the LM Studio server tab for incoming requests
Can't reach LM Studio from container
Ensure LM Studio is running on the host at http://localhost:1234. The proxy rewrites this to host.docker.internal automatically inside Docker.
File path screenshots fail through Docker
Cline saves screenshots to your host temp folder (e.g. C:\Users\...\AppData\Local\Temp\). The container mounts this at /host-temp — ensure you're using docker compose up (not a plain docker run without the volume). Run npm run test:e2e to verify file-path vision works.
- Original VSCode extension: amitrathiesh/lmstudio-proxy by Amit Rathiesh
- Docker rewrite: Dri-water/lmstudio-proxy
MIT — see LICENSE