ChatChain
A lightweight, cross-platform AI chat CLI built with Go. Supports multiple providers, streaming responses, file attachments, and an interactive terminal UI.
Features
- Multi-provider — OpenAI, OpenAI Responses API, Anthropic, Gemini, Vertex AI, and OpenClaw, with custom base URL support
- Interactive model selection — arrow-key navigation with filtering
- Streaming responses — real-time token output with loading spinner
- File attachments — send images, PDFs, and text files alongside messages with Tab-completion for file paths
- Non-interactive mode — single message in, response out, pipe-friendly
- Conversation history — full context maintained within a session
- System prompt — set via flag or interactive input
- Config file — persistent API keys, default models, and custom provider aliases via
~/.chatchain.yaml
- Styled terminal output — color-coded prompts
Install
Homebrew (macOS)
brew tap joyqi/tap
brew install chatchain
Go
go install github.com/joyqi/chatchain@latest
Build from source
git clone https://github.com/joyqi/chatchain.git
cd chatchain
go build -o chatchain .
Claude Code Plugin
ChatChain provides a Claude Code plugin, allowing you to call other LLMs directly within Claude Code.
Plugin Install
# Add the marketplace
/plugin marketplace add joyqi/chatchain
# Install the plugin
/plugin install chatchain@chatchain-marketplace
Plugin Usage
Slash command — manually ask another LLM:
/chatchain:ask openai gpt-4o "What is the meaning of life?"
/chatchain:ask anthropic claude-sonnet-4-20250514 "Explain monads"
/chatchain:ask gemini "Write a haiku"
Agent skill — Claude automatically uses ChatChain when you ask it to query another LLM:
> Use chatchain to ask GPT what is 1+1
> Ask Gemini to explain quicksort via chatchain
Local Testing
claude --plugin-dir ./chatchain-plugin
Usage
chatchain [openai|anthropic|gemini|vertexai|openresponses|openclaw] [flags]
Flags
| Flag | Short | Description |
|---|
--key | -k | API key (or set via env var) |
--url | -u | Custom base URL |
--model | -M | Model name (skip interactive selection) |
--temperature | -t | Sampling temperature, 0.0-2.0 (omit to use provider default) |
--message | -m | Send a single message and print the response (non-interactive, use - to read from stdin) |
--system | -s | System prompt (omit value for interactive input) |
--list | -l | List configured providers, or models for a given provider |
--config | -c | Path to config file (default: ~/.chatchain.yaml) |
--verbose | -v | Print HTTP request/response bodies for debugging |
Environment Variables
| Variable | Provider |
|---|
OPENAI_API_KEY | OpenAI / OpenResponses |
ANTHROPIC_API_KEY | Anthropic |
GOOGLE_API_KEY | Gemini / Vertex AI |
OPENCLAW_GATEWAY_TOKEN | OpenClaw |
Config File
ChatChain supports YAML config files for persistent settings and custom provider aliases.
Config Lookup Order
~/.chatchain.yaml or ~/.chatchain.yml (global)
./.chatchain.yaml or ./.chatchain.yml (project-local, merges over global)
-c/--config <path> (explicit, highest priority, used alone)
Same-name providers in later files override earlier ones.
Priority
For individual values: CLI flag > env var > config file.
Example
# ~/.chatchain.yaml
providers:
openai:
key: sk-official
model: gpt-4o
deepseek: # custom alias
type: openai # underlying provider type
key: sk-deepseek-xxx
url: https://api.deepseek.com/v1
model: deepseek-chat
system: "You are a helpful coding assistant"
claude:
type: anthropic
key: sk-ant-xxx
model: claude-sonnet-4-20250514
With this config:
# Use the "deepseek" alias — resolves to OpenAI provider with DeepSeek's key/URL/model
chatchain deepseek -m "hello"
# Config key used, no need for -k
chatchain openai -m "hi" -M gpt-4o
# CLI flag overrides config
chatchain openai -k sk-override -m "hi" -M gpt-4o
Chat Commands
In interactive mode, the following commands are available:
| Command | Description |
|---|
/file <path> | Attach a file (image, PDF, or text). Supports Tab completion for file paths. |
/files | List all currently attached files |
/clear | Remove all attached files |
/save [path] | Save conversation history to a Markdown file (default: history.md) |
/import [path] | Import conversation history from a saved Markdown file (default: history.md) |
Attached files are sent with your next message, then cleared automatically.
Supported File Types