Use local AI models with JanitorAI - Run Qwen, Llama, Mistral, and other LLMs locally via LM Studio
Run local LLMs (via LM Studio) with JanitorAI using nginx reverse proxy and a CSP bypass browser extension. No paid API keys needed - use your own hardware!
Keywords: JanitorAI local LLM, LM Studio JanitorAI, free JanitorAI API, JanitorAI reverse proxy, local AI roleplay
JanitorAI blocks custom API endpoints via Content Security Policy (CSP). This setup bypasses that restriction using:
- LM Studio - Local LLM server (OpenAI-compatible API)
- nginx - Reverse proxy that rewrites endpoints and handles CORS
- ngrok - Exposes local server to the internet
- CSP Bypass Extension - Firefox/Chrome extension that removes CSP restrictions
JanitorAI → ngrok → nginx:5001 → LM Studio:1234
↓
Rewrites /chat/completions
to /v1/chat/completions
- Windows 10/11
- LM Studio 0.4.6+
- ngrok (free account)
- Firefox 109+ or Chrome/Brave
- A local LLM model (e.g., Qwen 3.5 9B, Llama, Mistral)
- Download and install LM Studio
- Download a model (e.g., Qwen 3.5 9B)
- Load the model
- Important: Disable "Thinking Mode" if using Qwen 3.x models
- Start the local server (default port: 1234)
# Download nginx for Windows
curl -L -o nginx.zip https://nginx.org/download/nginx-1.24.0.zip
# Extract to C:\nginx-1.24.0
unzip nginx.zip -d C:\Replace C:\nginx-1.24.0\conf\nginx.conf with:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/json;
sendfile on;
keepalive_timeout 65;
upstream lmstudio {
server 127.0.0.1:1234;
}
server {
listen 5001;
server_name localhost;
# Hide upstream CORS headers to avoid duplicates
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
# JanitorAI sends to /chat/completions - proxy to /v1/chat/completions
location = /chat/completions {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
proxy_pass http://lmstudio/v1/chat/completions;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Content-Type $content_type;
proxy_set_header Authorization $http_authorization;
proxy_buffering off;
proxy_read_timeout 300;
}
# Handle /models without /v1
location = /models {
add_header 'Access-Control-Allow-Origin' '*' always;
proxy_pass http://lmstudio/v1/models;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# Default - pass through as-is
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
proxy_pass http://lmstudio;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
proxy_cache off;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
}
}
}cd C:\nginx-1.24.0
nginx.exe- Download ngrok
- Create a free account and get your auth token
- Configure ngrok:
ngrok config add-authtoken YOUR_TOKEN
ngrok http 5001Copy the public URL (e.g., https://xxxx-xx-xx-xx-xx.ngrok-free.app)
Download from: https://github.com/Dabaski/janitorai-csp-bypass
Firefox:
- Clone or download the extension repo
- Go to
about:debugging - Click "This Firefox"
- Click "Load Temporary Add-on..."
- Select
manifest.jsonfrom the extension folder
Chrome/Brave:
- Clone or download the extension repo
- Go to
chrome://extensions - Enable "Developer mode"
- Click "Load unpacked"
- Select the extension folder
- Go to JanitorAI
- Open API Settings
- Select "Proxy" or "OpenAI Compatible"
- Enter:
- API URL:
https://your-ngrok-url.ngrok-free.app(no /v1) - API Key: Any value (e.g.,
sk-local) - Model:
qwen/qwen3.5-9b(or your model name)
- API URL:
- Disable thinking mode in LM Studio model settings
- Reload the model after changing settings
- Make sure nginx is running (not the Python proxy)
- Check only ONE process is on port 5001:
netstat -ano | grep 5001
- nginx rewrites
/chat/completionsto/v1/chat/completions - Use base URL without
/v1in JanitorAI
- Verify the extension is installed and enabled
- Check the extension icon shows "Enabled"
- Try refreshing JanitorAI page
- Free tier URLs change on restart
- Check
http://localhost:4040for current URL - Consider Cloudflare Tunnel for permanent URLs
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ JanitorAI │────▶│ ngrok │────▶│ nginx │────▶│ LM Studio │
│ (Browser) │ │ :443 │ │ :5001 │ │ :1234 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
│ ▼
│ ┌─────────────────┐
│ │ Path Rewriting │
│ │ /chat/completions│
│ │ ↓ │
│ │/v1/chat/completions│
│ └─────────────────┘
▼
┌─────────────────┐
│ CSP Bypass │
│ Extension │
│ (Removes CSP) │
└─────────────────┘
JanitorAI Proxy/
├── README.md # This file
├── config.txt # Quick reference config
├── csp-bypass-extension/ # Firefox/Chrome extension
│ ├── manifest.json
│ ├── background.js
│ ├── popup/
│ ├── options/
│ ├── icons/
│ └── tests/
├── ngrok.exe # ngrok binary
├── proxy_server.py # Alternative Python proxy (not needed)
├── test_connection.py # Connection test script
├── test_page.html # Browser test page
└── SillyTavern/ # Alternative frontend (optional)
If you prefer not to use JanitorAI, SillyTavern works directly with LM Studio without needing ngrok or CSP bypass:
cd SillyTavern
npm install
node server.jsThen open http://localhost:8000 and configure:
- API: Chat Completion > Custom (OpenAI-compatible)
- Endpoint:
http://localhost:1234/v1 - Model:
qwen/qwen3.5-9b
MIT