ACLI-代理CLI
 ](https://www.npmjs.com/package/@lifeprompt/acli) 
美国寿险业协会 (Agent CLI)是基于MCP(模型上下文协议)构建的AI代理的轻量级CLI协议。
为什么选择ACLI?
传统的MCP工具定义需要为每个工具提供广泛的模式,消耗了宝贵的上下文窗口空间。ACLI通过以下方式解决了这个问题:
- 每个域一个工具:一个MCP工具(例如。,
math,calendar)处理相关命令 - 动态发现:代理通过以下方式学习命令
help和schema - 无壳安全:不执行shell,防止注入攻击
- 类型安全参数:基于Zod的验证,带有完整的TypeScript推理
- CLI和MCP双重支持:用作MCP工具或独立CLI
安装
npm install @lifeprompt/acli zod
# or
pnpm add @lifeprompt/acli zodhttps://github.com/user-attachments/assets/c4b2a395-446c-4178-b552-9868ee40403c
快速开始
MCP服务器集成
import { z } from "zod"
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import { registerAcli, defineCommand, arg } from "@lifeprompt/acli"
// Use defineCommand() for full type inference in handlers
const add = defineCommand({
description: "Add two numbers",
args: {
a: arg(z.coerce.number(), { positional: 0 }),
b: arg(z.coerce.number(), { positional: 1 }),
},
handler: async ({ a, b }) => ({ result: a + b }), // a, b are inferred as number
})
const multiply = defineCommand({
description: "Multiply two numbers",
args: {
a: arg(z.coerce.number(), { positional: 0 }),
b: arg(z.coerce.number(), { positional: 1 }),
},
handler: async ({ a, b }) => ({ result: a * b }),
})
const commands = { add, multiply }
const server = new McpServer({ name: "my-server", version: "1.0.0" })
// Register as "math" tool
registerAcli(server, "math", commands, "Mathematical operations.")
// → Tool description: "Mathematical operations. Commands: add, multiply. Run 'help' for details."AI代理如何调用ACLI工具
一旦注册,AI代理(如Claude)就会使用 command 字符串:
// Tool call from AI agent
{
"name": "math",
"arguments": {
"command": "add 10 20"
}
}
// Response
{
"content": [{ "type": "text", "text": "{\"result\":30}" }]
}// Discovery - agents can explore available commands
{ "name": "math", "arguments": { "command": "help" } }
{ "name": "math", "arguments": { "command": "help add" } }
{ "name": "math", "arguments": { "command": "schema" } }独立CLI
#!/usr/bin/env node
import { z } from "zod"
import { defineCommand, runCli, arg } from "@lifeprompt/acli"
const greet = defineCommand({
description: "Say hello",
args: {
name: arg(z.string(), { positional: 0 }),
},
handler: async ({ name }) => ({ message: `Hello, ${name}!` }), // name is inferred as string
})
runCli({ commands: { greet } })node my-cli.mjs greet World
# → { "message": "Hello, World!" }交互式REPL
从文件导出命令并以交互方式浏览它们——就像放入Docker容器一样:
// tools.ts
import { z } from "zod"
import { defineCommand, arg } from "@lifeprompt/acli"
export const add = defineCommand({
description: "Add two numbers",
args: {
a: arg(z.number(), { positional: 0 }),
b: arg(z.number(), { positional: 1 }),
},
handler: async ({ a, b }) => ({ result: a + b }),
})
export const greet = defineCommand({
description: "Say hello",
args: {
name: arg(z.string(), { positional: 0 }),
shout: arg(z.boolean().default(false)),
},
handler: async ({ name, shout = false }) => {
const msg = `Hello, ${name}!`
return { message: shout ? msg.toUpperCase() : msg }
},
})npx @lifeprompt/acli repl ./tools.ts
acli v0.7.3 — Interactive REPL
Loaded 2 command(s) from ./tools.ts
Type 'help' for commands, '.exit' to quit
acli> add 10 20
{ "result": 30 }
acli> greet Alice --shout
{ "message": "HELLO, ALICE!" }
acli> help
{ "commands": [{ "name": "add", ... }, { "name": "greet", ... }] }
acli> exit
Bye!单命令执行(可用于脚本编写):
npx @lifeprompt/acli exec ./tools.ts "add 1 2"
# → { "result": 3 }TypeScript支持: 本机适用于Node.js 22.6+、Bun和Deno。对于较旧的Node.js,请安装 集体: npm install -D jiti______________________________________________________________________
参数定义
ACLI使用Zod进行具有丰富验证的类型安全参数解析。
arg(schema, meta?)
用CLI元数据包装Zod模式:
import { z } from "zod"
import { arg } from "@lifeprompt/acli"
// Basic types
arg(z.string()) // Required string
arg(z.coerce.number()) // Number (coerced from string)
arg(z.coerce.number().int()) // Integer
arg(z.boolean().default(false)) // Flag (presence = true)
arg(z.array(z.string())) // Array (--tag a --tag b → ["a", "b"])
arg(z.coerce.date()) // Date (ISO8601 string → Date)
// Validation
arg(z.string().min(1).max(100)) // Length validation
arg(z.coerce.number().min(0).max(100)) // Range validation
arg(z.enum(["json", "csv", "table"])) // Enum validation
arg(z.string().email()) // Email validation
arg(z.string().regex(/^[a-z]+$/)) // Regex validation
// Optional & defaults
arg(z.string().optional()) // Optional
arg(z.string().default("hello")) // With default
// Metadata
arg(z.string(), { positional: 0 }) // Positional argument
arg(z.string(), { short: 'n' }) // Short alias (-n)
arg(z.string(), { description: "Name" }) // Help text
arg(z.string(), { examples: ["foo"] }) // Example valuesInferArgs
根据args定义推断解析的参数类型:
const myArgs = {
name: arg(z.string()),
count: arg(z.coerce.number().default(10)),
active: arg(z.boolean().optional()),
}
type MyArgs = InferArgs
// { name: string; count: number; active?: boolean }______________________________________________________________________
命令定义
结构
import { z } from "zod"
import { defineCommand, arg, type InferArgs } from "@lifeprompt/acli"
interface CommandDefinition {
description: string // Required
args?: TArgs // Zod-based arguments
handler?: (args: InferArgs) => Promise
subcommands?: CommandRegistry // Nested commands
}带有子命令的示例
使用 cmd() (别名 defineCommand)在子命令内部启用类型推断:
import { z } from "zod"
import { defineCommand, cmd, arg } from "@lifeprompt/acli"
const calendar = defineCommand({
description: "Calendar management",
subcommands: {
events: cmd({
description: "Manage events",
subcommands: {
list: cmd({
description: "List events",
args: {
from: arg(z.coerce.date().optional()),
limit: arg(z.coerce.number().int().default(10)),
},
handler: async ({ from, limit }) => {
// from: Date | undefined, limit: number (types inferred!)
return { events: await fetchEvents({ from, limit }) }
},
}),
create: cmd({
description: "Create event",
args: {
title: arg(z.string().min(1)),
date: arg(z.coerce.date()),
},
handler: async ({ title, date }) => {
// title: string, date: Date (types inferred!)
return { event: await createEvent({ title, date }) }
},
}),
},
}),
},
})
// Use directly: registerAcli(server, "cli", { calendar })备注:没有cmd(),内联子命令处理程序接收unknown由于TypeScript的类型推理限制。始终用以下方式包裹子命令cmd()为了确保完全的安全性。
用途:
calendar events list --from 2026-02-01 --limit 5
calendar events create --title "Meeting" --date 2026-02-02T10:00:00Z______________________________________________________________________
位置参数
位置参数允许更清晰的语法:
const add = defineCommand({
description: "Add numbers",
args: {
a: arg(z.coerce.number(), { positional: 0 }),
b: arg(z.coerce.number(), { positional: 1 }),
},
handler: async ({ a, b }) => ({ result: a + b }),
})
// Use: registerAcli(server, "math", { add })所有语法都有效:
add 10 20 # Positional
add --a 10 --b 20 # Named使用以下简短选项 -a,用以下方式明确定义它们 short 元数据:
const add = defineCommand({
description: "Add numbers",
args: {
a: arg(z.coerce.number(), { positional: 0, short: 'a' }),
b: arg(z.coerce.number(), { positional: 1, short: 'b' }),
},
handler: async ({ a, b }) => ({ result: a + b }),
})
// Now supports: add -a 10 -b 20标志否定(--no- 前缀)
布尔标志可以显式设置为 false 使用 --no- 前缀:
command --no-verbose # verbose = false
command --no-color # color = false重复选项(数组)
参数定义如下 z.array(...) 从重复选项中累积值:
const search = defineCommand({
description: "Search files",
args: {
ext: arg(z.array(z.string()), { short: 'e', description: "File extensions" }),
},
handler: async ({ ext }) => ({ extensions: ext }),
})
// search --ext .ts --ext .tsx → ext: [".ts", ".tsx"]
// search -e .ts -e .tsx → ext: [".ts", ".tsx"]______________________________________________________________________
内置命令
这些命令自动可用:
| 命令 | 描述 |
|---|---|
help | 列出所有命令 |
help | 显示命令详细信息 |
schema | 所有命令的JSON模式 |
schema | 特定命令的JSON模式 |
version | 显示ACLI版本 |
______________________________________________________________________
响应格式
ACLI使用MCP本地响应格式实现无缝集成。
处理程序返回值
处理程序可以通过两种方式返回值:
// 1. Simple object (auto-wrapped to MCP format)
handler: async () => ({ result: 123 })
// → { content: [{ type: "text", text: '{"result":123}' }] }
// 2. MCP native format (passed through as-is)
handler: async () => ({
content: [
{ type: "text", text: "Hello" },
{ type: "image", data: "base64...", mimeType: "image/png" },
]
})
// → passed through unchanged错误代码
| 代码 | 描述 |
|---|---|
COMMAND_NOT_FOUND | 命令不存在 |
VALIDATION_ERROR | 无效参数或缺少必需参数 |
EXECUTION_ERROR | 处理程序抛出错误 |
PARSE_ERROR | 命令字符串格式错误 |
PERMISSION_DENIED | 授权失败 |
______________________________________________________________________
安全
ACLI的设计考虑了安全性:
- 不执行Shell:命令在进程内直接解析和执行
- 命令白名单:只能执行已注册的命令
- 参数验证:处理程序执行前的Zod验证
- DoS防御:命令和参数的长度和计数限制
______________________________________________________________________
API 参考
registerAcli(server, name, commands, description?)
将命令注册为MCP工具。
registerAcli(server, "tool_name", commands)
// With description
registerAcli(server, "tool_name", commands, "Base description.")
// → "Base description. Commands: cmd1, cmd2. Run 'help' for details."runCli({ commands, args? })
作为独立CLI运行。
runCli({ commands }) // Uses process.argv
runCli({ commands, args: ["add", "1", "2"] }) // Custom argscreateAcli(commands)
创建手动集成的工具定义。
const tool = createAcli(commands)
const result = await tool.execute({ command: "add 1 2" })CLI(npx @lifeprompt/acli)
npx @lifeprompt/acli repl # Interactive REPL
npx @lifeprompt/acli exec # Single command execution
npx @lifeprompt/acli --help # Show help
npx @lifeprompt/acli --version # Show version这 ` 应通过默认导出导出ACLI命令,命名为 commands` 出口或单独命名的出口。
______________________________________________________________________
TypeScript类型
所有类型均已导出:
import type {
// Argument types
ArgSchema,
ArgMeta,
ArgsDefinition,
InferArgs,
// Command types
CommandDefinition,
CommandRegistry,
// MCP migration types
McpToolLike,
// MCP response types
CallToolResult,
TextContent,
ImageContent,
// Error types
AcliError,
AcliErrorCode,
// Options
AcliToolOptions,
CliOptions,
} from "@lifeprompt/acli"
// Helper functions
import { arg, defineCommand, cmd, aclify } from "@lifeprompt/acli"
// cmd is an alias for defineCommand - use inside subcommands for type inference
// aclify converts MCP-style tool definitions to ACLI CommandRegistry______________________________________________________________________
文档
______________________________________________________________________
贡献
看 贡献.md 用于开发设置、发布流程和指南。
______________________________________________________________________
许可证
麻省理工学院
