The agent CLIs are useful, and they are a poor thing to install on every laptop. Each machine needs its own login, its own copy of grok or claude, and a key that should never have left the server. A team that wants one subscription, a token budget, and a single outbound proxy ends up repeating that setup per person.
Remote LLM Gateway (https://github.com/AlanForester/remote-llm-gateway) keeps the project on the machine where the person is editing, and runs the agent on a server. The VS Code and Cursor plugin and the remote-llm CLI are thin clients. They speak ACP over a WebSocket. They do not call Grok, Claude, or OpenAI themselves. The gateway starts the agent, holds the keys, and writes the resulting edits back into the local tree.
This project is not affiliated with or endorsed by xAI, Anthropic, OpenAI, or Meta. The names Grok, Grok Build, Claude Code, Codex, and Muse Code are used only to describe compatibility.
What stays local
Open a repository in the editor, or cd into it and run remote-llm. At the start of a session the client copies the workspace to a directory that belongs to that session. After the reply, changed files come back.
The path on your laptop is only a key for that directory. The gateway does not clone your remote and does not open a checkout on the server at the path you sent. Commands the agent runs happen inside the session directory.
Gitignored files stay behind, and so do dependency trees such as node_modules and vendor. A single file larger than 1 MB is skipped. The rest is uploaded in chunks, so a workspace that does not fit in one HTTP request still gets a session. There is a cap on the session copy: 20,000 files and 256 MB. Past that cap the overflow is skipped and the chat says so, instead of refusing the prompt.
--no-sync on the CLI leaves the project entirely local. The plugin has no local grok or claude process to fall back on. If the gateway is down, the chat is down.
One subscription, several people
Every user connects to the same gateway. A session id is the user plus the project, on wss://<gateway>/ws/{sessionId}. The token travels in the Authorization header, not in the URL.
An administrator creates the user and sees the access token once. From the admin UI they can pin a model, set a token limit, choose when the counter resets (a day, a week, a month, or a custom interval), and set the outbound proxy. Without a pinned model, the person picks one in the client. With a pin, the plugin and the CLI show that model and do not offer a different one.
The limit counts tokens for the current period. When it is spent, new requests stop until the period ends and the counter resets. Older usage stays in the admin view.
Provider traffic leaves the server through the proxy configured in the admin UI or in .env. Changing the address changes the exit path. The service does not need a rebuild.
Sign-in for Claude and the other provider CLIs happens on the gateway machine. A login from a laptop does not authorize the agent, because the agent is not running there.
Three backends, one protocol
| Agent | On the server |
|---|---|
| Grok Build |
grok agent serve, ACP over WebSocket |
| Claude Code | claude agent serve |
| GPT | OpenAI Responses API and tool calling inside the gateway |
Grok Build and Claude Code bring their own tools and read MCP configuration from the gateway host. GPT has no separate Codex process. The gateway implements the tools: read, write, and show files in the session directory, and run a command there. Extra tools can be added from stdio MCP servers listed in MCP_CONFIG. The command environment is a short allow-list. Gateway secrets such as ADMIN_TOKEN, OPENAI_API_KEY, and REDIS_URL are not passed through.
The same three entry points sit in front of that:
- The plugin is a chat in the right sidebar of VS Code or Cursor. Set
remoteLlm.gatewayUrl, store the token in Secret Storage, and open the chat. The command palette titles are currently Russian: «Remote LLM: задать токен», «Remote LLM: открыть чат», and «Remote LLM: показать назначенную модель». -
remote-llmis the terminal client. Point it at the same gateway with--tokenorGATEWAY_TOKEN. The short namellmis intentionally unused. - The admin UI is users, tokens, models, limits, and usage. It listens on port 8081 when you run it locally.
apiaccepts calls with user tokens.gatewayaccepts the agent sessions.
The chat UI is based on GUI for Grok Build & Muse Code. That project has its own license. This repository is MIT.
Try it
Release v0.1.2 (https://github.com/AlanForester/remote-llm-gateway/releases/tag/v0.1.2) has remote-llm binaries, a .vsix, and container images. The plugin is not in the Marketplace yet. Install the .vsix from that release, or run the services from source:
cp .env.example .env
# set ADMIN_TOKEN in .env
set -a && source .env && set +a
go run ./gateway/cmd/gateway
go run ./admin/cmd/admin
go run ./api/cmd/api
Create a user at http://127.0.0.1:8081, then:
go run ./cmd/remote-llm --gateway http://127.0.0.1:8080 --token <token>
GATEWAY_ECHO=1 answers with an echo and does not need grok or claude installed. Unset it when you want a real agent. For a single host, deploy/docker-compose.yml brings up Redis, the three processes, nginx, Prometheus, and Grafana. Nginx is the public door: the admin UI on /, the gateway on /v1/ and /ws/, the API on /api/. The processes themselves listen on localhost.
A local go run without Redis stores users, limits, and the proxy in DATA_FILE. WebSocket sessions are not written to Redis. A restart drops a live conversation.
What this does not do
The gateway is a shared place to run agents you already pay for. It is not a new model, and it does not move the editor to the server. Provider login belongs on the gateway host. GPT goes through the Responses API in-process, so there is no Codex CLI in the loop. The plugin is distributed as a .vsix in the GitHub release until it is published to the Marketplace.
The code, the plugin, and the deploy files are at https://github.com/AlanForester/remote-llm-gateway. If the project is useful, star it: https://github.com/AlanForester/remote-llm-gateway/stargazers.
Top comments (0)