ViperLLM
ViperLLM is an advanced, high-performance Server-Side ONLY Fabric mod for Minecraft 1.21.x, 26.1.x, and 26.2.x. It connects vanilla Minecraft chat to compatible Large Language Model providers with automatic endpoint detection, isolated per-player profiles, conversation memory, endpoint fallback, and a live @tool system. No client mod is required.
Supported Versions
| Version | Java | Status |
|---|---|---|
| 1.21.x | 21 | Full support |
| 26.1.x | 25 | Full support |
| 26.2.x | 25 | Full support |
Purpose & Function
ViperLLM allows players to communicate with AI agents through standard Minecraft chat while granting those agents controlled access to live server information.
- Universal Endpoint Detection: Detects OpenAI, OpenRouter, LM Studio, Ollama, Anthropic, and compatible proxy layouts.
- Isolated Player Environments: Each player owns separate instances, models, API keys, prompts, settings, and memory at
world/viperllm/players/<UUID>.json. - Live State Tools: The LLM can request recipes, inventory, player status, nearby entities, weather, time, statistics, advancements, book/chest contents, and permitted commands.
- Memory Management: Combines short-term conversation history with asynchronous long-term summaries.
- Vanilla-Compatible Pipeline: Uses Fabric Mixins and Brigadier entirely server-side. Vanilla clients require no installation.
Key Features
| Feature | Description |
|---|---|
| Multi-Provider Architecture | OpenRouter, OpenAI-compatible APIs, LM Studio, Ollama, Anthropic, and custom reverse proxies. |
| Automated Endpoint Scanning | /llm scan probes common REST layouts and gives the player a written book containing discovered model IDs. |
| Model List Book | /llm set <id> model list probes the active endpoint and returns a written book of available models. |
| Per-Player Profiles | Separate instances, API keys, prompts, model settings, command permission, and memory. |
| Permanent Tool Rules | Server-enforced base rules remain active while player prompts are appended as extra instructions. |
| Endpoint Fallback | Retries compatible paths and payload formats when a provider rejects the current endpoint, then remembers the working combination. |
| Private-Network Protection | Restricts localhost and LAN endpoint scanning to operators unless the server explicitly allows all players. |
| Owner-Level Commands | @command runs only with the owning player's normal Minecraft permissions, never console permissions. |
| Non-Blocking HTTP | API traffic runs on a bounded daemon executor; Minecraft tools return to the server thread. |
| Minimal Footprint | Requires Fabric Loader but does not require Fabric API. |
| Model Tab Completion | /llm set <id> model tab-completes cached models from the endpoint. |
| No Bundled Secret | The default API key is empty. Server owners and players provide their own credentials. |
Enhance your server setup! Check out my other server-side mods over at : Fabric Server Essentials
Commands & Examples
| Command | Description | Example |
|---|---|---|
/llm configure <id> |
Create and activate an instance from global defaults | /llm configure helper |
/llm configure <id> <url> <model> [api_key] |
Detect and configure a custom endpoint, optionally with API key | /llm configure local http://localhost:1234 qwen3.5-4b |
/llm scan <url> [api_key] |
Detect endpoint format and available models | /llm scan https://api.openai.com YOUR_API_KEY |
/llm select <id> |
Select an existing instance | /llm select helper |
/llm delete <id> |
Delete an instance | /llm delete oldbot |
/llm info |
Display profile and active-instance details | /llm info |
/llm test |
Send an OK test through the active instance |
/llm test |
/llm ask <message> |
Send a message to the active LLM | /llm ask How do I craft a mace? |
/llm upload <url> <message> |
Send a media URL with a prompt | /llm upload https://example.com/image.png Describe this image |
/llm clearmemory |
Clear conversation memory | /llm clearmemory |
/llm mode PRIVATE|GLOBAL |
Change response routing mode | /llm mode PRIVATE |
/llm global |
Toggle routing all of your chat to the LLM | /llm global |
/llm commands |
Toggle command-tool permission for your profile | /llm commands |
/llm set <id> apikey <key> |
Set a per-instance API key | /llm set helper apikey YOUR_API_KEY |
/llm set <id> url <url> |
Change an instance endpoint | /llm set helper url http://localhost:11434/api/chat |
/llm set <id> model <name> |
Change an instance model | /llm set helper model qwen3.5-4b |
/llm set <id> model list |
Probe endpoint and show available models as a book | /llm set local model list |
/llm set <id> prompt <text> |
Append custom instructions after permanent rules | /llm set helper prompt Speak like a dwarf |
/llm set <id> temperature <0-2> |
Change sampling temperature | /llm set helper temperature 0.8 |
/llm set <id> timeout <5-120> |
Set the HTTP timeout in seconds | /llm set helper timeout 60 |
/llm set <id> prefix <text> |
Change the response prefix | /llm set helper prefix [AI] |
/llm set <id> color <code> |
Change the response color value | /llm set helper color gray |
/llm set <id> context playerdata <true|false> |
Toggle player-data context | /llm set helper context playerdata true |
/llm set <id> context inventory <true|false> |
Toggle inventory context | /llm set helper context inventory true |
/llm set <id> context recipes <true|false> |
Toggle recipe context | /llm set helper context recipes true |
/llm set <id> context maxrecipes <number> |
Set the recipe context limit | /llm set helper context maxrecipes 300 |
The implemented command is
apikey, notapi_key. There are currently no/llm chat,max_tokens, ortop_pcommand nodes.
URL Handling
The URL parser accepts both quoted and unquoted URLs. Quotes are optional unless an argument contains whitespace.
# Both are valid
/llm scan http://192.168.1.50:1234
/llm scan "http://192.168.1.50:1234"
/llm set local url http://localhost:1234/v1/chat/completions
/llm set local url "http://localhost:1234/v1/chat/completions"
/llm scan accepts a base URL, version root, or full endpoint:
/llm scan https://api.openai.com YOUR_API_KEY
/llm scan https://openrouter.ai/api/v1 YOUR_API_KEY
/llm scan "https://openrouter.ai/api/v1/chat/completions" YOUR_API_KEY
/llm scan http://localhost:11434
The optional scan key is used only for that scan and is not saved. If no scan key is provided, ViperLLM does not send the global default key to the scanned host.
Common endpoints include:
- OpenRouter:
https://openrouter.ai/api/v1/chat/completions - OpenAI:
https://api.openai.com/v1/chat/completions - LM Studio:
http://localhost:1234/v1/chat/completions - Ollama:
http://localhost:11434/api/chat - Anthropic:
https://api.anthropic.com/v1/messages
Usage Walkthrough
1. Configure OpenRouter or another cloud provider:
/llm configure cloud
/llm set cloud apikey YOUR_API_KEY
/llm test
/llm ask Hello!
No key is bundled. Set defaultApiKey in the server config or use /llm set <id> apikey <key>.
2. Scan and configure LM Studio:
/llm scan http://192.168.1.50:1234
/llm configure local http://192.168.1.50:1234 qwen3.5-4b
/llm select local
/llm ask What block am I looking at?
With the default security policy, a player must be an operator to use a private/LAN endpoint.
2b. List available models from the endpoint:
/llm set local model list
3. Add custom behavior:
/llm set local prompt You are a redstone expert. Explain circuits simply.
4. Disable command access for your profile:
/llm commands
Global Configuration
Created at config/viperllm.json:
{
"defaultMaxTokens": 500,
"defaultTemperature": 0.7,
"defaultTopP": 1.0,
"defaultProvider": "OPENROUTER",
"defaultModel": "google/gemma-4-31b-it:free",
"defaultUrl": "https://openrouter.ai/api/v1/chat/completions",
"defaultApiKey": "",
"debug": false,
"contextPlayerData": true,
"contextInventory": true,
"contextRecipes": true,
"contextMaxRecipes": 300,
"allowCommandExecution": true,
"allowPrivateNetworkScanning": false,
"allowPrivateNetworkScanningForOperators": true,
"findBlockRadius": 16
}
| Field | Description |
|---|---|
defaultProvider |
Provider type used for default instances |
defaultModel |
Default model identifier |
defaultUrl |
Default full chat endpoint |
defaultApiKey |
Optional global fallback key; empty by default |
defaultSystemPrompt |
(Removed - now hardcoded in mod. User prompts append via /llm set prompt) |
defaultMaxTokens |
Default output-token ceiling |
defaultTemperature |
Default sampling temperature |
defaultTopP |
Default nucleus-sampling value |
debug |
Enables additional diagnostic logging |
contextPlayerData |
Global player-data context default |
contextInventory |
Global inventory context default |
contextRecipes |
Global recipe context default |
contextMaxRecipes |
Global recipe context limit |
allowCommandExecution |
Server-wide master switch for @command; default true |
allowPrivateNetworkScanning |
Allow all players to scan and assign private endpoints; default false |
allowPrivateNetworkScanningForOperators |
Permit operators when general private access is disabled; default true |
findBlockRadius |
Search radius for @find_block tool; default 16 |
Restart the server after editing this file.
Private-Network Protection
Normal players cannot scan or assign endpoints resolving to internal networks unless allowPrivateNetworkScanning is enabled. Operators are allowed by default through allowPrivateNetworkScanningForOperators.
Protected destinations include:
localhost,*.localhost, and*.local127.0.0.0/810.0.0.0/8172.16.0.0/12192.168.0.0/16- Link-local, site-local, CGNAT, benchmark, multicast, and local IPv6 ranges
- Public hostnames that resolve to a protected address
This prevents normal players from turning /llm scan into an internal port scanner while still allowing operators to connect the server to local LM Studio or Ollama installations.
Per-Player Profiles
Profiles are stored at world/viperllm/players/<UUID>.json:
{
"activeInstanceId": "local",
"globalChatToggle": false,
"allowCommandExecution": true,
"chatMode": "PRIVATE",
"instances": {
"local": {
"providerType": "OPENAI",
"apiUrl": "http://192.168.1.50:1234/v1/chat/completions",
"apiKey": "",
"modelName": "qwen3.5-4b",
"systemPrompt": "",
"apiFormat": "openai",
"settings": {
"temperature": 0.7,
"maxTokens": 500,
"topP": 1.0,
"chatPrefix": "7[LLM]f ",
"responseColor": "7",
"memoryTurnLimit": 20,
"timeout": 0
}
}
},
"shortTermMemory": [],
"longTermSummary": ""
}
API keys are stored as plaintext in server-side profiles. Protect the world directory, backups, and command logs.
Tool Reference
| Tool | Arguments | Returns |
|---|---|---|
@player_stats |
None | Dimension, health, food, XP, game mode, and position |
@inventory |
None | Held items, armor, hotbar, and inventory |
@search_recipes |
Item name | Matching recipes (fuzzy fallback suggests close names; supports modded namespace:item). Results use human-readable names. |
@search_items |
Search term | Matching registered item IDs |
@search_blocks |
Search term | Matching registered block IDs |
@biome |
None | Current biome |
@time |
None | Current world time and phase |
@weather |
None | Current weather |
@difficulty |
None | Server difficulty |
@effects |
None | Active effects and durations |
@look |
None | Block targeted by the player |
@standing |
None | Block beneath the player |
@spawn |
None | Spawn or respawn information |
@nearby |
None | Nearby entity counts + what entity the player is looking at |
@enchant |
None | Enchantments on the held item |
@stats |
None | Deaths, damage, kills, play time, and distance |
@advancements |
None | Completed advancements |
@read_book |
None | Title, author, and pages of a book in the player's hands or inventory |
@chest_inv |
None | Inventory of chest/barrel/shulker/hopper/ender chest/minecart with chest the player is looking at |
@read_sign |
None | Text on the front and back of a sign the player is looking at |
@find_block |
Block name | Nearest matching block within findBlockRadius (default 16 blocks) |
@look_around |
None | Biome, position, time, weather, light level, ground block, nearby entities |
@command |
Minecraft command | Executes with the owning player's permission level when both command switches are enabled |
@tools |
None | Lists currently available tools |
Example tool calls:
@search_recipes mace
@search_items diamond
@find_block diamond_ore
@read_book
@chest_inv
@read_sign
@look_around
@command time query daytime
@tools
The mod does not currently expose @get_item, @get_block, @get_entity, @broadcast, @force_reply, @get_online_players, or @get_user_stats handlers.
Command Safety
@command requires both controls:
- Global
allowCommandExecution: true - Player profile
allowCommandExecution: true
Players toggle their profile setting with /llm commands. Commands execute through the owning player's command source. A normal player cannot make the LLM execute /op, /gamemode, or another command that the player could not execute directly.
Important Notes
- No API key is bundled or shared by default.
- Quoted and unquoted URLs are both supported.
/llm configure <id> <url> <model> [api_key]accepts an optional API key at the end./llm set <id> model listprobes the endpoint directly for available models. Models are cached for tab completion.- Scan keys are temporary; instance keys are persisted as plaintext.
- Private endpoints are operator/config restricted by default.
- The model-list book title is truncated to Minecraft's 32-character limit.
- Endpoint probing accepts base URLs and full endpoints.
@commanddefaults to available globally and per player, but never elevates permissions.- Recipe search falls back to fuzzy matching against the full item registry when no exact recipe match is found, supporting modded
namespace:itemqueries. @find_blockuses a single-word argument (e.g.@find_block diamond_ore). Sentences are rejected.
Built for servers that want tool-using AI assistants with no client installation, no bundled secrets, controlled LAN access, and no command-permission escalation.
