litellm-admin-mcp
by junwayne66
README.md
# litellm-admin-mcp
LiteLLM Admin MCP server for [OpenClaw](https://github.com/openclaw/openclaw). Exposes LiteLLM Proxy admin APIs (internal users, virtual keys, spend logs) as MCP tools over **streamable-http**, so agents can manage LiteLLM without custom HTTP glue.
> 将 LiteLLM Proxy 的管理能力封装为 MCP Server,供 OpenClaw Agent 通过 `streamable-http` 调用。
## Overview
| Item | Detail |
|------|--------|
| Transport | MCP Streamable HTTP at `/mcp` |
| Backend | LiteLLM Proxy REST API (`LITELLM_BASE_URL`) |
| Auth | `Authorization: Bearer sk-*` pass-through per request (not env var) |
| Tools | 18 admin tools (`litellm_user_*`, `litellm_key_*`, `litellm_model_*`, `litellm_usage_*`) |
| Health | `GET /health` → `{"status":"ok"}` |
```
OpenClaw Agent ──streamable-http + Bearer sk-*──► litellm-admin-mcp :3100/mcp
│
▼ Authorization pass-through
LiteLLM Proxy
```
## Prerequisites
- **Node.js 20+** (`engines.node` in `package.json`)
- A running **LiteLLM Proxy** with a valid **admin key** (`sk-*`)
- For OpenClaw integration: OpenClaw CLI with MCP support
## Install & Run
```bash
# Install dependencies
npm install
# Development (hot reload)
npm run dev
# Production build
npm run build
npm start
```
Default listen address: `http://0.0.0.0:3100`
- Health: `http://localhost:3100/health`
- MCP: `http://localhost:3100/mcp`
## Docker Deployment
### Quick start (docker compose)
```bash
docker compose up -d --build
docker compose logs -f litellm-admin-mcp
curl -s http://localhost:3100/health
```
Optional `.env` beside `docker-compose.yml`:
```bash
LITELLM_BASE_URL=http://192.168.91.200:8888
LITELLM_V1_BASE_URL=http://192.168.91.200:8888/v1
PORT=3100
```
> **Network note:** The container must reach LiteLLM at `LITELLM_BASE_URL`. From inside Docker, `127.0.0.1` points to the container itself — use the host LAN IP or `host.docker.internal` (Docker Desktop).
### Build and run manually
```bash
docker build -t litellm-admin-mcp:latest .
docker run -d \
--name litellm-admin-mcp \
-p 3100:3100 \
-e LITELLM_BASE_URL=http://192.168.91.200:8888 \
--restart unless-stopped \
litellm-admin-mcp:latest
```
Stop: `docker compose down` or `docker stop litellm-admin-mcp && docker rm litellm-admin-mcp`
## Environment Variables
Copy `.env.example` and adjust as needed:
```bash
cp .env.example .env
```
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `LITELLM_BASE_URL` | No | `http://192.168.91.200:8888` | LiteLLM Proxy base URL (no trailing slash) |
| `LITELLM_V1_BASE_URL` | No | `{LITELLM_BASE_URL}/v1` | OpenAI-compatible base URL used in `key_generate` onboarding (`BASE_URL` in `message_zh`) |
| `PORT` | No | `3100` | HTTP port for this MCP server |
| `HOST` | No | `0.0.0.0` | Bind address |
Example:
```bash
export LITELLM_BASE_URL=http://your-litellm-host:8888
export PORT=3100
export HOST=0.0.0.0
npm run dev
```
**Admin key is not an environment variable.** Configure it in the MCP client (e.g. OpenClaw headers), not in this server's env.
## Authentication
Every request to `/mcp` must include:
```http
Authorization: Bearer sk-<your-litellm-admin-key>
```
Behavior:
1. Missing or invalid header (must start with `Bearer sk-`) → **401** from this server; LiteLLM is not called.
2. Valid header → forwarded **unchanged** to LiteLLM API calls made by tool handlers.
OpenClaw (or any MCP client) supplies the key per session. Rotate keys in the client config without redeploying this server.
## OpenClaw Configuration
> 推荐用 **双 Agent** 隔离管理员与员工自助场景;权限由 LiteLLM RBAC + OpenClaw tool 白名单共同约束,MCP 本身不重复实现鉴权层。
### Recommended architecture: dual agents
| Agent | `Authorization` | Use case |
|-------|-------------------|----------|
| `litellm-admin` | `Bearer sk-<proxy_admin>` | Ops: users, keys, models, global usage reports |
| `litellm-self` | Employee self-serve key or scoped admin key | Feishu bot DM: request API key, check own usage |
```
Feishu Bot (litellm-self) Admin Agent (litellm-admin)
│ │
└──────── streamable-http ───────────┘
│
litellm-admin-mcp :3100/mcp
│
▼ Authorization pass-through
LiteLLM Proxy
```
### MCP server connection
Add to OpenClaw MCP config (e.g. `~/.openclaw/openclaw.json` or project-level MCP settings):
```json
{
"mcp": {
"servers": {
"litellm-admin": {
"url": "http://192.168.91.200:3100/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer sk-your-admin-key"
}
},
"litellm-self": {
"url": "http://192.168.91.200:3100/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer sk-your-self-serve-key"
}
}
}
}
}
```
Replace:
- `url` — host/port where `litellm-admin-mcp` runs (path must be `/mcp`)
- `litellm-admin` → LiteLLM proxy admin key (`sk-*`)
- `litellm-self` → a **scoped** key (self-serve or limited admin); do not reuse the root admin key for employee-facing bots
Network notes:
- OpenClaw and MCP on the same host: `http://127.0.0.1:3100/mcp`
- MCP in Docker, OpenClaw on host: use the **host LAN IP**, not container `127.0.0.1`
- OpenClaw must reach both this MCP server **and** LiteLLM is not required — only MCP needs `LITELLM_BASE_URL`
### Tool allowlists
Restrict tools per agent so employee bots cannot invoke destructive admin operations.
**Employee self-serve (`litellm-self`, e.g. Feishu bot):**
```
litellm_key_generate
litellm_key_list
litellm_key_info
litellm_user_info
litellm_model_list
litellm_model_info
litellm_usage_spend_logs
litellm_usage_user_activity
```
**Administrator (`litellm-admin`):** all 18 tools (see [MCP Tools](#mcp-tools-18) below).
Configure and verify:
```bash
openclaw mcp configure litellm-self \
--include litellm_key_generate,litellm_key_list,litellm_key_info,litellm_user_info,litellm_model_list,litellm_model_info,litellm_usage_spend_logs,litellm_usage_user_activity
openclaw mcp doctor litellm-admin --probe
openclaw mcp doctor litellm-self --probe
openclaw mcp tools litellm-admin # expect 18
openclaw mcp tools litellm-self # expect 8 (after allowlist)
```
### Feishu bot agent prompt (template)
Attach this system prompt to the `litellm-self` agent bound to your Feishu channel:
```
你是公司内网 LLM 服务助手。员工通过私聊可申请 API Key、查询可用模型和 token 用量。
## 申请 API Key
1. 确认员工身份(飞书 user_id / 工号);必要时用 litellm_user_info 核对是否已有账号
2. 调用 litellm_key_generate,建议 key_alias 设为唯一标识(如 feishu:<user_id>)
3. 将返回的 onboarding.message_zh 完整发给用户,必须包含 virtual_key
4. 明确告知:API Key 仅显示一次,请勿外传,仅在内网使用
## 查模型
- litellm_model_list / litellm_model_info
## 查用量
- litellm_usage_spend_logs(按 user_id 或时间范围)
- litellm_user_info(预算、累计 spend)
## 查已有 Key
- litellm_key_list / litellm_key_info(用 key_alias)
- 注意:LiteLLM 的 key_list / key_info 不会返回完整 virtual_key,只能查元数据
## 禁止
不要创建/删除用户、删模型、全局报表等管理员操作;引导用户联系 IT/管理员。
```
### Responsibilities: MCP vs OpenClaw
| Responsibility | MCP (this server) | OpenClaw |
|----------------|-------------------|----------|
| LiteLLM API wrappers | 18 tools | Select tools per agent |
| Chinese tool descriptions / keywords | Yes | — |
| Onboarding template (`curl`, `BASE_URL`) | `onboarding.message_zh` on `key_generate` | Forward to employee |
| Feishu `user_id` → LiteLLM `user_id` mapping | — | Your agent logic |
| Multi-turn chat, intent routing | — | Yes |
| Admin vs employee isolation | Pass-through `Authorization` | Separate agents + allowlists |
**User mapping suggestion:** map `feishu:ou_xxx` to a LiteLLM `user_id` on first request (`litellm_user_create` + `litellm_key_generate`), or rely on `key_alias=feishu:ou_xxx` if your Proxy config allows it.
### Key behavior reminders
1. **`virtual_key` is returned only once** at `litellm_key_generate` — send `onboarding.message_zh` to the user immediately; afterwards use `lookup_token` or `key_alias` for management.
2. **`key_list` / `key_info` never return the full key** — LiteLLM limitation, not an MCP bug.
3. **Set `LITELLM_V1_BASE_URL`** on the MCP server if employees reach LiteLLM through a reverse proxy (no `:8888` in the public URL); otherwise onboarding `curl` examples will point at the wrong host.
### OpenClaw rollout checklist
```bash
# 1. MCP health (no auth)
curl -s http://192.168.91.200:3100/health
# 2. OpenClaw connectivity
openclaw mcp doctor litellm-admin --probe
openclaw mcp doctor litellm-self --probe
# 3. Tool counts
openclaw mcp tools litellm-admin
openclaw mcp tools litellm-self
```
## MCP Tools (18)
### Users (5)
| Tool | Description |
|------|-------------|
| `litellm_user_list` | List internal users (pagination, filters) |
| `litellm_user_create` | Create internal user with role/budget/models |
| `litellm_user_update` | Update user role, budget, models |
| `litellm_user_delete` | Delete internal users |
| `litellm_user_info` | User details, keys, spend (self or admin) |
### Keys (5)
| Tool | Description |
|------|-------------|
| `litellm_key_list` | List virtual keys (`key_alias`, masked name, `lookup_token`) |
| `litellm_key_generate` | Create virtual key; returns `virtual_key` + `onboarding.message_zh` **once** |
| `litellm_key_update` | Update models, budget, rate limits |
| `litellm_key_delete` | Revoke virtual keys |
| `litellm_key_info` | Key details and spend; supports `key_alias` |
### Models (5)
| Tool | Description |
|------|-------------|
| `litellm_model_list` | List configured proxy models |
| `litellm_model_info` | Single model config details |
| `litellm_model_create` | Add model route (admin) |
| `litellm_model_update` | Update model params (admin) |
| `litellm_model_delete` | Remove model config (admin) |
### Usage (3)
| Tool | Description |
|------|-------------|
| `litellm_usage_spend_logs` | Per-request token/spend logs |
| `litellm_usage_global_report` | Platform-wide spend summary (admin) |
| `litellm_usage_user_activity` | Daily user activity trends |
Tool responses use a unified envelope:
```json
{ "success": true, "data": {} }
```
```json
{ "success": false, "error": { "status": 400, "message": "...", "detail": {} } }
```
## Verification
### Health check (no auth)
```bash
curl -s http://localhost:3100/health
# {"status":"ok"}
```
### OpenClaw MCP probe
With the server running and OpenClaw configured:
```bash
openclaw mcp doctor --probe
```
Confirm `litellm-admin` (or your server alias) reports a healthy streamable-http connection and lists all 18 tools.
## Testing
```bash
# Unit tests (default, no live LiteLLM)
npm test
# Optional integration tests against a real LiteLLM instance
RUN_INTEGRATION=1 npm test
# With custom LiteLLM URL / admin key for integration
LITELLM_BASE_URL=http://your-host:8888 LITELLM_ADMIN_KEY=sk-your-key RUN_INTEGRATION=1 npm test
```
Integration tests are read-only (`user/list`, `key/list`). They are skipped unless `RUN_INTEGRATION=1`.
## Security
**Treat the LiteLLM admin key (`sk-*`) as a root credential.**
- It can create/delete users and keys, change budgets, and read spend data.
- Store it only in trusted MCP client config (OpenClaw headers), secret managers, or CI secrets — **never** commit it to git.
- This server does not add a second auth layer; anyone who can reach `/mcp` with a valid admin key can perform admin actions on your LiteLLM Proxy.
- Bind to `127.0.0.1` or place the service behind a private network / reverse proxy with TLS if exposed beyond localhost.
- Do not log full `sk-*` values. `key_generate` may return a new plaintext key once (LiteLLM behavior); handle that response carefully.
## Project Layout
```
Dockerfile # Multi-stage production image
docker-compose.yml # One-command deployment
src/
server.ts # Hono app, /health, /mcp transport
litellm-client.ts # LiteLLM HTTP client with auth pass-through
tools/
users.ts # 5 user tools
keys.ts # 5 key tools (+ onboarding on generate)
models.ts # 5 model tools
usage.ts # 3 usage tools
index.ts # MCP server registration
utils/
response.ts # ok() / fail() helpers
onboarding.ts # virtual key quickstart / message_zh
tests/ # Vitest unit + optional integration tests
```
## License
See repository license file if present.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues