GPT Commander
# GPT Commander: An LLM-Facing Software Engineering Substrate
[](https://github.com/PushPullCommitPush/GPT-Commander---An-LLM-facing-software-engineering-substrate/actions/workflows/ci.yml)
[](LICENSE.md)
GPT Commander is a security-first MCP server that gives LLMs a safe, structured way to operate on a developer environment. It provides filesystem, process, and search tools; opinionated build/test/lint primitives; optional IDE-native context via VS Code; and integrations for CLI runners and memory stores.
This repo is intentionally "LLM-native": the tool surface is constrained, named, and predictable so models can operate reliably without improvising shell commands.
## Why this exists
- LLMs are best when the action space is **small, stable, and explicit**.
- Most existing "terminal helpers" are too permissive or too brittle.
- The difference between "helper" and "pair programmer" is **IDE context** and **safe primitives**.
## Feature highlights (all the bells + whistles)
- **Security guardrails**: path allowlist, command blocklist, read/write limits, binary file sniffing.
- **Process management**: start, interact, read output, kill; TTL auto-prunes long-running sessions.
- **Search + edits**: ripgrep-backed search + targeted block replacement.
- **Opinionated primitives**: `run_tests`, `lint`, `build`, `typecheck`, `dev_server_start`, etc.
- **IDE bridge (VS Code)**: diagnostics, symbols, references, workspace edits, and unsaved buffers.
- **CLI wrappers**: safe runners for Codex, Claude, and Gemini CLIs.
- **Memory MCP**: a `memory_note` tool that stores ad hoc notes externally.
- **Telemetry**: optional tool/command metrics + JSONL event log.
- **Onboarding gate**: mandatory obstacle course to ensure the model is actually calling tools correctly.
- **HTTP/SSE or stdio**: run as a local stdio MCP or as a URL-based SSE MCP.
---
## Requirements
- Node.js >= 18
- ripgrep (`rg`) on PATH (recommended for `start_search`)
## Install
```bash
npm install
npm run build
```
---
## Run: Stdio MCP (local clients)
Add to your MCP config (e.g. GPT Desktop, Claude Desktop, Codex, etc.):
```json
{
"mcpServers": {
"gpt-commander": {
"command": "node",
"args": ["/path/to/dist/index.js"],
"env": {
"GPT_DC_CONFIG": "/optional/custom/config.json"
}
}
}
}
```
## Run: HTTP/SSE MCP (URL clients)
```bash
npm run build
node dist/sse.js
```
Then point your MCP client at:
```
http://127.0.0.1:3333/mcp
```
If you are using a reverse proxy or tailnet URL, set an absolute endpoint:
```bash
GPT_DC_HOST=127.0.0.1 GPT_DC_PORT=3333 \
GPT_DC_ABSOLUTE_ENDPOINT="https://your-host.example/desktop" \
node dist/sse.js
```
---
## Ollama MCP (optional)
This repo includes a standalone MCP server that exposes local Ollama via tools.
```bash
npm run build
OLLAMA_HOST="http://127.0.0.1:11434" node dist/ollama-mcp.js
```
Tools:
- `ollama_list_models`
- `ollama_show_model`
- `ollama_generate`
- `ollama_chat`
Optional env:
- `OLLAMA_HOST` (default `http://127.0.0.1:11434`)
- `OLLAMA_TIMEOUT_MS` (default `120000`)
---
## OpenWebUI tool (sparse + CLI)
OpenWebUI Function plugin that bridges to Commander MCP with a minimal tool list plus CLI wrappers.
- File: `openwebui/commander_mcp_bridge.py`
- Setup: `openwebui/README.md`
---
## Configuration
Default config is created at `~/.gpt-desktop-commander/config.json`.
```json
{
"allowedDirectories": ["$HOME"],
"blockedCommands": ["rm", "shutdown", "reboot", "mkfs", "mount", "umount"],
"fileReadLimitBytes": 10485760,
"fileWriteLineLimit": 10000,
"defaultShell": "$SHELL",
"enableShell": true,
"telemetryEnabled": false,
"telemetryLogFile": "$HOME/.gpt-desktop-commander/telemetry.jsonl",
"telemetryMaxEvents": 200,
"processTtlMinutes": 480,
"onboarding": {
"enabled": true
},
"memoryMcp": {
"enabled": false,
"url": "",
"defaultType": "note",
"defaultScope": "",
"defaultTags": [],
"defaultTtlDays": 0
},
"ideBridge": {
"enabled": false,
"host": "127.0.0.1",
"port": 7311,
"token": "<generated>",
"requestTimeoutMs": 15000,
"originAllowlist": []
}
}
```
Set `GPT_DC_CONFIG` to point at a specific config file. The config is loaded at server start, so **restart the server** to apply changes.
---
## Onboarding gate (mandatory)
When `onboarding.enabled` is true, all tool **calls** are gated until onboarding completes. The tool list is still visible so the model can discover `commander_onboard`.
Onboarding steps:
1) `commander_onboard`
2) `tools/list`
3) `list_directory`
4) `start_search`
5) `commander_finish`
This ensures the model has proven it can execute tools correctly before getting full capabilities.
---
## IDE Bridge (VS Code)
The IDE bridge exposes LSP-grade context: diagnostics, symbols, references, workspace edits, and unsaved buffers.
1) Enable in config:
```json
{
"ideBridge": {
"enabled": true,
"host": "127.0.0.1",
"port": 7311,
"token": "YOUR_TOKEN"
}
}
```
2) Install the VS Code extension from the `vscode-extension/` folder.
3) Set VS Code settings:
```
gptDesktopCommander.bridgeUrl = "ws://127.0.0.1:7311"
gptDesktopCommander.bridgeToken = "YOUR_TOKEN"
```
4) Use `ide_list_workspaces()` to get the `workspaceId`, then call:
- `ide_get_diagnostics`
- `ide_symbol_search`
- `ide_find_references`
- `ide_read_buffer`
- `ide_apply_workspace_edit`
---
## Opinionated primitives (Node + Python)
The `project_info` tool detects project language and tooling. Primitives use the best available commands:
### Node/TypeScript
Detection:
- `package.json`, lockfiles for npm/yarn/pnpm
- `tsconfig*.json` for typecheck
Commands:
- `run_tests`: `npm run test` or local `vitest/jest/mocha/ava`
- `lint`: `npm run lint` or local `eslint/biome`
- `format`: `npm run format` or local `prettier/biome`
- `typecheck`: local `tsc/vue-tsc --noEmit`
- `dev_server_start`: `npm run dev` or `npm run start`
### Python
Detection:
- `pyproject.toml`, `requirements.txt`, `setup.py`
- `uv`, `poetry`, or `pip`
Commands:
- `run_tests`: `pytest`
- `lint`: `ruff check .`
‑ `format`: `ruff format .` or `black .`
‑ `typecheck`: `mypy .`
---
## CLI wrappers (Codex, Claude, Gemini)
Set the paths and the CLI wrappers become tools:
```bash
CODEX_PATH=/opt/homebrew/bin/codex
CLAUDE_PATH=$HOME/.local/bin/claude
GEMINI_PATH=/opt/homebrew/bin/gemini
GEMINI_WORKDIR=$HOME/gemini-work
```
Tools:
- `codex_run(args?, cwd?, env?, timeoutMs?, maxBufferBytes?, input?)`
- `claude_run(args?, cwd?, env?, timeoutMs?, maxBufferBytes?, input?)`
- `gemini_run(args?, cwd?, env?, timeoutMs?, maxBufferBytes?, input?)`
---
## Memory MCP integration
`memory_note` writes to a separate Memory MCP (e.g. `memory.write`).
Config:
```json
{
"memoryMcp": {
"enabled": true,
"url": "https://memory.example/mcp",
"defaultType": "note"
}
}
```
Tool:
```
memory_note { "content": "...", "type": "note", "tags": ["ops"] }
```
---
## Telemetry
When enabled, `get_metrics` returns totals and recent events for:
- tool calls
- command exits
- durations
- error counts
Optional JSONL logging is written to `telemetryLogFile`.
---
## Tool surface
Core tools:
- `commander_onboard`
- `commander_finish`
- `get_metrics`
- `memory_note`
- `list_directory`, `read_file`, `write_file`, `get_file_info`
- `start_process`, `interact_with_process`, `read_process_output`, `list_sessions`, `kill_process`
- `start_search` (ripgrep)
- `edit_block`
IDE tools:
- `ide_list_workspaces`, `ide_get_diagnostics`, `ide_symbol_search`, `ide_find_references`
- `ide_read_buffer`, `ide_apply_workspace_edit`
Primitives:
- `project_info`
- `run_tests`, `run_unit_tests`, `run_integration_tests`
- `lint`, `format`, `typecheck`, `build`
- `dev_server_start`, `dev_server_stop`
Dev helpers:
- `git_status`, `git_diff`, `git_commit_prepare`
- `search_code`, `find_symbol`, `open_file_at_line`
---
## Environment variables
Server:
- `GPT_DC_CONFIG` (config path override)
- `GPT_DC_HOST`, `GPT_DC_PORT` (SSE bind)
- `GPT_DC_TAILNET_HOST` (allowed host list)
- `GPT_DC_ABSOLUTE_ENDPOINT` (absolute base for SSE rewrite)
- `GPT_DC_TLS_KEY`, `GPT_DC_TLS_CERT` (optional HTTPS)
CLI wrappers:
- `CODEX_PATH`, `CLAUDE_PATH`, `GEMINI_PATH`, `GEMINI_WORKDIR`
---
## Security model
- **Path allowlist**: every FS op is resolved inside `allowedDirectories` using realpath.
- **Command blocklist**: hard-fails dangerous commands before spawn.
- **Read/write limits**: prevents giant file operations.
- **Binary detection**: rejects non-text reads by default.
- **Process TTL**: prevents zombie processes from lingering.
---
## Troubleshooting
- **Tool not found**: ensure you are calling tools by name via `tools/call`, not `/Commander/link_*`.
- **Tool list stale**: start a new chat to refresh the tool registry.
- **CLI tool missing**: verify the `*_PATH` env var is set before server start.
- **IDE bridge offline**: confirm VS Code extension is running and token matches.
- **SSE origin mismatch**: set `GPT_DC_ABSOLUTE_ENDPOINT` for proxy/tailnet URLs.
---
## Roadmap ideas
- Append-only audit log
- Rich search (glob + ignore support)
- Safer structured edits (range-based)
- Per-tool rate limits
---
## License
PolyForm Noncommercial 1.0.0. See `LICENSE.md`.
TDQS
Scored across 40 tools
Several tools have overlapping purposes: start_search and search_code both use ripgrep, and ide_symbol_search and find_symbol both use the IDE/LSP symbol index. This creates ambiguity in tool selection, especially for agents trying to choose the right search or symbol tool.
Most tools follow a verb_noun snake_case pattern (e.g., read_file, kill_process, list_sessions, dev_server_start). However, memory_note is a noun phrase rather than a verb, and a few tools are bare verbs (lint, format, build), creating minor inconsistency.
At 40 tools, the surface is very large. While the server aims to cover many domains, there are redundant tools (e.g., start_search/search_code, ide_symbol_search/find_symbol) that inflate the count and could be consolidated, making the tool set feel heavy and less focused.
Core workflows such as file operations, process management, IDE integration, and project commands are well covered. However, there are notable gaps: no file delete/rename, no memory retrieval (only memory_note), and git tools stop short of an actual commit, leaving some workflows incomplete.