关于 Layven
Layven 是供 Agent 和团队成员共用的文件空间,通过 MCP 服务访问。它为写入内容保留版本、记录执行操作的 Agent,并支持回滚,还提供文件搜索、编辑、历史记录和活动查询工具。
主要功能
- 01Agent 共用工作区
- 02文件写入版本管理
- 03记录 Agent 操作历史
- 04文件搜索与内容匹配
- 05恢复旧版本
适用场景
- 01在不同 Agent 间共享文件
- 02搜索工作区文件内容
- 03查看文件由谁修改
- 04恢复文件的早期版本
MCP 相关
托管的 Layven MCP 服务向 MCP 客户端提供工作区文件和活动记录工具,可读取、搜索、写入、编辑、移动、删除、锁定及恢复文件。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://api.layven.io/mcpclaude mcp add --transport http io-layven-layven https://api.layven.io/mcp{"mcpServers":{"io-layven-layven":{"type":"http","url":"https://api.layven.io/mcp"}}}在 Cursor 中打开{"servers":{"io-layven-layven":{"type":"http","url":"https://api.layven.io/mcp"}}}在 VS Code 中打开{"mcpServers":{"io-layven-layven":{"type":"http","url":"https://api.layven.io/mcp"}}}{"mcpServers":{"io-layven-layven":{"serverUrl":"https://api.layven.io/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Layven MCP 服务
Layven 是 Agent 通过 MCP 挂载的共享云盘。每次写入都会生成版本记录,每项操作都会归属到执行操作的 Agent,任何内容都可以回滚。
一个配置块即可,无需更改 Agent 代码。托管于 https://api.layven.io/mcp。
Layven MCP 服务文档版本为 1.0.2。
快速开始
claude mcp add --transport http layven https://api.layven.io/mcp --header "Authorization: Bearer agd_your_agent_token"
- 在 layven.io 获取令牌:打开控制台,前往 Agents,然后创建一个。密钥只会显示一次。
- 重启客户端。
- 向 Agent 提问:“列出我的 Layven 工作区”。
产品的价值在第二次连接时便会显现。创建第二个令牌,用它连接另一个工具,然后让该工具读取第一个工具刚写入的文件。两个 Agent 可以看到同一个云盘,活动动态会显示各自执行了哪些操作。演示教程:examples/two-agent-handoff.md。
连接客户端
Claude Code
claude mcp add --transport http layven https://api.layven.io/mcp --header "Authorization: Bearer agd_your_agent_token"
Claude.ai 自定义连接器
粘贴 https://api.layven.io/mcp,并使用 OAuth 进行身份验证。该界面没有自定义请求头字段,因此才需要 OAuth。
ChatGPT
与 Claude.ai 相同:粘贴 https://api.layven.io/mcp,并使用 OAuth 进行身份验证。
Cursor(~/.cursor/mcp.json)
{
"mcpServers": {
"layven": {
"url": "https://api.layven.io/mcp",
"headers": {
"Authorization": "Bearer agd_your_agent_token"
}
}
}
}
Codex(~/.codex/config.toml)
[mcp_servers.layven]
url = "https://api.layven.io/mcp"
http_headers = { "Authorization" = "Bearer agd_your_agent_token" }
Gemini(~/.gemini/settings.json)
使用与 Cursor 相同的 JSON,但键名是 httpUrl,而不是 url,因为 Gemini 会将 url 视为 SSE 端点。
{
"mcpServers": {
"layven": {
"httpUrl": "https://api.layven.io/mcp",
"headers": {
"Authorization": "Bearer agd_your_agent_token"
}
}
}
}
通用 MCP JSON
{
"mcpServers": {
"layven": {
"url": "https://api.layven.io/mcp",
"headers": {
"Authorization": "Bearer agd_your_agent_token"
}
}
}
}
身份验证
有两种接入方式,两者都会映射到同一个令牌记录,因此无论使用哪种方式,权限、撤销功能和审计跟踪都相同。
静态持有者令牌。 每次请求都发送 Authorization: Bearer agd_...。在控制台中创建;密钥只会显示一次。
OAuth 2.1,适用于界面没有自定义请求头字段的客户端:
| 授权服务器 | https://api.layven.io |
| 受保护资源元数据 | https://api.layven.io/.well-known/oauth-protected-resource/mcp |
| 资源 | https://api.layven.io/mcp |
| 动态客户端注册 | 支持 |
| 客户端密钥有效期 | 永不过期 |
用户授权后会生成一个普通令牌,你可以像其他令牌一样,在控制台中查看并撤销它。
传输
POST https://api.layven.io/mcp,Streamable HTTP,无状态。- 每个 POST 请求都完全独立。没有会话 ID、没有会话恢复、没有独立的 SSE 端点,也不支持 stdio。
- GET 和 DELETE 返回 HTTP 405,且响应正文严格如下:
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Method not allowed (stateless)"},"id":null} - 必需的请求头:
Content-Type: application/json和Accept: application/json, text/event-stream。Accept中必须同时包含这两种媒体类型,否则服务器会返回 406。 - 响应的
Content-Type为text/event-stream。 MCP-Protocol-Version为可选项。如果提供,其值必须是2025-11-25、2025-06-18、2025-03-26、2024-11-05、2024-10-07之一,否则服务器会返回 HTTP 400。- 能力:仅
tools。不提供资源或提示词。 initialize时的服务器身份信息:名称Layven,版本1.0.2,网站https://layven.io。
工具
每个工具都接受一个可选的 workspace,即工作区 slug。令牌恰好获准访问一个工作区时,可以省略该参数。不带 workspace 调用 list 时,会遍历令牌可访问的所有工作区。
| 工具 | 访问权限 | 功能 | 关键参数 |
|---|---|---|---|
list | ro | 列出文件夹,或按路径子字符串查找文件 | path、recursive、q、limit |
read | ro | 读取当前版本或较早版本的文件 | path、version |
grep | ro | 使用 RE2 模式搜索文件内容 | pattern、prefix、context_lines、max_matches |
history | ro | 按从新到旧的顺序列出单个文件的版本 | path、limit、cursor |
activity | ro | 列出变更内容及执行变更的 Agent | since、path_prefix、limit |
write | rw | 使用内联内容创建或替换文件 | path、content、encoding、expected_version |
edit | rw | 对现有文本文件应用字符串替换 | path、edits、expected_version |
move | rw | 移动或重命名文件 | from、to、overwrite |
delete | rw | 将文件标记为删除,可使用 restore 恢复 | path、expected_version |
restore | rw | 将文件恢复到某个版本,或将文件夹恢复到某个时间戳 | path + to_version,或 prefix + at |
lock | rw | 对路径加 5 分钟的建议锁 | path |
unlock | rw | 释放此令牌持有的锁 | path |
request_upload | rw | 开始上传大文件,返回预签名 PUT URL | path、size、expected_version |
finalize_upload | rw | 将已上传的文件提交为新版本 | upload_id |
只有 delete 标记为具有破坏性;它会写入一个可通过 restore 恢复的删除标记版本。write、delete、lock 和 unlock 标记为幂等;edit、move、restore、request_upload 和 finalize_upload 则不是幂等操作。所有工具的操作范围都不会超出 Layven。
任何工具都可能返回 NOT_FOUND(无法解析工作区)、PERMISSION_DENIED、RATE_LIMITED 和 INTERNAL;因此,下面每个工具的 Errors 行会列出该工具特有的错误。
list
列出文件夹,或在所有获准访问的工作区中搜索路径包含指定子字符串的文件。
参数
workspace? string workspace slug; omit to fan out over every granted workspace
path string default "" (workspace root)
recursive boolean default false
include_deleted boolean default false
limit integer 1..1000, default 500, applied per workspace
cursor? string opaque; requires an explicit workspace
q? string 1..1024 chars, case-insensitive substring of the full path; implies recursive
返回值
{
"results": [
{
"workspace": { "id": "...", "slug": "research" },
"entries": [
{
"path": "notes/todo.md",
"type": "file",
"size": 1284,
"version": 7,
"modified_at": "2026-08-05T09:12:44Z",
"modified_by_label": "research-agent",
"by_actor": "agent",
"deleted": true
}
],
"next_cursor": "..."
}
]
}
type 的值为 "file" 或 "folder"。每个条目中的 size、version、modified_at、modified_by_label、by_actor 和 deleted 均为可选字段。
错误: INVALID_PATH。
说明
- 即使令牌恰好获准访问一个工作区,
results也始终是一个包含各工作区数据块的数组。不要编写期望返回裸entries数组的客户端。 - 在跨工作区遍历时传入
cursor会返回INVALID_PATH,并附带reason: "cursor_requires_workspace"。分页前,请固定指定工作区。 - 文件夹由路径前缀合成。不存在可创建或删除的文件夹记录。
read
读取文件的当前版本或较早版本。
参数
workspace? string
path string
version? integer defaults to the current version
当原始大小不超过 262144 字节且 MIME 类型为文本时,内联返回:
{
"path": "notes/todo.md",
"version": 7,
"size": 1284,
"mime_type": "text/markdown",
"encoding": "utf8",
"content": "..."
}
对于更大的文件或二进制文件,返回:
{
"path": "datasets/corpus.tar.gz",
"version": 3,
"size": 431912448,
"mime_type": "application/gzip",
"download_url": "https://...",
"url_expires_at": "2026-08-05T09:27:00Z"
}
错误: NOT_FOUND(如果路径已标记为删除,则附带 deleted: true 和 last_version)、INVALID_PATH。
说明
- 响应结构会根据大小和 MIME 类型切换,而非根据你传入的标志切换。文件超过 256 KiB 或属于任何非文本文件时,会返回有效期为 15 分钟的
download_url,而不是内联内容。请处理这两种响应结构。
grep
使用正则表达式搜索文件内容。
参数
workspace? string
path? string search a single file
prefix? string search one folder; omit both path and prefix to search the whole workspace
pattern string min 1 char, RE2 syntax
case_sensitive boolean default false
context_lines integer 0..10, default 2
max_matches integer 1..200, default 50
返回
{
"matches": [
{
"path": "notes/todo.md",
"line": 42,
"text": "TODO: rotate the staging token",
"before": ["..."],
"after": ["..."]
}
],
"files_scanned": 128,
"files_skipped_binary": 3,
"files_skipped_too_large": 0,
"truncated": false
}
错误: INVALID_PATTERN、INVALID_PATH。
注意事项
- 模式使用 RE2,因此不支持反向引用和环视。无效模式会返回
INVALID_PATTERN。 - 仅在单行内查找匹配项。跨越换行符的模式永远不会匹配。
- 每个匹配行返回一条记录,类似于
grep -n,无论该行中有多少处匹配。 truncated: true表示扫描已达到预算上限,结果不完整。请缩小prefix范围或收紧模式。- 行号仅用于显示。切勿将其粘贴到
edit的old_str中。
history
按时间倒序列出一个文件的版本。
参数
workspace? string
path string
limit integer 1..1000, default 50
cursor? string digits only
返回
{
"versions": [
{
"version": 7,
"op": "write",
"size": 1284,
"content_hash": "...",
"created_at": "2026-08-05T09:12:44Z",
"by_label": "research-agent",
"by_actor": "agent",
"moved_from": "drafts/todo.md",
"purged": false,
"restorable_until": "2027-08-05T09:12:44Z"
}
],
"next_cursor": "182734"
}
op 是 write、edit、move、delete、restore 之一。moved_from、by_actor 和 restorable_until 为可选项。
错误: NOT_FOUND、INVALID_PATH。
注意事项
- 按时间倒序排列,因此
limit: 1是确认写入已生效的最简便方式。 next_cursor是不透明字符串,不是数字。最后一页中不会出现该字段,可据此判断何时停止。purged: true表示保留策略已释放该版本的内容。该条目仍会保留在审计记录中,但对其执行restore会返回NOT_FOUND,且reason: "version_purged"。
activity
列出工作区中的变更以及执行变更的 Agent。
参数
workspace? string
since? string RFC 3339 timestamp
path_prefix? string
limit integer 1..1000, default 100
cursor? string
返回
{
"events": [
{
"at": "2026-08-05T09:12:44Z",
"actor": "agent",
"by_label": "research-agent",
"by_actor": "agent",
"op": "write",
"path": "notes/todo.md",
"old_path": "drafts/todo.md",
"version": 7
}
],
"next_cursor": "9014522"
}
actor 是 agent、user、system 之一。按时间倒序排列。
op 是 write、edit、move、delete、restore、purge、lock、unlock 或 grep。系统清理也会记录 purge_retention 和 purge_workspace_delete,两者均不带路径。只有 write、edit、move、delete 和单文件 restore 会携带 version;其他操作的该字段为 null。请注意,purge 会携带实际路径或文件夹前缀,因此会匹配 path_prefix 筛选条件:如果你通过此信息流审计某个文件夹,purge 会与写入记录一同显示。
错误: INVALID_PATH。
注意事项
next_cursor是不透明字符串,不是数字。最后一页中不会出现该字段,可据此判断何时停止。- 这是轮询机制。没有 webhook、触发器或推送。Agent 通过按固定间隔调用
activity来协调,这种方式在每隔几秒到几分钟调用一次时都能轻松满足速率限制。 since是时间戳,不是游标,而且两个事件可能拥有相同的时间戳。请预期偶尔会重复投递,并确保工作具备幂等性。请参阅 examples/two-agent-handoff.md。
write
使用内联内容创建或替换文件。
参数
workspace? string
path string
content string
encoding "utf8" | "base64" default "utf8"
mime_type? string
expected_version? integer fail instead of overwriting a concurrent change
override_lock boolean default false
内联上限:解码后为 1 MiB。更大的内容需通过 request_upload 处理。
返回
{
"path": "notes/todo.md",
"version": 8,
"size": 1301,
"content_hash": "...",
"deduplicated": false,
"unchanged": true
}
仅在适用时才会出现 unchanged。
错误: INVALID_PATH、VERSION_CONFLICT、LOCKED、QUOTA_EXCEEDED、TOO_LARGE。
注意事项
- 写入与当前版本逐字节相同的内容时,不会产生任何变更:会返回
unchanged: true,且不会创建新版本。对于定时任务,这一点值得重点记录,因为这通常意味着生成器没有运行。 - 与较早版本相同的内容仍会创建新版本。
- 向已删除标记的路径写入内容会使其恢复。
edit
通过字符串替换修改现有文本文件,无需重新发送整个正文。
参数
workspace? string
path string
edits array of 1..20 objects:
old_str string min 1 char
new_str string
replace_all boolean default false
expected_version? integer
override_lock boolean default false
文本文件大小上限为 16 MiB。
返回
{
"path": "notes/todo.md",
"version": 9,
"edits_applied": 2,
"replacements": [1, 3],
"size_before": 1301,
"size_after": 1288,
"context": "..."
}
仅在适用时才会出现 unchanged。
错误: STRING_NOT_FOUND、STRING_NOT_UNIQUE、NOT_EDITABLE、TOO_LARGE_FOR_EDIT、VERSION_CONFLICT、LOCKED、QUOTA_EXCEEDED、NOT_FOUND。
注意
- 编辑按顺序应用,并以一个新版本原子提交,因此一次包含 20 项编辑的调用在
history中只会生成一条记录,而不是 20 条。如果任何一项编辑失败,则所有编辑都不会生效。 - 每个
old_str必须恰好匹配一次,否则会返回STRING_NOT_FOUND或STRING_NOT_UNIQUE。如果要替换所有匹配项,请设置replace_all。 - 编辑按顺序应用,因此后续的
old_str必须匹配前面编辑完成后留下的文本。
move
移动或重命名文件。
参数
workspace? string
from string
to string
expected_version? integer
overwrite boolean default false
override_lock boolean default false
返回
{ "from": "drafts/todo.md", "to": "notes/todo.md", "version": 1 }
version 是目标位置的新版本。
错误: NOT_FOUND、INVALID_PATH、VERSION_CONFLICT(包含 reason: "destination_exists")、LOCKED。
注意
- 令牌需要同时拥有两个路径的写入权限。仅覆盖源路径、不覆盖目标路径的前缀规则会导致
PERMISSION_DENIED。 - 如果目标路径上存在未删除的文件且
overwrite: false,则会返回包含reason: "destination_exists"的VERSION_CONFLICT。这类错误很有用:两个工作线程同时争抢同一项时,可以执行move,落败的一方会收到明确错误,而不会重复处理。
delete
为文件添加删除标记。
参数
workspace? string
path string
expected_version? integer
override_lock boolean default false
返回
{ "path": "notes/todo.md", "version": 10, "unchanged": true }
仅在适用时才会出现 unchanged。
错误: NOT_FOUND、INVALID_PATH、VERSION_CONFLICT、LOCKED。
注意
- 这会写入一个删除标记版本,而不会抹除内容。在计划所允许的版本历史保留期限内,你都可以通过
restore恢复该文件。 - 之后再次写入同一路径,会在同一历史记录中将其作为新版本重新创建。
- 除非传入
include_deleted: true,否则list会隐藏带有删除标记的路径。
restore
将单个文件恢复到较早版本,或将整个文件夹恢复到某个时间点的状态。
参数,文件形式:
workspace? string
path string
to_version integer
override_lock boolean default false
参数,文件夹形式:
workspace? string
prefix string
at string RFC 3339 timestamp in UTC, e.g. 2026-08-05T14:04:55Z
override_lock boolean default false
返回,文件形式:
{ "path": "notes/todo.md", "version": 11 }
返回,文件夹形式:
{
"restored": 42,
"deleted": 3,
"affected_paths": ["content/pricing.md", "content/index.md"],
"total": 45
}
affected_paths 是有上限的样本;total 是实际数量。
错误: NOT_FOUND(如果保留策略已释放目标版本,则包含 reason: "version_purged")、INVALID_PATH、LOCKED。
注意
at必须使用 UTC,以Z结尾,可带毫秒。即使+02:00这样的 UTC 偏移是有效的 RFC 3339 格式,也会被拒绝,因此调用前请先转换。- 恢复操作会追加新版本,绝不会重写历史记录。错误版本仍会保留在
history中,因此恢复到错误的时间戳后仍可再次恢复,而且重复恢复也是安全的。 - 在文件夹形式中,
at时不存在的文件会收到删除标记,计入deleted。这些文件不会被抹除,之后再次写入即可恢复。 - 不支持试运行。请先用
list评估操作规模,并用history确认单个文件。操作指南:examples/folder-restore-after-bad-run.md。
lock
对路径获取咨询式锁。
参数
workspace? string
path string
返回
{ "path": "notes/todo.md", "expires_at": "2026-08-05T09:17:44Z" }
错误: LOCKED、INVALID_PATH。
注意
- 锁为咨询式,有效期为 5 分钟。使用相同令牌再次调用
lock即可续期。 - 锁不会阻止读取。存在有效的其他锁时,写入会返回包含
locked_by_label和expires_at的LOCKED;除非调用方传入override_lock: true,该操作会记录在活动动态中。 - 文件可以不存在,因此你可以锁定即将创建的路径。
- 如果任务可以实现为幂等操作,优先使用
move进行认领,而不是加锁:即使发生崩溃,认领也会保留,而 5 分钟的 TTL 则不会。
unlock
释放此令牌持有的锁。
参数
workspace? string
path string
返回值
{ "path": "notes/todo.md", "released": true }
错误: PERMISSION_DENIED(锁属于其他令牌)、INVALID_PATH。
说明
- 解锁一个未持有锁的路径会返回
released: true,而不是NOT_FOUND。此调用不会说明是否存在锁,因此不能用来询问锁由谁持有。
request_upload
为无法通过内联 write 写入的大型内容启动上传。共两步,这是第一步;请参阅大文件上传。
参数
workspace? string
path string
size integer positive, the exact byte count of the file
mime_type? string
expected_version? integer
override_lock boolean default false
返回值
{
"upload_id": "...",
"put_url": "https://...",
"url_expires_at": "2026-08-05T09:27:00Z",
"max_size": 1073741824
}
错误: TOO_LARGE、QUOTA_EXCEEDED、VERSION_CONFLICT、LOCKED、INVALID_PATH。
说明
- 预签名 PUT URL 的有效期为 15 分钟,上传记录的有效期为 1 小时。不支持断点续传或分段上传:如果 PUT 失败,请重新从
request_upload开始。 size必须是精确的字节数。finalize_upload会再次检查该值。
finalize_upload
将已上传的文件提交为新版本。共两步,这是第二步。
参数
workspace? string
upload_id string
返回值
{
"path": "datasets/corpus.tar.gz",
"size": 431912448,
"version": 3,
"content_hash": "..."
}
错误: UPLOAD_EXPIRED、VERSION_CONFLICT、QUOTA_EXCEEDED、TOO_LARGE。
说明
- 这里会再次检查大小和
expected_version,因此即使request_upload成功,finalize时也可能出现VERSION_CONFLICT。这表示你上传期间有人写入了该路径;请重新从request_upload开始。 - 第二次调用 finalize 会返回
UPLOAD_EXPIRED。
错误
领域错误会作为携带 isError: true 的普通工具结果返回,其文本内容为 JSON:
{ "code": "VERSION_CONFLICT", "message": "...", "current_version": 9 }
它们绝不会是协议级 JSON-RPC 错误。Agent 和客户端应根据 code 进行分支处理。
参数验证失败时也会以相同方式返回,但文本不是 JSON。传入类型错误的参数会返回 isError: true 和一条英文纯文本,例如 MCP error -32602: Input validation error: Invalid arguments for tool activity: ...;该错误由 MCP 层生成,请求尚未到达 Layven。因此应谨慎解析:如果 isError 结果的文本无法解析为 JSON,这说明调用存在问题,而不是 Layven 领域错误。upload/layven-upload.mjs 正是如此处理的:无法解析时会使用 code: "UNKNOWN",并将原始文本作为消息。
| Code | 含义 | 附加信息 |
|---|---|---|
NOT_FOUND | 路径、版本或工作区不存在 | 工作区 slug 无法解析时为 workspaces(该令牌的 slug);路径已删除时为 deleted: true 和 last_version;版本已清除时为 reason: "version_purged" |
PERMISSION_DENIED | 令牌的访问级别不足,或前缀规则阻止访问该路径 | required |
INVALID_PATH | 路径未通过规范化检查 | reason |
VERSION_CONFLICT | expected_version 不匹配,或目标已存在 | current_version,有时还包括 reason(例如 destination_exists) |
LOCKED | 另一个令牌持有有效锁 | locked_by_label、expires_at |
QUOTA_EXCEEDED | 组织超出存储配额 | limit_bytes、used_bytes |
TOO_LARGE | 内联内容超过上限,或文件超过 1 GiB | max_bytes |
UPLOAD_EXPIRED | 对已过期或已使用的上传调用 finalize | |
RATE_LIMITED | 达到令牌或组织的速率上限 | retry_after_ms |
INTERNAL | 意外的服务端故障 | request_id |
STRING_NOT_FOUND | edit:文件中不存在 old_str | 提示 |
STRING_NOT_UNIQUE | edit:old_str 匹配多处,且未设置 replace_all | |
NOT_EDITABLE | edit:文件不是文本文件 | |
TOO_LARGE_FOR_EDIT | edit:文件超过 16 MiB | |
INVALID_PATTERN | grep:模式不是有效的 RE2 |
RATE_LIMITED 是唯一值得自动重试的代码:等待 retry_after_ms 指定的时间,然后重试。
限制
| 限制 | 值 |
|---|---|
| 内联写入 | 解码后 1 MiB;更大的内容通过 request_upload 上传 |
| 内联读取 | 256 KiB 且 MIME 类型为文本,否则返回下载 URL |
| 编辑 | 最大 16 MiB 的文本文件,每次调用最多 20 项编辑 |
| Grep | 每个文件扫描 8 MiB,每次调用最多 500 个候选文件;超出时间预算时返回部分结果 |
| 最大文件大小 | 1 GiB |
| 预签名 PUT URL | 15 分钟 |
| 上传记录 | 1 小时 |
| 下载 URL | 15 分钟 |
| 路径长度 | 1024 字节 |
| 锁定 TTL | 5 分钟,可续期 |
| 速率限制 | 每个令牌每分钟 600 个请求,每个组织每分钟 3000 个请求 |
超出速率限制时会返回 RATE_LIMITED,并附带 retry_after_ms。
路径和版本控制
路径使用 UTF-8 编码,以 / 分隔,并区分大小写。输入时会进行规范化:
- 不带前导斜杠:
/a/b会变为a/b - 不允许重复斜杠
- 不允许
.或..段,也不允许空段 - 文件路径末尾不允许有斜杠
- 不允许控制字符
- 最长 1024 字节
其他情况都会返回带有 reason 的 INVALID_PATH。目录是隐式的:没有文件夹记录,list 会根据路径前缀生成文件夹。
版本控制。 每次变更都会创建一个新版本,版本号按文件分别递增。delete 会写入一个墓碑版本。move 会在目标位置创建一个版本,并为源文件写入墓碑。restore 会追加一个新版本,重现较早的状态。历史记录只会追加,绝不会重写,因此错误的恢复操作本身也可以恢复。
乐观并发控制。 默认采用最后写入者获胜,这样是安全的,因为不会丢失任何内容。如果希望写入在发生并发更改时失败,而不是覆盖更改,请传入你读取时的版本作为 expected_version。如果版本不匹配,会在载荷中返回带有 current_version 的 VERSION_CONFLICT,以便调用方重新读取并作出决定。
锁定。 lock 会获取一个为期 5 分钟的建议锁;再次使用相同令牌调用 lock 即可续期。有效的其他锁会使写入返回带有 locked_by_label 和 expires_at 的 LOCKED;设置 override_lock: true 则仍会继续操作,并将此操作记录在活动动态中。锁定不会阻止读取。
权限
每个令牌都会被授予对特定工作区的访问权限,权限分为三个级别:
| 级别 | 工具 |
|---|---|
ro | list、read、grep、history、activity |
rw | ro 中的所有工具,以及 write、edit、move、delete、restore、lock、unlock、request_upload、finalize_upload |
admin | 保留给未来的工作区管理功能 |
授权可以包含可选的前缀规则,将令牌限制为特定文件夹,并以 allow 或 deny 列表表示。拒绝规则优先于允许规则。move 要求对源路径和目标路径都具有权限。
为每个 Agent 分配独立的令牌。这样 list、history 和 activity 中的 by_label 才更易于理解,也能让你撤销某个 Agent 的访问权限,而不影响其他 Agent。
大文件上传
内联 write 的上限为 1 MiB。超过此限制时,分三步上传。
1. 获取 URL。 使用准确的字节数调用 request_upload:
{ "path": "datasets/corpus.tar.gz", "size": 431912448, "mime_type": "application/gzip" }
{
"upload_id": "...",
"put_url": "https://...",
"url_expires_at": "2026-08-05T09:27:00Z",
"max_size": 1073741824
}
2. 将字节数据 PUT 到 put_url。 这是对原始文件进行的普通 HTTP PUT,不是 MCP 调用。该 URL 的有效期为 15 分钟。
3. 提交。 调用 finalize_upload:
{ "upload_id": "..." }
{
"path": "datasets/corpus.tar.gz",
"size": 431912448,
"version": 3,
"content_hash": "..."
}
为什么没有 SDK
没有 Layven 客户端库,今后也不会提供。Layven 是托管式 MCP 服务:只需将客户端指向一个 URL,Agent 就能使用 14 个工具,无需编写代码,也无需维护代码。这是唯一的例外。上传流程中有一个步骤需要进行原始 HTTP PUT,而 MCP 客户端无法执行此操作,因此我们提供了一个无依赖的脚本。你可以复制、阅读并修改它。它采用 MIT 许可证。
upload/layven-upload.mjs
Node 18 或更高版本。无依赖,无需安装。
LAYVEN_TOKEN=agd_your_agent_token \
node upload/layven-upload.mjs ./corpus.tar.gz datasets/corpus.tar.gz \
[--workspace slug] [--mime type] [--expected-version N] [--override-lock] \
[--url https://api.layven.io/mcp]
必须设置 LAYVEN_TOKEN。--url 默认为 https://api.layven.io/mcp。
在仓库根目录运行以下命令来执行测试:
node --test
示例
- examples/two-agent-handoff.md:Agent A 将工作放到云盘上,Agent B 通过轮询
activity接手。 - examples/nightly-write-and-verify.md:由 cron 驱动的 Agent 写入一个产物,并验证该产物已成功写入。
- examples/folder-restore-after-bad-run.md:排查一次有问题的 Agent 运行,并将文件夹回滚到指定时间戳。
套餐
| 免费版 | 专业版 $19/mo | 扩展版 $49/mo | 企业版 | |
|---|---|---|---|---|
| 存储空间 | 5 GB | 100 GB | 500 GB | 自定义 |
| 版本历史 | 30 天 | 1 年 | 不限 | 不限 |
| 活动日志 | 30 天 | 1 年 | 1 年 | 不限 |
| 工作区 | 1 | 5 | 25 | 不限 |
| 令牌 | 2 | 25 | 100 | 不限 |
| 席位 | 1 | 3 | 10 | 不限 |
| 最大文件大小 | 1 GiB | 1 GiB | 1 GiB | 1 GiB |
| 速率限制 | 600 req/min/token | 600 req/min/token | 600 req/min/token | 600 req/min/token |
统一定价。不按用量计费,也不使用点数。
数据驻留
您的文件存储在法国 Gravelines 的 OVHcloud 上,并经过静态加密。任何第三方 AI 或模型 API 都不会接触您的内容。您可以将所有内容导出为普通文件,删除操作也会彻底删除数据。
版本管理
server.json 和变更日志中的版本与服务端在 initialize 时报告的版本一致,因此您始终可以确认正在与哪个版本通信。若文档变更未对应服务端变更,则不会提升版本号。
请参阅 CHANGELOG.md。
支持
如果这些文档、示例或上传助手中存在问题,请提交 issue。关于账户、账单或数据的问题,请联系 [email protected]。
许可证
MIT 许可证适用于此代码库:文档、示例和上传助手。Layven 服务本身为闭源软件。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。