App Server
实现 Lime 客户端的线程、轮次、事件、审批与配置控制。
什么时候使用
App Server 是 Lime 的应用运行协议入口,适合构建自定义客户端、长连接自动化和工具集成。它通过双向请求与通知提供线程、轮次、审批、配置和运行状态;它不是 MCP 服务器。一次性脚本优先使用 lime exec。
启动运行组件
lime app-server --backend runtime --stdio显式选择 runtime 才会使用真实任务运行后端。mock 用于测试,unavailable 不执行真实任务,external 需要组织提供外部后端命令。不能把协议连接成功当成模型或工具已可用。
传输与远程连接
| 传输 | 启动选择 | 用途 |
|---|---|---|
| 标准输入输出 | --stdio 或 --listen stdio:// | 每行一个协议消息,适合本地子进程。 |
| Unix 套接字 | --listen unix:///absolute/path.sock | 本机受控连接。 |
| WebSocket | --listen ws://127.0.0.1:PORT | 本机连接或经组织 TLS 代理访问。 |
| 关闭监听 | --listen off | 由其他受控方式管理进程。 |
服务器监听 ws://,客户端远程使用 wss:// 时由组织的 TLS 层保护。限制监听地址并配置身份认证;明文连接仅用于回环或受控隧道。
WebSocket 身份
可选择 capability-token 或 signed-bearer-token。前者使用 --ws-token-file 或 --ws-token-sha256;后者需要共享密钥文件,并核对 issuer、audience、有效期和允许时钟偏差。令牌和共享密钥不能出现在 URL 或日志中。
CLI 客户端使用 --remote-auth-token-env 从环境变量读取令牌。传输身份不代替线程内的审批、文件系统与网络权限。
消息结构
请求包含 method、id 与 params;响应使用相同 id 返回 result 或 error;通知没有 id。服务器也会向客户端发起审批或输入请求,因此客户端必须同时处理两个方向,不能只等待自己发出的请求。
{"id":1,"method":"initialize","params":{"clientInfo":{"name":"my_lime_client","version":"1.0.0"},"capabilities":{"experimentalApi":false}}}初始化与实验性 API
连接后先发送 initialize,等待响应,再发送 initialized 通知。只有完成初始化后才发送业务请求。需要实验性方法时显式声明 experimentalApi,并处理当前版本不支持的错误。
{"method":"initialized","params":{}}能力开关表示客户端愿意处理实验接口,不表示服务器一定有相应运行实现或组织权限。以当前二进制的 Schema、返回值和集成测试共同确认支持范围。
核心对象与生命周期
| 对象 | 作用 |
|---|---|
| Thread | 保存对话上下文、配置和持久历史。 |
| Turn | 一次用户请求及其执行过程。 |
| Item | 消息、推理、命令、文件更改或工具调用等可展示条目。 |
常见流程是创建或恢复线程,启动轮次,接收条目与增量事件,最后等待轮次完成。请求返回只表示已接受,不表示工作完成。每个对象使用服务器返回的 ID,不能由显示名称推算。
创建线程
{"id":2,"method":"thread/start","params":{"cwd":"/path/to/project","approvalPolicy":"on-request","sandbox":"workspace-write","serviceName":"my_lime_client"}}可选择 model、modelProvider 和推理配置。省略模型时使用有效默认;实际返回的模型与配置才是本线程采用的值。serviceName 可用于集成服务的线程指标标记。
返回的 instructionSources 可用于解释加载了哪些指令。thread.sessionId 表示会话树根,派生线程不一定与自己的线程 ID 相同。
权限与配置快照
线程支持审批策略、审批审查方、沙盒或命名权限档案。permissions 与 sandbox 不能同时设置;先调用 permissionProfile/list 获取当前目录允许的档案。runtimeWorkspaceRoots 扩展运行根时仍需满足组织策略。
新线程会冻结创建时的配置。修改配置不保证重写已有线程默认;恢复或派生后应展示实际返回的模型、cwd 与权限,而不是沿用客户端缓存。
恢复与派生
thread/resume 继续已有线程,thread/fork 建立新的上下文分支。使用线程 ID 精确关联记录。恢复聊天不恢复文件版本;派生上下文也不自动创建 Git 工作树。
ephemeral 与 historyMode 影响持久化方式。选择非持久化运行前确认是否需要后续恢复与审计,不把临时运行用于必须保留记录的工作流。
开始、引导与中断轮次
{"id":3,"method":"turn/start","params":{"threadId":"<THREAD_ID>","input":[{"type":"text","text":"读取项目指令,说明测试入口"}]}}使用 turn/steer 为正在运行的轮次补充指令,并提供期望轮次 ID 以避免写入错误任务。使用 turn/interrupt 取消指定轮次,等待终止状态并检查已有副作用。
turn/start 可携带输入与允许的本轮覆盖。图片、文件或其他输入必须符合 Schema 和当前模型能力;客户端不可把本地路径当作已上传内容。
模型与功能目录
model/list 提供可选模型、默认模型、输入能力及支持的推理强度。处理分页,不硬编码模型列表、快速服务层级或账号权益。experimentalFeature/list 返回功能的阶段和启用状态;已移除的功能不应继续展示为可用。
environment/info 等环境接口需实验能力和实际已配置环境。环境未知或连接失败时显示明确错误,不回退到本机目录。
读取历史与分页
| 方法 | 用途 |
|---|---|
| thread/read | 读取已存储元数据,无需恢复运行线程。 |
| thread/turns/list | 按游标读取轮次,可选择条目加载视图。 |
| thread/items/list | 分页读取线程或指定轮次的条目。 |
| thread/list | 分页筛选持久线程。 |
| thread/loaded/list | 查看当前已加载线程。 |
使用返回游标继续分页,直到没有下一页。历史加载与实时通知去重需要按稳定 ID 合并;不能把新消息简单追加到历史末尾而制造重复。
分组、附件和元数据
线程分组、附件和元数据接口用于组织客户端视图,不改变领域权限。附件应按 API 上传或注册并保存引用;删除附件与删除磁盘原文件的范围要分别说明。
thread/metadata/update 用于受支持的线程元数据。分组移动使用 thread/section/move 等当前 Schema 定义,不把分组名称作为授权依据。
持续目标
thread/goal/set、thread/goal/get 和 thread/goal/clear 管理线程目标。客户端应展示真实状态与更新通知,区分进行中、暂停、完成和清除,不以停止接收事件自动判定完成。目标只用于任务跟踪,不能扩大用户授权。
订阅、归档和删除
thread/unsubscribe 取消当前连接的订阅;它不等同于中断轮次。thread/archive 整理活跃记录,thread/unarchive 恢复记录,thread/delete 永久删除持久线程及其适用后代,必须让用户理解范围。
收到 thread/closed 表示加载或订阅生命周期变化。归档、删除、停止与取消订阅应使用不同 UI 文案,避免误导。
压缩、注入和历史回退
thread/compact/start 发起上下文压缩;等待事件确认结果。thread/inject_items 向已加载线程加入模型可见条目,属于低层协议能力,不能用于伪造用户授权。
thread/revert 回退保存的线程历史,不回滚已经修改的文件或外部系统。操作前独立核对文件、进程和远端状态。
事件与增量内容
按 threadId、turnId 与 itemId 归属处理轮次、条目和文本增量。常见事件包括 turn/started、turn/completed、item/started、item/completed,以及文本、推理或命令输出增量。先创建条目再合并增量,收到完成事件后冻结最终内容。
维护未知通知的兼容处理。实验性文件模糊搜索、警告和沙盒设置通知不应打断正常对话;必要时可通过初始化能力声明屏蔽不需要的通知。
错误与重试
请求错误与轮次执行失败分别处理。记录错误码、消息、关联 ID 和可重试信息;凭据、路径或策略错误应修复根因。断连或超时后先读取原线程与轮次,不直接重发可能产生副作用的请求。
工具失败可以发生在已有部分输出或写入之后。展示部分结果和恢复建议,不能仅凭最后一条模型文字把失败变为成功。
命令与进程
| 方法组 | 用途 |
|---|---|
| command/exec | 执行独立命令,配合 write、resize、terminate 管理交互。 |
| process/spawn | 启动进程,配合 writeStdin、resizePty、kill 管理生命周期。 |
| thread/shellCommand | 在线程上下文执行命令。 |
使用 Schema 中的工作目录、超时和输出字段,不拼接不可信 Shell 文本。消费 outputDelta 与 exited 通知,记录最终退出码;停止后检查文件与外部副作用。
文件系统接口
fs/readFile、writeFile、createDirectory、getMetadata、readDirectory、remove 和 copy 操作绝对路径。fs/watch 与 fs/unwatch 管理监听,fs/changed 提供变化通知。路径属于执行环境,不把远端文件路径直接交给本机文件系统。
写入与删除需遵守当前权限和用户授权。处理并发改动时先读取版本或内容,避免覆盖用户新编辑。监听是变化提示,重新读取才得到当前文件内容。
审批与用户输入
服务器可以发起命令执行、文件更改、权限、MCP 工具和动态工具请求。客户端应显示动作、目标、参数和权限范围,再以该请求 ID 返回明确决策。关闭窗口、超时或断连不能默认为同意。
tool/requestUserInput 收集有限的结构化问题。mcpServer/elicitation/request 可要求表单或 URL 流程;应验证来源、展示数据用途,并只传回用户提供的必要字段。
MCP 连接
mcpServerStatus/list 返回服务器、工具与身份状态;threadId 可用于复用线程连接。使用 mcpServer/tool/call 和 mcpServer/resource/read 调用已配置服务器。OAuth 登录返回授权地址与关联 ID,完成通知需与原登录流程匹配。
config/mcpServer/reload 重新读取连接配置并为已加载线程安排刷新。列表存在、初始化成功和具体工具成功是不同状态,界面应分别呈现。
技能、插件与应用
skills/list、skills/config/write 及技能更新通知管理可用技能。插件与市场接口管理发现、安装及来源;应用接口提供连接器元数据和实际安装状态。以运行时 enabled、installed 和可调用状态决定入口,不能仅凭目录条目展示为已连接。
动态工具由客户端声明并处理服务器调用。它们同样需要输入验证、错误结果和审批边界,不能借动态工具绕过组织权限。
配置与管理员要求
config/read 返回有效配置、来源和层信息。config/value/write 与 config/batchWrite 使用版本比较并指定允许的绝对文件路径;冲突时重新读取,保留无关配置和注释。用户 YAML 与可信项目 TOML 的职责见配置文档。
configRequirements/read 提供管理员限制。用户配置与 RPC 不得自授管理员身份。Windows 沙盒设置应通过 readiness、setupStart 与完成通知跟踪实际状态。
外部资源导入
externalAgentConfig/detect 与 import 按版本支持的资源检测和导入。先展示来源、目标、冲突及影响,再逐项选择。长任务需要消费 progress 和 completed 通知;导入不能覆盖现有配置或把外部指令自动视为可信。
身份与产品边界
Lime 的模型提供方连接、远程 App Server 身份和外部工具 OAuth 各有独立职责。协议中出现某种兼容账号类型,不表示 Lime 已交付该提供商的托管登录、限额兑换、工作空间邮件或云消息服务。客户端只展示当前实现和组织实际提供的身份入口。
集成验收
- 验证初始化与版本不兼容错误。
- 验证线程创建、历史分页、恢复与配置快照。
- 验证流式条目、工具失败和轮次最终状态。
- 验证同意、拒绝、取消、超时和断连。
- 验证文件、进程、MCP 与凭据边界。
- 在当前安装版本上验证真实任务,而不只校验 Schema。