A command-line interface for AI agents, built on @ai-zen/agents-sdk and @ai-zen/agents-core. Provides an interactive conversation terminal with built-in file system tools, sub-agent orchestration, and skill management.
npm install -g @ai-zen/cligit clone git@github.com:ai-zen/cli.git
cd cli
pnpm install
pnpm build
npm install -g .# Interactive main menu
zen
# Quick chat (pass message as argument)
zen Hello, introduce yourself.Run zen to enter the main menu:
๐ค Welcome to AI-Zen CLI
? Select an action:
โถ๏ธ Continue last unfinished conversation (if draft exists)
๐ฌ Start a new conversation
๐ Continue a saved conversation
๐ Manage saved conversations
๐ค Manage Agents
โ๏ธ Configuration
โ Exit
If you exit a conversation without saving (or the process is killed), the conversation is automatically saved as a draft. Next time you start zen, you'll see:
โถ๏ธ Continue last unfinished conversation (12 messages, 2025/1/1 12:00:00)
๐ฌ Start a new conversation (discard draft)
While in a conversation, all commands start with /:
| Command | Description |
|---|---|
/exit /quit |
Exit the conversation (prompts to save) |
/save |
Save the current conversation |
/new |
Reset the conversation (clear history) |
/back |
Undo messages (roll back to a specific point and resend) |
/editor |
Open system editor for long-form input |
/clear |
Clear the screen |
/help |
Show available commands |
When the API response's usage.prompt_tokens exceeds the model's maxContextTokens, the system automatically generates a handover document summarizing completed tasks, pending items, and key decisions. A new conversation session is created with this document as context, ensuring seamless continuation.
The migration prompt template includes:
- Conversation Breakpoint โ Last user/AI exchange verbatim
- Completed Tasks โ Task titles and output paths
- Pending Tasks โ Description, progress, next steps
- Important Notes โ Technical preferences, lessons learned, architecture decisions
- File Index โ Key files with descriptions
- Handover Instructions โ SOP for the relay agent (read files first, verify state, then act)
When you type an unrecognized command in your terminal, it can be automatically forwarded to AI for processing:
# Install the hook
zen hook install
# After that, try typing something random:
> what's the weather today?
# This will be forwarded to AI instead of showing "command not found"
# Uninstall
zen hook uninstallConfiguration is stored in ~/.ai-zen/cli/config.json (or $AI_ZEN_DIR/cli/config.json if set). The maxContextTokens field on each model sets the migration threshold (typically ~25% of the model's actual context window, e.g. 250,000 for a 1M-token model).
AI_ZEN_DIRโ Override the shared root directory (default:~/.ai-zen). CLI runtime data goes to$AI_ZEN_DIR/cli/, and shared resources (agents, skills, tools, MCP, etc.) go to$AI_ZEN_DIR/.
~/.ai-zen/ โ Shared root (AI_ZEN_DIR)
โโโ cli/ โ CLI runtime data
โ โโโ config.json โ CLI endpoints, models
โ โโโ conversations/ โ CLI conversations
โ โโโ drafts/ โ CLI drafts
โโโ agents/ โ Agent definitions (shared)
โ โโโ default.json โ Default agent (created on first run)
โ โโโ my-custom-agent.json
โโโ sub-agents/ โ SubAgent definitions (shared)
โ โโโ general-assistant.json โ Default sub-agent (created on first run)
โ โโโ my-coder.json
โโโ skills/ โ Skill directory (shared)
โ โโโ my-skill/
โ โโโ SKILL.md
โโโ tools/ โ User-defined tools (shared)
โ โโโ my-tool.js
โโโ mcp.json โ MCP config (shared)
โโโ mcp-oauth/ โ MCP OAuth tokens (shared)
/path/to/project/
โโโ .mcp.json โ Project-shared MCP config (committable)
โโโ .ai-zen/
โโโ mcp.json โ Project-personal MCP config (not committed)
โโโ skills/ โ Project Skill directory
โ โโโ my-skill/
โ โโโ SKILL.md
โโโ tools/ โ Project tool directory
โ โโโ my-tool.js
โโโ sub-agents/ โ Project SubAgent directory
โ โโโ project-helper.json
โโโ agents/ โ Project Agent directory (overrides user-level)
โโโ project-agent.json
MCP server configurations are merged from multiple sources (high to low priority):
- Project personal
.ai-zen/mcp.json(collected from cwd up to git root) - Project shared
.mcp.json(same) - User-level
~/.ai-zen/mcp.json
Same-named servers in higher priority override lower ones.
The CLI provides 17 built-in file system tools, implemented by @ai-zen/agents-sdk:
| Tool | Description |
|---|---|
cwd |
Get current working directory |
readFile |
Read file contents |
writeFile |
Write content to file |
edit |
Replace text in files (single replacement) |
batchEdit |
Batch replace text in files |
exec |
Execute shell commands |
exec_async |
Execute a shell command asynchronously (returns immediately) |
mkdir |
Create directories |
rm |
Delete files or directories |
glob |
Scan files with glob patterns |
ls |
List directory contents |
exist |
Check if path exists |
findText |
Search text in files |
downloadFile |
Download file from URL |
rename |
Rename or move files |
copy |
Copy files or directories |
sleep |
Wait for a specified number of milliseconds |
Conditionally injected (requires defaultImageModel in config):
| Tool | Description |
|---|---|
generateImage |
Generate images from text |
In addition to built-in tools, the SDK provides 5 dynamic loading tools that are registered based on available resources and permissions:
| Tool | Purpose |
|---|---|
load_skill |
Load a Skill document into context (idempotent, repeated calls skip re-injection) |
call_skill_sub_agent |
Delegate a task to a Skill sub-agent (only works for Skills with sub-agent: true in frontmatter) |
load_mcp |
Connect to an MCP server and list its tools (idempotent, repeated calls skip reconnection) |
call_mcp_tool |
Call a tool on a connected MCP server |
read_mcp_resource |
Read a resource from a connected MCP server |
Tools are assembled in three phases by the SDK's Provider capability pipeline:
- Discovery โ Scan filesystem for built-in tools, user tools, SubAgents, Skills, and MCP servers
- Filtering โ Apply permissions (
allow/deny) and security exclusions (recursion protection) - Instantiation โ Map filtered names to
Toolinstances and register dynamic loaders
Each Agent has independent permissions โ no inheritance between parent Agent and SubAgent. The only exception is the temporary Skill sub-agent (created by call_skill_sub_agent), which inherits the caller's permissions as a transient conversation proxy rather than an independent entity.
interface AgentPermissions {
tools?: { allow: string[] } | { deny: string[] };
skills?: { allow: string[] } | { deny: string[] };
mcps?: { allow: string[] } | { deny: string[] };
subagents?: { allow: string[] } | { deny: string[] };
}- Missing
permissionsfield = all dimensions denied (deny: ["*"]) - Each dimension uses either
allow(whitelist) ordeny(blacklist), mutually exclusive "*"wildcard matches any name- Denied resources are fully invisible to the LLM (not just blocked)
MCP servers are configured in mcp.json files:
{
"mcpServers": {
"my-server": {
"transport": "stdio",
"command": "node",
"args": ["server.js"],
"env": {
"API_KEY": "xxx"
}
}
}
}Connection lifecycle (connect, reconnect with exponential backoff, idle timeout) is fully managed by the SDK's McpConnectionManager.
OAuth 2.0 ๆๆๆต็จ๏ผmcp.json ไธญ็ oauth ๅญๆฎต๏ผๅทฒๅฎไน็ฑปๅๅ้ข็ mcp-oauth/ ๅญๅจ็ฎๅฝ๏ผไฝๅฐๆชๅฎ็ฐใ็ฎๅ้
็ฝฎไบ oauth ็ HTTP MCP ๆๅกๅจๅฐๅ ็ผบๅฐ token ่่ฟๆฅๅคฑ่ดฅใ
| ID | Name | Default Base URL |
|---|---|---|
openai |
OpenAI | https://api.openai.com/v1 |
bigmodelcn |
BigModelCN (ZhipuAI) | https://open.bigmodel.cn/api/paas/v4 |
deepseek |
DeepSeek | https://api.deepseek.com/v1 |
| ID | Name | Endpoint |
|---|---|---|
gpt-5.5 |
GPT-5.5 | OpenAI |
glm-5.2 |
GLM-5.2 | ZhipuAI |
glm-5.1 |
GLM-5.1 | ZhipuAI |
glm-5 |
GLM-5 | ZhipuAI |
glm-5-turbo |
GLM-5-Turbo | ZhipuAI |
glm-5v-turbo |
GLM-5V-Turbo | ZhipuAI |
glm-4.7-flash |
GLM-4.7-Flash | ZhipuAI |
deepseek-v4-pro |
DeepSeek-V4-Pro | DeepSeek |
deepseek-v4-flash |
DeepSeek-V4-Flash | DeepSeek (default) |
pnpm install
pnpm build
pnpm start# Unit tests
pnpm test
# E2E tests (requires API key in .env.local)
pnpm test -- src/__tests__/e2e.test.tsISC
{ "endpoints": [ { "id": "openai", "name": "OpenAI", "apiKey": "sk-xxx", "baseUrl": "https://api.openai.com/v1" } ], "models": [ { "id": "gpt-5.5", "name": "GPT-5.5", "endpointId": "openai", "modelName": "gpt-5.5", "maxContextTokens": 250000 } ], "imageModels": [ { "id": "cogview-3", "name": "CogView-3", "endpointId": "bigmodelcn", "modelName": "cogview-3", "defaultSize": "1024x1024" } ], "defaultModel": "deepseek-v4-flash", "defaultImageModel": "cogview-3", "defaultAgent": "default", "defaultMigrationModel": "deepseek-v4-flash" }