服务器
通过 HTTP 与 Dropstone 服务器交互。
dropstone serve 命令运行一个无头 HTTP 服务器,该服务器暴露一个 Dropstone 客户端可以使用的 OpenAPI 端点。
用法
dropstone serve [--port <number>] [--hostname <string>] [--cors <origin>]
选项
| 标志 | 描述 | 默认值 |
|---|---|---|
--port | 监听的端口 | 4096 |
--hostname | 监听的主机名 | 127.0.0.1 |
--mdns | 启用 mDNS 发现 | false |
--mdns-domain | mDNS 服务的自定义域名 | dropstone.local |
--cors | 允许的其他浏览器来源 | [] |
--cors 可以多次传递:
dropstone serve --cors http://localhost:5173 --cors https://app.example.com
身份验证
设置 DROPSTONE_SERVER_PASSWORD 以使用 HTTP 基本身份验证保护服务器。用户名默认为 dropstone,或设置 DROPSTONE_SERVER_USERNAME 来覆盖它。这适用于 dropstone serve 和 dropstone web。
DROPSTONE_SERVER_PASSWORD=your-password dropstone serve
Agent 凭据
DROPSTONE_SERVER_PASSWORD 保护服务器本身。它不会告诉 agent 如何访问 Dropstone。在无人值守的机器上,没有已登录的账户可以继承,因此请通过提供商配置传递 API 密钥:
{
"provider": {
"dropstone": {
"options": {
"apiKey": "dsk_live_...",
"baseURL": "https://api.dropstone.io/api/v1"
}
}
}
}
baseURL 很重要。API 密钥在 /api/v1 处被接受,而不是在 /v1 处,发送到 /v1 的密钥会被拒绝并返回 403 Invalid token format. Please log in again. 请在此处设置它,而不是通过 DROPSTONE_BASE_URL,后者也用于构建账户、使用情况和内存端点,如果你将其指向带版本号的路径,则会破坏这些端点。
在 dropstone.io/dashboard/settings 生成密钥。
Note
默认的 build agent 会在每次工具调用前询问。这里没有任何东西可以回答该提示,因此请求会挂起而不是失败。要么发送 "agent": "accept all",要么设置显式的权限允许列表。请参阅 权限。
发送提示
POST /session/:id/message 需要 agent 和 model。省略 model 不会解析默认值:该轮返回 200 且主体为空,并且不会运行任何内容。
curl -X POST "http://127.0.0.1:4096/session/$SID/message?directory=$PWD" \
-H "Content-Type: application/json" \
-d '{
"agent": "build",
"model": { "providerID": "dropstone", "modelID": "dropstone-pro" },
"parts": [{ "type": "text", "text": "Add error handling to src/index.ts" }]
}'
失败的轮次仍然返回 200。原因在 data.info.error 中,而不是在传输层,因此请检查该字段,而不是依赖状态码。
工作原理
dropstone serve 通过 OpenAPI 3.1 HTTP 端点暴露 Dropstone 的功能。同一端点用于生成 SDK。
当你想要以编程方式驱动 Dropstone 时,请使用服务器:从脚本、CI 管道或你自己的集成中。交互式会话和服务器是独立的。无论你是否打开了交互式会话,运行 dropstone serve 都会启动一个全新的独立服务器。
你可以使用 --hostname 和 --port 标志 覆盖绑定地址。
规范
服务器发布一个 OpenAPI 3.1 规范,可以在以下位置查看:
http://<hostname>:<port>/doc
例如,http://localhost:4096/doc。使用该规范生成客户端或检查请求和响应类型。或者也可以在 Swagger 资源管理器中查看。
API
Dropstone 服务器暴露以下 API。
全局
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /global/health | 获取服务器健康状态和版本 | { healthy: true, version: string } |
GET | /global/event | 获取全局事件(SSE 流) | 事件流 |
项目
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /project | 列出所有项目 | Project[] |
GET | /project/current | 获取当前项目 | Project |
路径与 VCS
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /path | 获取当前路径 | Path |
GET | /vcs | 获取当前项目的 VCS 信息 | VcsInfo |
配置
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /config | 获取配置信息 | Config |
PATCH | /config | 更新配置 | Config |
会话
| 方法 | 路径 | 描述 | 备注 |
|---|---|---|---|
GET | /session | 列出所有会话 | 返回 Session[] |
POST | /session | 创建新会话 | body: { parentID?, title? }, 返回 Session |
GET | /session/status | 获取所有会话的会话状态 | 返回 { [sessionID: string]: SessionStatus } |
GET | /session/:id | 获取会话详情 | 返回 Session |
DELETE | /session/:id | 删除会话及其所有数据 | 返回 boolean |
PATCH | /session/:id | 更新会话属性 | body: { title? }, 返回 Session |
GET | /session/:id/children | 获取会话的子会话 | 返回 Session[] |
GET | /session/:id/todo | 获取会话的待办事项列表 | 返回 Todo[] |
POST | /session/:id/init | 分析应用并创建 AGENTS.md | body: { messageID, providerID, modelID }, 返回 boolean |
POST | /session/:id/fork | 在消息处派生现有会话 | body: { messageID? }, 返回 Session |
POST | /session/:id/abort | 中止正在运行的会话 | 返回 boolean |
GET | /session/:id/diff | 获取此会话的差异 | query: messageID?, 返回 FileDiff[] |
POST | /session/:id/summarize | 总结会话 | body: { providerID, modelID }, 返回 boolean |
POST | /session/:id/revert | 还原消息 | body: { messageID, partID? }, 返回 boolean |
POST | /session/:id/unrevert | 恢复所有已还原的消息 | 返回 boolean |
POST | /session/:id/permissions/:permissionID | 响应权限请求 | body: { response, remember? }, 返回 boolean |
消息
| 方法 | 路径 | 描述 | 备注 |
|---|---|---|---|
GET | /session/:id/message | 列出会话中的消息 | query: limit?, 返回 { info: Message, parts: Part[]}[] |
POST | /session/:id/message | 发送消息并等待响应 | body: { messageID?, model?, agent?, noReply?, system?, tools?, parts }, 返回 { info: Message, parts: Part[]} |
GET | /session/:id/message/:messageID | 获取消息详情 | 返回 { info: Message, parts: Part[]} |
POST | /session/:id/prompt_async | 异步发送消息(不等待) | body: 与 /session/:id/message 相同, 返回 204 No Content |
POST | /session/:id/command | 执行斜杠命令 | body: { messageID?, agent?, model?, command, arguments }, 返回 { info: Message, parts: Part[]} |
POST | /session/:id/shell | 运行 shell 命令 | body: { agent, model?, command }, 返回 { info: Message, parts: Part[]} |
命令
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /command | 列出所有命令 | Command[] |
文件
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /find?pattern=<pat> | 在文件中搜索文本 | 匹配对象数组,包含 path, lines, line_number, absolute_offset, submatches |
GET | /find/file?query=<q> | 按名称查找文件和目录 | string[] (路径) |
GET | /find/symbol?query=<q> | 查找工作区符号 | Symbol[] |
GET | /file?path=<path> | 列出文件和目录 | FileNode[] |
GET | /file/content?path=<p> | 读取文件 | FileContent |
GET | /file/status | 获取受跟踪文件的状态 | File[] |
/find/file 查询参数
query(必需):搜索字符串(模糊匹配)type(可选):将结果限制为"file"或"directory"directory(可选):覆盖搜索的项目根目录limit(可选):最大结果数(1–200)dirs(可选):旧版标志("false"仅返回文件)
LSP、格式化器与 MCP
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /lsp | 获取 LSP 服务器状态 | LSPStatus[] |
GET | /formatter | 获取格式化器状态 | FormatterStatus[] |
GET | /mcp | 获取 MCP 服务器状态 | { [name: string]: MCPStatus } |
POST | /mcp | 动态添加 MCP 服务器 | body: { name, config }, 返回 MCP 状态对象 |
Agents
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /agent | 列出所有可用的 agents | Agent[] |
日志
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
POST | /log | 写入日志条目。Body: { service, level, message, extra? } | boolean |
身份验证
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
PUT | /auth/:id | 为给定目标设置身份验证凭据。 | boolean |
事件
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /event | 服务器发送事件流。第一个事件是 server.connected,然后是总线事件 | 服务器发送事件流 |
文档
| 方法 | 路径 | 描述 | 响应 |
|---|---|---|---|
GET | /doc | OpenAPI 3.1 规范 | 包含 OpenAPI 规范的 HTML 页面 |