This is a command line client for using LLMs over OpenAI-compatible APIs. You can easily ask questions (responses are streamed in real time), tweak system prompt (or other params), include local files, pipe the response and ask follow up questions.
demo.mp4
Installation
go install github.com/edofic/llm-cli@latest
Usage
It uses the API so you need to provide your own token via OPENAI_API_KEY environment variable.
export OPENAI_API_KEY=your_api_keyWithout any params the arguments (plural, you can omit the quotes) are taken to be your message
$ llm-cli 'what is the capital of france?'
The capital of France is Paris.Note responses are streamed as they are generated (just as on the web UI) which gives you something almost immediately even for longer responses.
Reading from stdin
Pass - as the message to read the prompt from stdin. Useful for piping in content.
$ cat notes.txt | llm-cli -Tuning the response
Two flags let you tune the model output:
-maxTokenssets the maximum number of tokens to generate (default500)-temperaturesets the sampling temperature (default0)
$ llm-cli -maxTokens 2000 -temperature 0.7 'write a short poem about Go'Interactive mode
If you invoke the CLI without a message, it drops into an interactive REPL. Type a message and press Enter to send; the response streams back and the session stays open for follow-ups. Press Ctrl-D (or Ctrl-C) to exit.
$ llm-cli > what is the capital of france? The capital of France is Paris. > and germany? The capital of Germany is Berlin. >
Flags like -c, -systemMsg, and -includeFile work the same way in interactive mode. -includeFile loads the file as initial context before the first prompt. Each exchange is saved to the session file, so you can resume later with -c.
Follow up questions
You can pass -c to continue last session and ask follow up questions.
$ llm-cli -c 'what about germany?'
The capital of Germany is Berlin.Session is stored in /tmp/llm-cli-last-session.json - there is only one "last session".
System message
You can configure the system prompt and tweak behavior this way
$ llm-cli -systemMsg 'You are an assistant that speaks like Shakespeare.' 'what is the capital of france?' The fair capital of France is known as Paris, my would-be lord.
Files
You can pass in local files as additional messages
$ llm-cli -includeFile main.go 'what is this in one sentence?' This is a Go programming language script that uses an OpenAI-compatible API to provide a command-line interface for interacting with AI language models.
Or you can store the output
llm-cli 'write a dockerfile for a Go program, omit any explanation' | tee Dockerfile FROM golang:latest WORKDIR /app COPY . . RUN go build -o myApp . CMD ["./myApp"]
Model versions
Currently this tool defaults to gpt-5.4-mini.
You can override the model with the -model flag or the OPENAI_MODEL environment variable (the flag takes precedence):
llm-cli -model gpt-4o 'explain this'export OPENAI_MODEL=gpt-4oCustom API endpoint
To point at any OpenAI-compatible API (e.g. a local LLM server or a proxy), set OPENAI_ENDPOINT:
export OPENAI_ENDPOINT='http://localhost:8080/v1'
Agentic mode
Pass -agent to give the model tools it can call to accomplish multi-step tasks. The model loops autonomously, calling tools and feeding results back, until it decides it is done.
$ llm-cli -agent 'add a TODO comment at the top of main.go' tool call read("main.go") tool call edit("main.go") Done. Added a TODO comment at the top of main.go.
Each tool call is printed to stdout as it happens so you can follow along.
Available tools
| Tool | What it does |
|---|---|
read |
Read a local file, with optional line offset and limit |
write |
Create a new file (fails if it already exists) |
edit |
Replace an exact string inside an existing file (fails if not found or not unique) |
bash |
Run a shell command and return combined stdout+stderr (disabled by default; see below) |
Bash tool and sandboxing
The bash tool is disabled by default. Enable it with -tool-mode:
# Sandboxed: cwd read/write only, no network, uses fence llm-cli -agent -tool-mode=safe 'run the tests and fix any failures' # Unrestricted: full filesystem and network access llm-cli -agent -tool-mode=unsafe 'set up the project dependencies'
safe mode uses fence to enforce:
- filesystem writes restricted to the current directory
- filesystem reads restricted to the current directory (system paths blocked)
- all outbound network blocked
unsafe gives the model a plain sh -c with no restrictions. Use it only when you trust the task and the model output.
Customising the sandbox with fence.jsonc
When -tool-mode=safe is active, llm-cli looks for a fence.jsonc in the current directory (and walks up to the user config at ~/.config/fence/fence.jsonc). Settings there are merged on top of the defaults, so you can poke holes without switching to unsafe:
See the fence documentation for the full config reference.
Configuration reference
Flags
| Flag | Default | Description |
|---|---|---|
-maxTokens |
8192 |
Maximum number of tokens to generate |
-temperature |
0 |
Sampling temperature |
-model |
"" |
Model to use (overrides OPENAI_MODEL) |
-systemMsg |
"" |
System message to include with the prompt |
-includeFile |
"" |
File to include as an additional user message |
-pretty |
auto | Render markdown; defaults to true when stdout is a TTY |
-c |
false |
Continue last session |
-agent |
false |
Enable agentic mode (read/write/edit tools) |
-tool-mode |
off |
Bash tool: off, safe (fence-sandboxed), unsafe |
Environment variables
| Variable | Description |
|---|---|
OPENAI_API_KEY |
API key (required) |
OPENAI_MODEL |
Override the default model (gpt-5.4-mini) |
OPENAI_ENDPOINT |
Base URL for an OpenAI-compatible API (e.g. http://localhost:8080/v1) |