LLMRing core server: alias sync, receipts, and usage logging (key-scoped, no users)
Project description
LLMRing Server
Self-hostable backend for the LLMRing project. It provides optional persistence and advanced features on top of the lockfile-only workflow.
Key Features
- Usage Tracking: Log LLM usage with costs and statistics
- Registry Proxy: Cached access to the public model registry (from GitHub Pages)
- Conversations: Store and retrieve conversation history
- MCP Integration: Persist MCP servers, tools, resources, and prompts
- Templates: Reusable conversation templates
This service is optional. LLMRing works fully in lockfile-only mode; run this server when you need persistence, usage tracking, or MCP integration.
Quick start
Requirements:
- Python 3.10+
- PostgreSQL (reachable from the server)
Install and run:
make dev
By default the dev server listens on http://0.0.0.0:9101 and exposes Swagger UI at /docs.
Manual alternative:
uv run llmring-server serve --env dev --reload --port 9101
Docker Compose (production-like local stack)
make docker
Services:
db: PostgreSQL 15 with persistent volumeredis: Redis 7 for caching/rate limiting (optional but bundled)server: llmring-server (production-like)
Default ports:
server: http://localhost:9100 (override withLLMRING_HTTP_PORT=...)
Common commands:
make docker-stop— stop the Docker stackmake logs— follow Docker logsmake status— show Docker status
Docker image (server only)
docker build -t llmring-server .
docker run --rm -p 9100:8000 \
-e LLMRING_DATABASE_URL='postgresql://user:pass@host:5432/dbname' \
llmring-server
Bare-metal development helper
./scripts/dev-server.sh
The script:
- Creates the development database if needed (
uv run llmring-server db create --env dev) - Runs migrations (
uv run llmring-server db migrate --env dev) - Starts the FastAPI server with auto-reload (default port
9101, override withLLMRING_PORT=...)
Bootstrap client configuration
After the server is running, generate a local env file from your application repo:
llmring server init --env-file .env.llmring
source .env.llmring
CLI helpers:
llmring server status— verify health checks and API key acceptancellmring server key rotate— create a fresh API key and update.env.llmringllmring server key list— inspect current values from env and env filellmring server stats— aggregated usage for the active API keyllmring server logs --output csv— export raw usage eventsllmring server conversations— inspect stored conversation history
Configuration
Configuration is provided via environment variables (Pydantic Settings). Key variables:
- LLMRING_DATABASE_URL: PostgreSQL connection string (default: postgresql://localhost/llmring)
- LLMRING_DATABASE_SCHEMA: Schema name (default: llmring)
- LLMRING_DATABASE_POOL_SIZE: Connection pool size (default: 20)
- LLMRING_DATABASE_POOL_OVERFLOW: Pool overflow (default: 10)
- LLMRING_REDIS_URL: Redis URL for caching (default: redis://localhost:6379/0)
- LLMRING_CACHE_TTL: Cache TTL seconds (default: 3600)
- LLMRING_CORS_ORIGINS: Comma-separated origins or JSON array (default: http://localhost:5173,http://localhost:5174)
- LLMRING_REGISTRY_BASE_URL: Base URL for the public registry (default: https://llmring.github.io/registry/)
Minimal required: set LLMRING_DATABASE_URL to a reachable Postgres instance.
Authentication model
- Project-scoped via
X-API-Keyheader - No user management in this service
- Aliases are local to each codebase in its lockfile; the server only logs the alias label used
Security notes:
- The
X-API-Keymust be treated as a secret. Do not expose it publicly - The server validates the header is present, non-empty, below 256 chars, and without whitespace
- In production, set narrow
LLMRING_CORS_ORIGINS(avoid*) and deploy behind TLS
Endpoints
Public Endpoints
- GET
/→ service info - GET
/health→ DB health - GET
/registry(and/registry.json) → aggregated provider registry (fetched from GitHub Pages)
Project-Scoped Endpoints (require header X-API-Key)
Usage Tracking (/api/v1)
- POST
/api/v1/log→ Log LLM usage{ "provider": "openai", "model": "gpt-4", "input_tokens": 100, "output_tokens": 50, "cached_input_tokens": 0, "alias": "summarizer", "profile": "prod", "cost": 0.0025 }
- GET
/api/v1/stats?start_date=&end_date=&group_by=day→ Usage statistics
Conversations (/conversations)
- POST
/→ Create new conversation{ "title": "Chat Title", "system_prompt": "You are helpful", "model_alias": "claude-3", "project_id": "uuid" }
- GET
/→ List conversations - GET
/{conversation_id}→ Get conversation with messages - PATCH
/{conversation_id}→ Update conversation metadata - GET
/{conversation_id}/messages→ Get conversation messages - POST
/{conversation_id}/messages/batch→ Add multiple messages - DELETE
/old-messages→ Clean up old messages
Conversation Templates (/api/v1/templates)
- POST
/→ Create template - GET
/→ List all templates - GET
/stats→ Template usage statistics - GET
/{template_id}→ Get specific template - PUT
/{template_id}→ Update template - DELETE
/{template_id}→ Delete template - POST
/{template_id}/use→ Record template usage
MCP Integration (/api/v1/mcp)
MCP Servers
- POST
/servers→ Register MCP server{ "name": "my-server", "url": "http://localhost:8080", "transport_type": "http", "auth_config": {...}, "capabilities": {...}, "project_id": "uuid" }
- GET
/servers→ List MCP servers - GET
/servers/{server_id}→ Get server details - PUT
/servers/{server_id}→ Update server - DELETE
/servers/{server_id}→ Remove server - POST
/servers/{server_id}/refresh→ Refresh server capabilities
MCP Tools
- GET
/tools→ List all tools (with server info) - GET
/tools/{tool_id}→ Get tool details - POST
/tools/{tool_id}/execute→ Execute tool{ "input": {...}, "conversation_id": "uuid" }
- GET
/tools/{tool_id}/history→ Get execution history
MCP Resources
- GET
/resources→ List all resources - GET
/resources/{resource_id}→ Get resource details - GET
/resources/{resource_id}/content→ Get resource content
MCP Prompts
- GET
/prompts→ List all prompts - GET
/prompts/{prompt_id}→ Get prompt details - POST
/prompts/{prompt_id}/render→ Render prompt with arguments
Security notes:
- Stats and logs are key-scoped; ensure you send the right API key to avoid data leakage across projects
Registry
The server proxies the public registry hosted at https://llmring.github.io/registry/. Models are returned with provider-prefixed keys (e.g., openai:gpt-4o-mini). Responses are cached in Redis when configured.
Database Schema
The server uses PostgreSQL with two schemas:
llmring schema (core data)
- usage_logs: LLM usage tracking
- conversations: Conversation metadata
- messages: Conversation messages
- conversation_templates: Reusable templates
mcp_client schema (MCP data)
- servers: MCP server registrations
- tools: Available tools from MCP servers
- resources: Available resources
- prompts: Available prompts
- tool_executions: Tool execution history
Migrations are managed via pgdbm and applied automatically on startup.
Development
Install dev dependencies and run:
# run tests
uv run pytest -q
# run the server in reload mode
uv run llmring-server --reload
# run migrations manually
uv run llmring-db migrate
The project uses:
- FastAPI for HTTP API
- pgdbm for Postgres migrations and access
- httpx for outbound HTTP
- redis (optional) for caching
- Pydantic for data validation
Security Checklist
- Set
LLMRING_CORS_ORIGINSto explicit origins (not*) in production - Serve behind TLS (reverse proxy like nginx or cloud load balancer)
- Store and rotate
X-API-Keyvalues securely; consider per-env keys - Restrict egress if running in sensitive environments; registry fetches use outbound HTTP
- Enable Redis with authentication (set
LLMRING_REDIS_URL) if caching is needed
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llmring_server-0.1.3.tar.gz.
File metadata
- Download URL: llmring_server-0.1.3.tar.gz
- Upload date:
- Size: 68.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52e5172eb5e39e762339dcc95c775f8408c9815fc285ed84dd7ded233c9c2501
|
|
| MD5 |
25a853fe0f4bba246cb1fe5f82109e7e
|
|
| BLAKE2b-256 |
a365e9bbced094013bf90975b924d0ae6ca04ab155ad0ca8c391660444067296
|
File details
Details for the file llmring_server-0.1.3-py3-none-any.whl.
File metadata
- Download URL: llmring_server-0.1.3-py3-none-any.whl
- Upload date:
- Size: 58.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a4d207f5ebd7656573b0a441551384dc1cf81653477205e0083c35a1ed74cd5
|
|
| MD5 |
ad4521a6030f18ae36ec7b9945eb3b6f
|
|
| BLAKE2b-256 |
684bbef8bc8f1d00659463eb21c76ba14d1e9475ce939ce5ed946fcc2f6e8e2b
|