REST API 和 WebSocket 协议完整参考
| 服务 | 端口 | 说明 |
|---|---|---|
| Backend API | 18765 | REST + WebSocket |
| Frontend Dev | 18766 | Vite 开发服务器 |
REST API: http://localhost:18765/api
WebSocket: ws://localhost:18765/ws
Health: http://localhost:18765/api/health
当设置了 API_KEY 环境变量时,所有请求需要认证。
方式一:Header
X-API-Key: your-api-key方式二:Bearer Token
Authorization: Bearer your-api-key在 init 消息中传递:
{
"type": "init",
"data": {
"workDir": "/path",
"apiKey": "your-api-key"
}
}GET /api/health响应:
{
"status": "ok",
"version": "0.0.1",
"timestamp": "2024-01-01T00:00:00.000Z"
}GET /api/conversations响应:
{
"conversations": [
{
"id": "uuid-string",
"name": "会话名称",
"workDir": "/path/to/project",
"cliType": "claude",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
]
}POST /api/conversations
Content-Type: application/json请求体:
{
"name": "新会话",
"workDir": "/path/to/project"
}响应:
{
"id": "uuid-string",
"name": "新会话",
"workDir": "/path/to/project",
"cliType": "claude",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}GET /api/conversations/:idPATCH /api/conversations/:id
Content-Type: application/json请求体:
{
"name": "新名称"
}DELETE /api/conversations/:id响应:
{
"success": true
}GET /api/conversations/:id/messages响应:
{
"messages": [
{
"id": "msg-id",
"role": "user",
"content": "消息内容",
"type": "text",
"timestamp": 1234567890
}
]
}GET /api/workdirs响应:
{
"directories": [
{ "path": "/Users/name", "name": "home" },
{ "path": "/Users/name/codes", "name": "codes" }
]
}GET /api/directories?path=/Users/name/codes响应:
{
"path": "/Users/name/codes",
"directories": [
{ "name": "project1", "path": "/Users/name/codes/project1" },
{ "name": "project2", "path": "/Users/name/codes/project2" }
]
}GET /api/config响应:
{
"defaultWorkDir": "/Users/name/codes"
}PUT /api/config
Content-Type: application/json请求体:
{
"defaultWorkDir": "/new/path"
}const ws = new WebSocket('ws://localhost:18765/ws')所有消息使用 JSON 格式,结构如下:
interface WebSocketMessage {
type: string
data: unknown
}必须在连接后 10 秒内发送,否则连接将被关闭。
{
"type": "init",
"data": {
"workDir": "/path/to/project",
"apiKey": "optional-api-key"
}
}{
"type": "prompt",
"data": {
"prompt": "你的问题或指令",
"workDir": "/path/to/project",
"conversationId": "optional-conversation-id"
}
}{
"type": "interrupt"
}{
"type": "close"
}{
"type": "connected",
"data": {
"sessionId": "uuid-string"
}
}{
"type": "initialized",
"data": {
"sessionId": "uuid-string"
}
}{
"type": "message",
"data": {
"role": "assistant",
"content": "完整消息内容",
"type": "text"
}
}{
"type": "stream",
"data": {
"delta": {
"text": "文本片段"
}
}
}{
"type": "thinking",
"data": {
"content": "AI 的思考过程"
}
}{
"type": "tool_call",
"data": {
"toolName": "Bash",
"toolInput": {
"command": "ls -la",
"description": "列出文件"
}
}
}{
"type": "tool_result",
"data": {
"toolName": "Bash",
"toolOutput": "file1.txt\nfile2.txt",
"success": true
}
}{
"type": "done",
"data": null
}{
"type": "error",
"data": "错误描述信息"
}const ws = new WebSocket('ws://localhost:18765/ws')
ws.onopen = () => {
// 1. 初始化
ws.send(JSON.stringify({
type: 'init',
data: { workDir: '/Users/name/project' }
}))
}
ws.onmessage = (event) => {
const msg = JSON.parse(event.data)
switch (msg.type) {
case 'connected':
console.log('WebSocket 连接成功')
break
case 'initialized':
console.log('会话初始化完成')
// 2. 发送消息
ws.send(JSON.stringify({
type: 'prompt',
data: { prompt: 'Hello!', workDir: '/Users/name/project' }
}))
break
case 'stream':
// 3. 接收流式响应
process.stdout.write(msg.data.delta.text)
break
case 'tool_call':
console.log('工具调用:', msg.data.toolName)
break
case 'tool_result':
console.log('工具结果:', msg.data.toolOutput)
break
case 'done':
console.log('响应完成')
break
case 'error':
console.error('错误:', msg.data)
break
}
}interface Conversation {
id: string // UUID
name: string // 会话名称
workDir: string // 工作目录路径
cliType: 'claude' // CLI 类型
createdAt: string // ISO 8601 时间
updatedAt: string // ISO 8601 时间
}interface Message {
id: string // 唯一标识
role: 'user' | 'assistant' | 'system' | 'tool'
content: string // 消息内容
type: 'text' | 'thinking' | 'tool_use' | 'tool_result'
metadata?: { // 工具调用元数据
toolName?: string
toolInput?: object
toolOutput?: string
}
timestamp: number // Unix 时间戳(毫秒)
}支持的 Claude Agent SDK 工具:
| 工具 | 用途 | 示例输入 |
|---|---|---|
Read |
读取文件 | { "file_path": "/path/to/file" } |
Edit |
编辑文件 | { "file_path": "/path/to/file", "old_string": "...", "new_string": "..." } |
Bash |
执行命令 | { "command": "ls -la", "description": "列出文件" } |
Glob |
文件搜索 | { "pattern": "**/*.ts" } |
Grep |
内容搜索 | { "pattern": "function", "path": "/path" } |
| 状态码 | 含义 | 场景 |
|---|---|---|
| 200 | 成功 | 正常响应 |
| 400 | 请求错误 | 参数验证失败 |
| 401 | 未认证 | API Key 缺失或无效 |
| 403 | 禁止访问 | 路径不在允许范围内 |
| 404 | 未找到 | 会话或资源不存在 |
| 429 | 请求过多 | 超出速率限制 |
| 500 | 服务器错误 | 内部错误 |
{
"error": "错误类型",
"message": "详细错误信息",
"details": {}
}- 连接后立即关闭:未发送 init 消息或超时
- 收到 error 消息:处理请求时出错
- 连接异常关闭:网络问题或服务器重启
默认限制:100 请求/分钟
超过限制时返回:
HTTP/1.1 429 Too Many Requests
Retry-After: 60# 健康检查
curl http://localhost:18765/api/health
# 创建会话
curl -X POST http://localhost:18765/api/conversations \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{"name":"Test","workDir":"/Users/name"}'
# 获取会话列表
curl http://localhost:18765/api/conversations \
-H "Authorization: Bearer your-key"# 使用 wscat
npm install -g wscat
wscat -c ws://localhost:18765/ws
# 发送 init
> {"type":"init","data":{"workDir":"/Users/name"}}
# 发送消息
> {"type":"prompt","data":{"prompt":"Hello","workDir":"/Users/name"}}