Add LICENSE, update docs with Anthropic endpoint and free-claude-code attribution
This commit is contained in:
parent
cc3ee5a03c
commit
9872175fb0
@ -1,10 +1,11 @@
|
||||
# mediaeng/llmproxy
|
||||
|
||||
A lightweight reverse proxy for [Ollama](https://ollama.com) that manages API keys with configurable token and request quotas. Incoming requests in OpenAI-compatible format are authenticated, checked against the quota, and forwarded to the configured Ollama server.
|
||||
A lightweight reverse proxy for [Ollama](https://ollama.com) that manages API keys with configurable token and request quotas. Incoming requests in OpenAI-compatible or Anthropic-compatible format are authenticated, checked against the quota, and forwarded to the configured Ollama server.
|
||||
|
||||
## Features
|
||||
|
||||
- OpenAI-compatible endpoint (`/v1/chat/completions`, `/v1/models`)
|
||||
- **Anthropic Messages API** (`/v1/messages`) — compatible with Claude Code CLI and Anthropic SDK clients
|
||||
- API key management with daily and monthly token/request limits
|
||||
- Web-based admin interface (port 8001)
|
||||
- Model lock: enforces a specific model for all requests (useful for courses and lab sessions)
|
||||
@ -17,7 +18,7 @@ A lightweight reverse proxy for [Ollama](https://ollama.com) that manages API ke
|
||||
|
||||
| Port | Service |
|
||||
|------|---------|
|
||||
| `8000` | Proxy endpoint (OpenAI API) |
|
||||
| `8000` | Proxy endpoint (OpenAI and Anthropic API) |
|
||||
| `8001` | Admin API + web interface |
|
||||
|
||||
All API endpoints require the `ADMIN_PASSWORD` — without a valid token, only the public frontend files (HTML/JS/CSS of the login page) are accessible. The password is therefore the primary protection.
|
||||
@ -35,6 +36,8 @@ All API endpoints require the `ADMIN_PASSWORD` — without a valid token, only t
|
||||
| `ADMIN_PORT` | `8001` | Admin API port |
|
||||
| `APP_TZ` | `Europe/Berlin` | Timezone for daily/monthly quota resets |
|
||||
| `LOG_FILE` | `logs/usage.log` | Path of the rotating usage log file |
|
||||
| `ANTHROPIC_DEFAULT_MODEL` | – | Default model for `/v1/messages` (Ollama model name, e.g. `llama3`) |
|
||||
| `BACKEND_API_KEY` | – | API key for an upstream proxy (forwarded to the backend) |
|
||||
|
||||
## Docker Compose – Ollama on the Host (Linux, recommended)
|
||||
|
||||
@ -60,6 +63,7 @@ volumes:
|
||||
ADMIN_PASSWORD=changeme
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
APP_TZ=Europe/Berlin
|
||||
ANTHROPIC_DEFAULT_MODEL=llama3
|
||||
```
|
||||
|
||||
## Docker Compose – Ollama as Container, SQLite
|
||||
@ -77,8 +81,8 @@ services:
|
||||
environment:
|
||||
ADMIN_PASSWORD: changeme
|
||||
OLLAMA_URL: http://ollama:11434
|
||||
|
||||
APP_TZ: Europe/Berlin
|
||||
ANTHROPIC_DEFAULT_MODEL: llama3
|
||||
volumes:
|
||||
- llmproxy-data:/app/backend
|
||||
depends_on:
|
||||
@ -110,9 +114,9 @@ services:
|
||||
environment:
|
||||
ADMIN_PASSWORD: changeme
|
||||
OLLAMA_URL: http://ollama:11434
|
||||
|
||||
APP_TZ: Europe/Berlin
|
||||
DATABASE_URL: postgresql://llmproxy:secret@db:5432/llmproxy
|
||||
ANTHROPIC_DEFAULT_MODEL: llama3
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@ -147,9 +151,19 @@ volumes:
|
||||
|
||||
## Client Configuration
|
||||
|
||||
Configure the proxy as an OpenAI-compatible endpoint:
|
||||
|
||||
**OpenAI-compatible client:**
|
||||
```
|
||||
Base URL: http://<host>:8000/v1
|
||||
API Key: <API key created in the admin interface>
|
||||
```
|
||||
|
||||
**Claude Code CLI:**
|
||||
```bash
|
||||
ANTHROPIC_BASE_URL=http://<host>:8000 \
|
||||
ANTHROPIC_AUTH_TOKEN=<API key> \
|
||||
claude
|
||||
```
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
The Anthropic Messages API endpoint (`/v1/messages`) was inspired by [free-claude-code](https://github.com/Alishahryar1/free-claude-code) by Ali Khokhar, which pursues a similar approach for routing Claude Code requests to alternative LLM backends.
|
||||
|
||||
22
DOCKERHUB.md
22
DOCKERHUB.md
@ -1,10 +1,11 @@
|
||||
# mediaeng/llmproxy
|
||||
|
||||
Ein schlanker Reverse-Proxy für [Ollama](https://ollama.com), der API-Keys mit konfigurierbaren Token- und Request-Quoten verwaltet. Eingehende Anfragen im OpenAI-kompatiblen Format werden authentifiziert, auf Quota geprüft und an den konfigurierten Ollama-Server weitergeleitet.
|
||||
Ein schlanker Reverse-Proxy für [Ollama](https://ollama.com), der API-Keys mit konfigurierbaren Token- und Request-Quoten verwaltet. Eingehende Anfragen im OpenAI-kompatiblen oder Anthropic-kompatiblen Format werden authentifiziert, auf Quota geprüft und an den konfigurierten Ollama-Server weitergeleitet.
|
||||
|
||||
## Funktionen
|
||||
|
||||
- OpenAI-kompatibler Endpunkt (`/v1/chat/completions`, `/v1/models`)
|
||||
- **Anthropic Messages API** (`/v1/messages`) — kompatibel mit Claude Code CLI und Anthropic-SDK-Clients
|
||||
- API-Key-Verwaltung mit tages- und monatlichen Token-/Request-Limits
|
||||
- Web-basierte Admin-Oberfläche (Port 8001)
|
||||
- Modell-Lock: erzwingt ein bestimmtes Modell für alle Requests (nützlich für Praktika/Kurse)
|
||||
@ -17,7 +18,7 @@ Ein schlanker Reverse-Proxy für [Ollama](https://ollama.com), der API-Keys mit
|
||||
|
||||
| Port | Dienst |
|
||||
|------|--------|
|
||||
| `8000` | Proxy-Endpunkt (OpenAI-API) |
|
||||
| `8000` | Proxy-Endpunkt (OpenAI- und Anthropic-API) |
|
||||
| `8001` | Admin-API + Web-Oberfläche |
|
||||
|
||||
Alle API-Endpunkte erfordern das `ADMIN_PASSWORD` — ein Zugriff ohne gültiges Token liefert nur die öffentlichen Frontend-Dateien (HTML/JS/CSS der Login-Seite). Das Passwort ist damit die primäre Schutzmaßnahme.
|
||||
@ -35,6 +36,8 @@ Alle API-Endpunkte erfordern das `ADMIN_PASSWORD` — ein Zugriff ohne gültiges
|
||||
| `ADMIN_PORT` | `8001` | Port der Admin-API |
|
||||
| `APP_TZ` | `Europe/Berlin` | Zeitzone für Tages-/Monats-Reset der Quoten |
|
||||
| `LOG_FILE` | `logs/usage.log` | Pfad der rotierenden Nutzungs-Logdatei |
|
||||
| `ANTHROPIC_DEFAULT_MODEL` | – | Standard-Modell für `/v1/messages` (Ollama-Modellname, z. B. `llama3`) |
|
||||
| `BACKEND_API_KEY` | – | API-Key für einen vorgelagerten Proxy (wird an das Backend weitergereicht) |
|
||||
|
||||
## Docker Compose – Ollama auf dem Host (Linux, empfohlen)
|
||||
|
||||
@ -60,6 +63,7 @@ volumes:
|
||||
ADMIN_PASSWORD=changeme
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
APP_TZ=Europe/Berlin
|
||||
ANTHROPIC_DEFAULT_MODEL=llama3
|
||||
```
|
||||
|
||||
## Docker Compose – Ollama als Container, SQLite
|
||||
@ -77,8 +81,8 @@ services:
|
||||
environment:
|
||||
ADMIN_PASSWORD: changeme
|
||||
OLLAMA_URL: http://ollama:11434
|
||||
|
||||
APP_TZ: Europe/Berlin
|
||||
ANTHROPIC_DEFAULT_MODEL: llama3
|
||||
volumes:
|
||||
- llmproxy-data:/app/backend
|
||||
depends_on:
|
||||
@ -110,9 +114,9 @@ services:
|
||||
environment:
|
||||
ADMIN_PASSWORD: changeme
|
||||
OLLAMA_URL: http://ollama:11434
|
||||
|
||||
APP_TZ: Europe/Berlin
|
||||
DATABASE_URL: postgresql://llmproxy:secret@db:5432/llmproxy
|
||||
ANTHROPIC_DEFAULT_MODEL: llama3
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@ -147,9 +151,15 @@ volumes:
|
||||
|
||||
## Client-Konfiguration
|
||||
|
||||
Den Proxy als OpenAI-kompatibler Endpunkt konfigurieren:
|
||||
|
||||
**OpenAI-kompatibler Client:**
|
||||
```
|
||||
Base URL: http://<host>:8000/v1
|
||||
API Key: <angelegter API-Key aus der Admin-Oberfläche>
|
||||
```
|
||||
|
||||
**Claude Code CLI:**
|
||||
```bash
|
||||
ANTHROPIC_BASE_URL=http://<host>:8000 \
|
||||
ANTHROPIC_AUTH_TOKEN=<API-Key> \
|
||||
claude
|
||||
```
|
||||
|
||||
27
LICENSE
Normal file
27
LICENSE
Normal file
@ -0,0 +1,27 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Oliver Hofmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
Portions of this software were inspired by free-claude-code
|
||||
(https://github.com/Alishahryar1/free-claude-code),
|
||||
copyright (c) 2026 Ali Khokhar, MIT License.
|
||||
47
README.md
47
README.md
@ -4,12 +4,13 @@ Ollama bietet von sich aus keine Authentifizierung — wer die API erreicht, kan
|
||||
|
||||
## Features
|
||||
|
||||
- API-Key-Authentifizierung (Bearer Token oder `sk-`-Prefix)
|
||||
- API-Key-Authentifizierung (Bearer Token, `sk-`-Prefix, `x-api-key`- und `anthropic-auth-token`-Header)
|
||||
- Optionales Ablaufdatum pro API-Key
|
||||
- Quota-Management mit getrennten Tages- und Monatslimits (Tokens & Requests)
|
||||
- Token-Zählung via tiktoken, Reset-Grenzen in der Zeitzone Europe/Berlin
|
||||
- Token-Zählung via tiktoken, Reset-Grenzen in der konfigurierten Zeitzone
|
||||
- Web-Admin-Oberfläche (API-Keys verwalten, Ollama-Einstellungen, Verbrauchsanzeige)
|
||||
- OpenAI-kompatibler `/v1/chat/completions`-Endpunkt mit Streaming und Tool-Use
|
||||
- **Anthropic Messages API** `/v1/messages` — kompatibel mit Claude Code CLI und Anthropic-SDK-Clients
|
||||
- Rotierende Nutzungs-Logs
|
||||
- SQLite (Standard) oder PostgreSQL
|
||||
- Docker-Image auf DockerHub: `mediaeng/llmproxy`
|
||||
@ -35,6 +36,7 @@ DATABASE_URL=sqlite:///./test.db
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
APP_TZ=Europe/Berlin
|
||||
LOG_FILE=logs/usage.log
|
||||
ANTHROPIC_DEFAULT_MODEL=llama3
|
||||
```
|
||||
|
||||
| Variable | Standard | Beschreibung |
|
||||
@ -49,6 +51,8 @@ LOG_FILE=logs/usage.log
|
||||
| `APP_TZ` | `Europe/Berlin` | Zeitzone für tägliche/monatliche Quota-Resets |
|
||||
| `LOG_FILE` | `logs/usage.log` | Pfad der rotierenden Nutzungs-Logdatei |
|
||||
| `ALLOWED_ORIGINS` | `http://localhost:5173` | CORS-Origins (nur für Entwicklung relevant) |
|
||||
| `ANTHROPIC_DEFAULT_MODEL` | — | Standard-Modell für `/v1/messages` (Ollama-Modellname) |
|
||||
| `BACKEND_API_KEY` | — | API-Key für einen vorgelagerten Proxy (wird an das Backend weitergereicht) |
|
||||
|
||||
## Entwicklung (lokal)
|
||||
|
||||
@ -78,6 +82,23 @@ Das Script prüft alle Ports auf Belegung, initialisiert die Datenbank und start
|
||||
|
||||
Admin-Oberfläche: `http://localhost:5173`
|
||||
|
||||
## Claude Code CLI
|
||||
|
||||
Der Proxy stellt einen Anthropic-kompatiblen Endpunkt bereit, über den Claude Code CLI mit lokalen Ollama-Modellen genutzt werden kann.
|
||||
|
||||
```bash
|
||||
# ANTHROPIC_DEFAULT_MODEL in .env setzen, dann:
|
||||
./start_claude.sh
|
||||
|
||||
# Oder mit Key als Argument:
|
||||
./start_claude.sh sk-dein-api-key
|
||||
|
||||
# Oder als Umgebungsvariable:
|
||||
PROXY_API_KEY=sk-dein-api-key ./start_claude.sh
|
||||
```
|
||||
|
||||
Das Script setzt `ANTHROPIC_BASE_URL` und `ANTHROPIC_AUTH_TOKEN` automatisch aus der `.env` und startet `claude`.
|
||||
|
||||
## Produktion (Docker)
|
||||
|
||||
### Docker Compose (empfohlen)
|
||||
@ -168,17 +189,26 @@ Clients konfigurieren dann `https://llm.example.com/v1` als Base URL.
|
||||
|
||||
## Proxy-Endpunkte (Port 8000)
|
||||
|
||||
Alle Endpunkte erfordern einen gültigen API-Key im `Authorization`-Header.
|
||||
Alle Endpunkte erfordern einen gültigen API-Key im `Authorization`-Header (`Bearer sk-...`), im `x-api-key`-Header oder im `anthropic-auth-token`-Header.
|
||||
|
||||
```bash
|
||||
# OpenAI-kompatibler Endpunkt
|
||||
curl -X POST http://localhost:8000/v1/chat/completions \
|
||||
-H "Authorization: Bearer sk-xxxxxx" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"llama3","messages":[{"role":"user","content":"Hallo"}]}'
|
||||
|
||||
# Anthropic-kompatibler Endpunkt (z. B. für Claude Code)
|
||||
curl -X POST http://localhost:8000/v1/messages \
|
||||
-H "x-api-key: sk-xxxxxx" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"llama3","messages":[{"role":"user","content":"Hallo"}],"max_tokens":1024}'
|
||||
```
|
||||
|
||||
| Endpunkt | Methode | Beschreibung |
|
||||
|----------|---------|--------------|
|
||||
| `/v1/messages` | POST | Chat (Anthropic-Format, Streaming + Tool-Use) |
|
||||
| `/v1/chat/completions` | POST | Chat (OpenAI-Format, Streaming + Tool-Use) |
|
||||
| `/v1/models` | GET | Modelle (OpenAI-Format) |
|
||||
| `/api/generate` | POST | Ollama generate (nativ) |
|
||||
@ -226,7 +256,8 @@ llm_quota/
|
||||
│ └── tests/
|
||||
│ ├── conftest.py
|
||||
│ ├── test_auth.py
|
||||
│ └── test_quota.py
|
||||
│ ├── test_quota.py
|
||||
│ └── test_anthropic_messages.py
|
||||
├── frontend/
|
||||
│ └── src/
|
||||
│ ├── main.jsx # React-Admin-UI
|
||||
@ -238,13 +269,19 @@ llm_quota/
|
||||
├── docker-entrypoint.sh
|
||||
├── .dockerignore
|
||||
├── start.sh # Entwicklungs-Startscript
|
||||
├── start_claude.sh # Claude Code CLI mit Proxy starten
|
||||
├── run_dev.py # Entwicklungs-Runner für PyCharm
|
||||
├── build_push.sh # Docker-Build & Push zu DockerHub
|
||||
├── LICENSE
|
||||
├── DOCKERHUB.md # DockerHub-Beschreibung (deutsch)
|
||||
├── DOCKERHUB.en.md # DockerHub-Beschreibung (englisch)
|
||||
└── .gitignore
|
||||
```
|
||||
|
||||
## Danksagung
|
||||
|
||||
Der Anthropic-kompatible Endpunkt (`/v1/messages`) wurde durch das Projekt [free-claude-code](https://github.com/Alishahryar1/free-claude-code) von Ali Khokhar inspiriert, das einen ähnlichen Ansatz für das Weiterleiten von Claude-Code-Anfragen an alternative LLM-Backends verfolgt.
|
||||
|
||||
## Lizenz
|
||||
|
||||
MIT
|
||||
MIT — siehe [LICENSE](LICENSE)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user