Skip to content

Repository files navigation

GTerm

Garry's Mod external console software. WindowsTerminal_2025-12-21_19-19-37 WindowsTerminal_2025-12-21_19-19-21 WindowsTerminal_2025-12-21_19-19-31

Client Installation

  • Download the latest release.
  • Launch the gterm executable whenever Garry's Mod is running.
  • Restart Garry's Mod to complete the installation.
  • Enjoy!

Server Installation (steamcmd)

  • Download the latest release of gterm.
  • Move the .dll (even on macos/linux!) under srcds/garrysmod/lua/bin (if the bin folder doesnt exist, create it).
  • In srcds/garrysmod/lua/includes/init.lua add at the top of the file require("gterm").
  • Restart the server.
  • Launch the gterm executable.
  • Enjoy!

IMPORTANT NOTE: GTerm communicates with the gmod module over a localhost TCP socket (127.0.0.1:27514), so GTerm must run on the same host as the server. If you run your server inside a docker container or any other sandbox, run GTerm inside that same sandbox (or otherwise share the loopback interface).

In case GTerm does NOT detect your Garry's Mod CLIENT installation

  • Download the latest release of gterm.
  • Move the .dll (even on macos/linux!) under GarrysMod/garrysmod/lua/bin (if the bin folder doesnt exist, create it).
  • In GarrysMod/garrysmod/lua/menu/menu.lua add at the bottom of the file require("gterm").
  • Restart Garry's Mod.
  • Voila!

WebSocket API

GTerm includes a WebSocket server for console streaming and command execution.

Setup:

  1. Enable API in Config.json: "API": true
  2. Connect WebSocket clients to ws://localhost:27512/ws/

Configuration Options:

{
  "API": true,
  "APIPort": 27512,
  "APISecret": "your_secret_here"
}

Example Payloads:

Sending commands (text message):

status

Receiving console output (JSON):

{
  "Time": 1704123456,
  "Data": [
    {
      "Color": { "R": 255, "G": 255, "B": 255, "A": 255 },
      "Text": "hostname: My Server\n"
    }
  ]
}

MCP Server Integration

GTerm includes an MCP (Model Context Protocol) server for AI agents such as Cursor, Vscode, Zed, Claude Code, etc..

Setup:

  1. Enable MCP in Config.json: "MCP": true
  2. (Optional) Set "MCPSecret" for authentication
  3. Configure your MCP client to connect to http://localhost:27513 (add ?secret=... if using authentication)

Available Tools:

  • get_game_status - Report whether GMod is connected, in a session, and which Lua realms can run code right now (map, gamemode, players). Works even while GMod is closed. Agents should call this first.
  • run_gmod_command - Execute a console command and capture its output
  • execute_lua_code - Execute Lua in a required realm (server or client).
  • validate_lua_syntax - Compile-check Lua with the game's own CompileString without executing it
  • check_game_file - Ask the running game whether a path exists in its virtual filesystem (mounted addons/GMAs included), not just on disk
  • capture_console_output - Monitor console output for a duration
  • list_gmod_directory - Browse the Garry's Mod file structure on disk
  • read_gmod_file - Read a text file from the installation on disk
  • read_game_file - Read a file's contents from the running game's virtual filesystem (mounted addons, Workshop GMAs), which the on-disk reader can't see
  • take_screenshot_region - Capture one rectangle of the screen and return it enlarged, so a HUD element, viewmodel or panel is actually legible. Preferred over the full-screen shot for anything specific
  • take_screenshot - Capture the whole screen. Last resort: prove things with Lua state and arithmetic first
  • read_gmod_wiki - Fetch a page from the Garry's Mod wiki (wiki.facepunch.com/gmod) to check a function's real signature before using it
  • list_tool_packages - Lists all the third party tools provided by addons in lua/gterm_packages/*.lua (see below)
  • request_tool_packages - Ask the user, in GTerm's own console, which packages to enable. The agent cannot choose by itself
  • call_package_tool - Run one tool from an enabled package with a JSON args object

Every tool result is prefixed with a [GTerm] status line so the agent always knows the connection and realm state. When a precondition is not met (disconnected, wrong realm, no session), the tool returns an error explaining what to do rather than failing silently; pass force: true to attempt the call anyway.

Seeing what an agent is doing. MCP clients show the tool name but usually not the arguments, so GTerm surfaces them itself: every tool call prints a magenta [agent] line in GTerm's console before it runs. Lua is shown in full on its own lines with Monokai syntax highlighting, and console commands are highlighted inline.

MCP Tool packages (opt-in)

Addons and servers can provide their own tools to the agent as Lua files at lua/gterm_packages/<package>.lua. GTerm discovers and loads packages with client-realm Lua (sv_allowcslua must be 1).

Enabling is done manually in GTerm's console using packages in GTerm, or when the agent calls request_tool_packages. Consent is stored in Config.json under ToolPackageConsent per scope (server IPv4, or local for listen servers and singleplayer).

The file returns a table: optional description, optional server (IPv4; only usable on that server), and tools. Each tool has name ([a-z][a-z0-9_]*), description, inputSchema (JSON schema, type = "object"), optional realm ("client", the default, or "server"), and run(args). Its return value (string or table) comes back as the result, capped at 4096 characters by print. Limits: 32 tools, 512-character descriptions, 8 KB input schema, 256 KB definition. Package names: [a-z0-9][a-z0-9_-]{0,63}.

Example lua/gterm_packages/my_addon.lua:

return {
    description = "Helpers for my addon.",
    tools = {
        {
            name = "find_entities",
            description = "Lists entities of a class near the local player.",
            inputSchema = {
                type = "object",
                properties = {
                    class = { type = "string", description = "Entity class, e.g. prop_physics" },
                    radius = { type = "number", description = "Search radius in units (default 512)" },
                },
                required = { "class" },
            },
            run = function(args)
                local out = {}
                for _, e in ipairs(ents.FindInSphere(LocalPlayer():GetPos(), args.radius or 512)) do
                    if e:GetClass() == args.class then out[#out + 1] = { id = e:EntIndex(), pos = tostring(e:GetPos()) } end
                end
                return out
            end,
        },
        {
            name = "count_props",
            description = "Counts props on the server (listen server or singleplayer only).",
            inputSchema = { type = "object" },
            realm = "server",
            run = function() return #ents.FindByClass("prop_physics") end,
        },
    },
}

Configuration Options:

{
  "MCP": true,
  "MCPPort": 27513,
  "MCPCollectionWindowMs": 1000,
  "MCPSecret": "your_secret_here"
}

MCP Client Example (with secret):

{
  "mcpServers": {
    "gterm": {
      "url": "http://localhost:27513?secret=your_secret_here"
    }
  }
}
image image

About

Garry's Mod external console software with MCP and Websocket support.

Topics

Resources

Stars

26 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages