Layven

io.layven由 layven.io 發布官方發布者v1.0.2更新於 Oct 24, 2026

Shared drive for your agents and teammates.

已驗證Streamable HTTP可網頁執行效率與工作流檔案與儲存知識與記憶

概覽

AI 產生的概覽

Layven 是託管的共享磁碟,透過 MCP 掛載給代理,用來讀取、搜尋、版本化並回復各工作區中的檔案。

可以做什麼
  • 列出資料夾、依路徑片段尋找檔案,並讀取目前或先前的版本
  • 以 RE2 正規表示式搜尋檔案內容,並檢視單一檔案的版本歷程
  • 查看活動紀錄,了解哪些內容被變更以及是哪個代理所為
  • 建立、取代、編輯、移動、刪除與還原檔案,包括把整個資料夾還原到某個時間點
  • 取得與釋放建議性鎖定,並透過預簽章網址流程上傳大型檔案
適用情境
適合多個代理或團隊成員共用一個可稽核檔案庫的情境:在代理之間交接工作、讓排程工作寫入產物並驗證寫入結果,或在一次失敗的執行後把資料夾回復。若只用於搜尋與稽核,唯讀權杖即可。
執行需求
遠端 Streamable HTTP 端點 api.layven.io/mcp,不需在本機安裝。必須驗證:使用在 Layven 主控台建立的靜態 bearer 權杖(僅顯示一次),或對沒有自訂標頭欄位的用戶端使用 OAuth 2.1。需要 Layven 帳號以及已授權權杖的工作區;權杖分為 ro 或 rw 等級,並可附帶資料夾前綴規則。
安裝前請注意
權杖可讀寫工作區檔案;應為每個代理建立獨立權杖,以便單獨撤銷。寫入類工具會變更共用資料:delete 會留下墓碑版本,資料夾還原會一次建立與刪除大量路徑且沒有試跑,override_lock 會略過其他代理的鎖定並記錄在活動紀錄中。上傳與下載網址是短期有效的預簽章連結。權杖與組織層級均有限流。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Layven,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.layven%2Flayven/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "layven": {
      "type": "http",
      "url": "https://api.layven.io/mcp"
    }
  }
}

README

Layven MCP Server

Layven is a shared drive your agents mount over MCP. Every write is versioned, every action is attributed to the agent that made it, and anything can be rolled back.

One config block, no agent code changes. Hosted at https://api.layven.io/mcp.

Documents Layven MCP server 1.0.2.


Quick start

claude mcp add --transport http layven https://api.layven.io/mcp --header "Authorization: Bearer agd_your_agent_token"
  1. Get a token at layven.io: open the console, go to Agents, create one. The secret is shown once.
  2. Restart your client.
  3. Ask your agent: "list my Layven workspaces".

The point of the product shows up on the second connection. Create a second token, connect a different tool with it, and have that tool read the file the first one just wrote. Both agents see the same drive, and the activity feed says which one did what. Walkthrough: examples/two-agent-handoff.md.


Connect your client

Claude Code

claude mcp add --transport http layven https://api.layven.io/mcp --header "Authorization: Bearer agd_your_agent_token"

Claude.ai custom connector

Paste https://api.layven.io/mcp and authenticate with OAuth. That UI has no custom-header field, which is why OAuth exists.

ChatGPT

Same as Claude.ai: paste https://api.layven.io/mcp and authenticate with OAuth.

Cursor (~/.cursor/mcp.json)

json
{  "mcpServers": {    "layven": {      "url": "https://api.layven.io/mcp",      "headers": {        "Authorization": "Bearer agd_your_agent_token"      }    }  }}

Codex (~/.codex/config.toml)

toml
[mcp_servers.layven]url = "https://api.layven.io/mcp"http_headers = { "Authorization" = "Bearer agd_your_agent_token" }

Gemini (~/.gemini/settings.json)

Same JSON as Cursor, but the key is httpUrl instead of url, because Gemini reads url as an SSE endpoint.

json
{  "mcpServers": {    "layven": {      "httpUrl": "https://api.layven.io/mcp",      "headers": {        "Authorization": "Bearer agd_your_agent_token"      }    }  }}

Generic MCP JSON

json
{  "mcpServers": {    "layven": {      "url": "https://api.layven.io/mcp",      "headers": {        "Authorization": "Bearer agd_your_agent_token"      }    }  }}

Authentication

There are two ways in, and both resolve to the same token record, so permissions, revocation and the audit trail are identical either way.

Static bearer token. Send Authorization: Bearer agd_... on every request. Create it in the console; the secret is shown once.

OAuth 2.1, for clients whose UI has no custom-header field:

Authorization serverhttps://api.layven.io
Protected resource metadatahttps://api.layven.io/.well-known/oauth-protected-resource/mcp
Resourcehttps://api.layven.io/mcp
Dynamic client registrationSupported
Client secret expiryDoes not expire

Consent mints an ordinary token, which you can see and revoke in the console like any other.


Transport

  • POST https://api.layven.io/mcp, Streamable HTTP, stateless.
  • Every POST is fully independent. No session id, no session resumption, no separate SSE endpoint, no stdio.
  • GET and DELETE return HTTP 405 with exactly this body:
    json
    {"jsonrpc":"2.0","error":{"code":-32000,"message":"Method not allowed (stateless)"},"id":null}
  • Required request headers: Content-Type: application/json and Accept: application/json, text/event-stream. Both media types must be present in Accept or the server returns 406.
  • Responses come back as Content-Type: text/event-stream.
  • MCP-Protocol-Version is optional. If present it must be one of 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07, otherwise the server returns HTTP 400.
  • Capabilities: tools only. No resources, no prompts.
  • Server identity on initialize: name Layven, version 1.0.2, website https://layven.io.

Tools

Every tool takes an optional workspace, the workspace slug. A token granted exactly one workspace may omit it. list with no workspace fans out over every workspace the token can reach.

ToolAccessDoesKey arguments
listroList a folder, or find files by path substringpath, recursive, q, limit
readroRead a file at the current or an older versionpath, version
greproSearch file contents with an RE2 patternpattern, prefix, context_lines, max_matches
historyroList one file's versions, newest firstpath, limit, cursor
activityroList what changed and which agent changed itsince, path_prefix, limit
writerwCreate or replace a file with inline contentpath, content, encoding, expected_version
editrwApply string replacements to an existing text filepath, edits, expected_version
moverwMove or rename a filefrom, to, overwrite
deleterwTombstone a file, recoverable with restorepath, expected_version
restorerwRestore a file to a version, or a folder to a timestamppath + to_version, or prefix + at
lockrwTake a 5-minute advisory lock on a pathpath
unlockrwRelease a lock this token holdspath
request_uploadrwStart a large-file upload, returns a presigned PUT URLpath, size, expected_version
finalize_uploadrwCommit an uploaded file as a new versionupload_id

Only delete is annotated destructive, and it writes a tombstone version that restore brings back. write, delete, lock and unlock are annotated idempotent; edit, move, restore, request_upload and finalize_upload are not. No tool reaches outside Layven.

NOT_FOUND (unresolvable workspace), PERMISSION_DENIED, RATE_LIMITED and INTERNAL can come back from any tool, so the Errors line under each tool below names what is specific to that tool.

list

List a folder, or search every granted workspace for paths matching a substring.

Arguments

workspace?        string    workspace slug; omit to fan out over every granted workspacepath              string    default "" (workspace root)recursive         boolean   default falseinclude_deleted   boolean   default falselimit             integer   1..1000, default 500, applied per workspacecursor?           string    opaque; requires an explicit workspaceq?                string    1..1024 chars, case-insensitive substring of the full path; implies recursive

Returns

json
{  "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 is "file" or "folder". size, version, modified_at, modified_by_label, by_actor and deleted are optional per entry.

Errors: INVALID_PATH.

Notes

  • results is always an array of per-workspace blocks, even when the token is granted exactly one workspace. Do not write a client that expects a bare entries array.
  • Passing cursor while fanning out returns INVALID_PATH with reason: "cursor_requires_workspace". Pin the workspace before you paginate.
  • Folders are synthesized from path prefixes. There are no folder records to create or delete.
read

Read a file, either the current version or an older one.

Arguments

workspace?   stringpath         stringversion?     integer   defaults to the current version

Returns, inline, when the raw size is 262144 bytes or less and the mime type is text:

json
{  "path": "notes/todo.md",  "version": 7,  "size": 1284,  "mime_type": "text/markdown",  "encoding": "utf8",  "content": "..."}

Returns, for anything larger or binary:

json
{  "path": "datasets/corpus.tar.gz",  "version": 3,  "size": 431912448,  "mime_type": "application/gzip",  "download_url": "https://...",  "url_expires_at": "2026-08-05T09:27:00Z"}

Errors: NOT_FOUND (with deleted: true and last_version when the path is tombstoned), INVALID_PATH.

Notes

  • The response shape switches on size and mime type, not on a flag you pass. Above 256 KiB, or for any non-text file, you get a download_url valid for 15 minutes instead of inline content. Handle both shapes.
grep

Search file contents with a regular expression.

Arguments

workspace?       stringpath?            string    search a single fileprefix?          string    search one folder; omit both path and prefix to search the whole workspacepattern          string    min 1 char, RE2 syntaxcase_sensitive   boolean   default falsecontext_lines    integer   0..10, default 2max_matches      integer   1..200, default 50

Returns

json
{  "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}

Errors: INVALID_PATTERN, INVALID_PATH.

Notes

  • Patterns are RE2, so there are no backreferences and no lookaround. An invalid pattern returns INVALID_PATTERN.
  • Matches are found within single lines only. A pattern spanning a newline will never match.
  • One entry per matching line, like grep -n, no matter how many occurrences that line holds.
  • truncated: true means the scan hit its budget and the results are partial. Narrow the prefix or tighten the pattern.
  • Line numbers are display-only. Never paste one into edit's old_str.
history

List the versions of one file, newest first.

Arguments

workspace?   stringpath         stringlimit        integer   1..1000, default 50cursor?      string    digits only

Returns

json
{  "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 is one of write, edit, move, delete, restore. moved_from, by_actor and restorable_until are optional.

Errors: NOT_FOUND, INVALID_PATH.

Notes

  • Newest first, so limit: 1 is the cheapest way to confirm a write landed.
  • next_cursor is an opaque string, never a number. It is absent on the last page, which is how you know to stop.
  • purged: true means retention released the content of that version. The row stays for the audit trail, but restore to it returns NOT_FOUND with reason: "version_purged".
activity

List what changed in a workspace and which agent changed it.

Arguments

workspace?    stringsince?        string    RFC 3339 timestamppath_prefix?  stringlimit         integer   1..1000, default 100cursor?       string

Returns

json
{  "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 is one of agent, user, system. Newest first.

op is write, edit, move, delete, restore, purge, lock, unlock or grep. System sweeps also record purge_retention and purge_workspace_delete, both with no path. Only write, edit, move, delete and a single-file restore carry a version; on the rest it is null. Note that purge carries a real path or folder prefix, so it matches a path_prefix filter: if you are auditing a folder from this feed, a purge shows up alongside the writes.

Errors: INVALID_PATH.

Notes

  • next_cursor is an opaque string, never a number. It is absent on the last page, which is how you know to stop.
  • This is a poll. There are no webhooks, no triggers and no push. Agents coordinate by calling activity on an interval, which fits comfortably inside the rate limit at seconds-to-minutes cadence.
  • since is a timestamp, not a cursor, and two events can share one. Expect occasional re-delivery and make the work idempotent. See examples/two-agent-handoff.md.
write

Create or replace a file with inline content.

Arguments

workspace?         stringpath               stringcontent            stringencoding           "utf8" | "base64"   default "utf8"mime_type?         stringexpected_version?  integer   fail instead of overwriting a concurrent changeoverride_lock      boolean   default false

Inline cap: 1 MiB decoded. Anything larger goes through request_upload.

Returns

json
{  "path": "notes/todo.md",  "version": 8,  "size": 1301,  "content_hash": "...",  "deduplicated": false,  "unchanged": true}

unchanged is present only when it applies.

Errors: INVALID_PATH, VERSION_CONFLICT, LOCKED, QUOTA_EXCEEDED, TOO_LARGE.

Notes

  • Writing content byte-identical to the current version is a no-op: it returns unchanged: true and creates no new version. For a scheduled job that is worth logging loudly, because it usually means the generator did not run.
  • Content identical to an older version does create a new version.
  • Writing to a tombstoned path resurrects it.
edit

Apply string replacements to an existing text file without resending the whole body.

Arguments

workspace?         stringpath               stringedits              array of 1..20 objects:                     old_str      string    min 1 char                     new_str      string                     replace_all  boolean   default falseexpected_version?  integeroverride_lock      boolean   default false

Text files up to 16 MiB.

Returns

json
{  "path": "notes/todo.md",  "version": 9,  "edits_applied": 2,  "replacements": [1, 3],  "size_before": 1301,  "size_after": 1288,  "context": "..."}

unchanged is present only when it applies.

Errors: STRING_NOT_FOUND, STRING_NOT_UNIQUE, NOT_EDITABLE, TOO_LARGE_FOR_EDIT, VERSION_CONFLICT, LOCKED, QUOTA_EXCEEDED, NOT_FOUND.

Notes

  • Edits apply in order and commit atomically as one new version, so a 20-edit call is one entry in history, not twenty. If any edit fails, none of them land.
  • Each old_str must match exactly once, otherwise you get STRING_NOT_FOUND or STRING_NOT_UNIQUE. Set replace_all when you mean every occurrence.
  • Because edits apply in order, a later old_str must match the text as the earlier edits left it.
move

Move or rename a file.

Arguments

workspace?         stringfrom               stringto                 stringexpected_version?  integeroverwrite          boolean   default falseoverride_lock      boolean   default false

Returns

json
{ "from": "drafts/todo.md", "to": "notes/todo.md", "version": 1 }

version is the new version at the destination.

Errors: NOT_FOUND, INVALID_PATH, VERSION_CONFLICT (with reason: "destination_exists"), LOCKED.

Notes

  • The token needs write access to both paths. A prefix rule that covers the source but not the destination fails with PERMISSION_DENIED.
  • A live destination with overwrite: false returns VERSION_CONFLICT with reason: "destination_exists". That failure is useful: two workers racing to claim the same item can move it, and the loser gets a clean error instead of duplicated work.
delete

Tombstone a file.

Arguments

workspace?         stringpath               stringexpected_version?  integeroverride_lock      boolean   default false

Returns

json
{ "path": "notes/todo.md", "version": 10, "unchanged": true }

unchanged is present only when it applies.

Errors: NOT_FOUND, INVALID_PATH, VERSION_CONFLICT, LOCKED.

Notes

  • This writes a tombstone version, it does not erase content. The file stays recoverable with restore for as long as your plan's version history window allows.
  • Writing to the same path later resurrects it as a new version on the same history.
  • list hides tombstoned paths unless you pass include_deleted: true.
restore

Restore one file to an earlier version, or a whole folder to a point in time.

Arguments, file form:

workspace?      stringpath            stringto_version      integeroverride_lock   boolean   default false

Arguments, folder form:

workspace?      stringprefix          stringat              string    RFC 3339 timestamp in UTC, e.g. 2026-08-05T14:04:55Zoverride_lock   boolean   default false

Returns, file form:

json
{ "path": "notes/todo.md", "version": 11 }

Returns, folder form:

json
{  "restored": 42,  "deleted": 3,  "affected_paths": ["content/pricing.md", "content/index.md"],  "total": 45}

affected_paths is a capped sample; total is the true count.

Errors: NOT_FOUND (with reason: "version_purged" when retention already released the target version), INVALID_PATH, LOCKED.

Notes

  • at must be UTC, ending in Z, with optional milliseconds. A UTC offset such as +02:00 is rejected even though it is valid RFC 3339, so convert before you call.
  • Restore appends new versions and never rewrites history. The bad versions stay in history, so restoring to the wrong timestamp is itself restorable, and restoring twice is safe.
  • In the folder form, files that did not exist at at receive delete tombstones, counted by deleted. They are not erased and a later write brings them back.
  • There is no dry run. Size the operation with list and confirm a single file with history first. Walkthrough: examples/folder-restore-after-bad-run.md.
lock

Take an advisory lock on a path.

Arguments

workspace?   stringpath         string

Returns

json
{ "path": "notes/todo.md", "expires_at": "2026-08-05T09:17:44Z" }

Errors: LOCKED, INVALID_PATH.

Notes

  • Advisory and 5 minutes. Call lock again with the same token to renew.
  • Locks never block reads. A foreign valid lock makes writes return LOCKED with locked_by_label and expires_at, unless the caller passes override_lock: true, which is recorded in the activity feed.
  • The file need not exist, so you can lock a path you are about to create.
  • For work that can be made idempotent, prefer a claim with move over a lock: it survives a crash, and a 5-minute TTL does not.
unlock

Release a lock this token holds.

Arguments

workspace?   stringpath         string

Returns

json
{ "path": "notes/todo.md", "released": true }

Errors: PERMISSION_DENIED (the lock belongs to another token), INVALID_PATH.

Notes

  • Unlocking a path that holds no lock returns released: true, not NOT_FOUND. The call says nothing about whether a lock existed, so it is not a way to ask who holds one.
request_upload

Start an upload for content too large for inline write. First of two steps; see Large file uploads.

Arguments

workspace?         stringpath               stringsize               integer   positive, the exact byte count of the filemime_type?         stringexpected_version?  integeroverride_lock      boolean   default false

Returns

json
{  "upload_id": "...",  "put_url": "https://...",  "url_expires_at": "2026-08-05T09:27:00Z",  "max_size": 1073741824}

Errors: TOO_LARGE, QUOTA_EXCEEDED, VERSION_CONFLICT, LOCKED, INVALID_PATH.

Notes

  • The presigned PUT URL is valid for 15 minutes and the upload record for 1 hour. There is no resumable or multipart upload: if the PUT fails, start again from request_upload.
  • size must be the exact byte count. It is re-checked at finalize_upload.
finalize_upload

Commit an uploaded file as a new version. Second of two steps.

Arguments

workspace?   stringupload_id    string

Returns

json
{  "path": "datasets/corpus.tar.gz",  "size": 431912448,  "version": 3,  "content_hash": "..."}

Errors: UPLOAD_EXPIRED, VERSION_CONFLICT, QUOTA_EXCEEDED, TOO_LARGE.

Notes

  • Size and expected_version are both re-checked here, so a VERSION_CONFLICT can surface at finalize even though request_upload succeeded. Someone wrote the path while you were uploading; start again from request_upload.
  • Calling finalize a second time returns UPLOAD_EXPIRED.

Errors

Domain failures come back as a normal tool result carrying isError: true, whose text content is JSON:

json
{ "code": "VERSION_CONFLICT", "message": "...", "current_version": 9 }

They are never protocol-level JSON-RPC errors. Agents and clients should branch on code.

Argument validation fails the same way, but the text is not JSON. Passing an argument of the wrong type returns isError: true with a plain English string like MCP error -32602: Input validation error: Invalid arguments for tool activity: ..., produced by the MCP layer before the request reaches Layven. So parse defensively: an isError result whose text will not parse as JSON is a bug in your call, not a Layven domain error. upload/layven-upload.mjs does exactly this, falling back to code: "UNKNOWN" with the raw text as the message.

CodeMeansExtras
NOT_FOUNDPath, version or workspace absentworkspaces (the token's slugs) when a workspace slug does not resolve; deleted: true and last_version on a tombstoned path; reason: "version_purged" on a purged version
PERMISSION_DENIEDToken lacks the access level, or a prefix rule blocks the pathrequired
INVALID_PATHPath fails normalizationreason
VERSION_CONFLICTexpected_version did not match, or the destination existscurrent_version, sometimes reason (for example destination_exists)
LOCKEDAnother token holds a valid locklocked_by_label, expires_at
QUOTA_EXCEEDEDOrganization is over its storage quotalimit_bytes, used_bytes
TOO_LARGEInline content over the cap, or file over 1 GiBmax_bytes
UPLOAD_EXPIREDFinalize called on an expired or already-consumed upload
RATE_LIMITEDToken or organization rate cap hitretry_after_ms
INTERNALUnexpected server failurerequest_id
STRING_NOT_FOUNDedit: old_str is not present in the filehint
STRING_NOT_UNIQUEedit: old_str matched more than once and replace_all was not set
NOT_EDITABLEedit: the file is not text
TOO_LARGE_FOR_EDITedit: file over 16 MiB
INVALID_PATTERNgrep: the pattern is not valid RE2

RATE_LIMITED is the only code worth retrying automatically: sleep retry_after_ms, then try again.


Limits

LimitValue
Inline write1 MiB decoded; larger content goes through request_upload
Inline read256 KiB and a text mime type, otherwise a download URL
EditText files up to 16 MiB, up to 20 edits per call
Grep8 MiB per file scanned, 500 candidate files per call, partial results past the time budget
Max file size1 GiB
Presigned PUT URL15 minutes
Upload record1 hour
Download URL15 minutes
Path length1024 bytes
Lock TTL5 minutes, renewable
Rate limit600 requests per minute per token, 3000 per minute per organization

Exceeding a rate limit returns RATE_LIMITED with retry_after_ms.


Paths and versioning

Paths are UTF-8, /-separated and case-sensitive. They are normalized on input:

  • no leading slash: /a/b becomes a/b
  • no duplicate slashes
  • no . or .. segments, and no empty segments
  • no trailing slash on a file
  • no control characters
  • 1024 bytes maximum

Anything else returns INVALID_PATH with a reason. Directories are implicit: there are no folder records, and list synthesizes folders from path prefixes.

Versioning. Every mutation creates a new version, numbered per file. delete writes a tombstone version. move creates a version at the destination and tombstones the source. restore appends a new version reproducing an earlier state. History is append-only and is never rewritten, which is why a bad restore is itself restorable.

Optimistic concurrency. The default is last-write-wins, which is safe because nothing is lost. When you want a write to fail rather than clobber a concurrent change, pass expected_version with the version you read. A mismatch returns VERSION_CONFLICT with current_version in the payload, so the caller can re-read and decide.

Locks. lock takes a 5-minute advisory lock, renewed by calling lock again with the same token. A foreign valid lock makes writes return LOCKED with locked_by_label and expires_at; override_lock: true proceeds anyway and is recorded in the activity feed. Locks never block reads.


Permissions

Each token is granted access to specific workspaces at one of three levels:

LevelTools
rolist, read, grep, history, activity
rweverything in ro, plus write, edit, move, delete, restore, lock, unlock, request_upload, finalize_upload
adminreserved for future workspace management

A grant can carry optional prefix rules that restrict a token to particular folders, expressed as allow or deny lists. Deny beats allow. move requires permission on both the source and the destination path.

Give each agent its own token. That is what makes by_label in list, history and activity readable, and it is what lets you revoke one agent without touching the others.


Large file uploads

Inline write caps at 1 MiB. Above that, upload in three steps.

1. Ask for a URL. Call request_upload with the exact byte count:

json
{ "path": "datasets/corpus.tar.gz", "size": 431912448, "mime_type": "application/gzip" }
json
{  "upload_id": "...",  "put_url": "https://...",  "url_expires_at": "2026-08-05T09:27:00Z",  "max_size": 1073741824}

2. PUT the bytes to put_url. This is a plain HTTP PUT of the raw file, not an MCP call. The URL is valid for 15 minutes.

3. Commit it. Call finalize_upload:

json
{ "upload_id": "..." }
json
{  "path": "datasets/corpus.tar.gz",  "size": 431912448,  "version": 3,  "content_hash": "..."}

Why there is no SDK

There is no Layven client library and there will not be one. Layven is a hosted MCP server: you point your client at one URL and your agent gets 14 tools, with no code to write and nothing to keep up to date. This is the one exception. The upload flow has a middle step that is a raw HTTP PUT, and an MCP client cannot issue one, so we ship a single dependency-free script for it. Copy it, read it, change it. It is MIT.

upload/layven-upload.mjs

Node 18 or newer. No dependencies, no install.

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 is required. --url defaults to https://api.layven.io/mcp.

Run its tests from the repository root with:

node --test

Examples


Plans

FreePro $19/moScale $49/moEnterprise
Storage5 GB100 GB500 GBCustom
Version history30 days1 yearUnlimitedUnlimited
Activity log30 days1 year1 yearUnlimited
Workspaces1525Unlimited
Tokens225100Unlimited
Seats1310Unlimited
Max file size1 GiB1 GiB1 GiB1 GiB
Rate limit600 req/min/token600 req/min/token600 req/min/token600 req/min/token

Flat price. No meters, no credits.


Data residency

Your files are stored on OVHcloud in Gravelines, France, and are encrypted at rest. No third-party AI or model API ever touches your content. You can export everything as plain files, and deletion is real deletion.


Versioning

The version in server.json and in the changelog matches the version the server reports on initialize, so you can always check what you are talking to. Documentation changes that do not track a server change do not bump the version.

See CHANGELOG.md.


Support

Bugs in these docs, the examples, or the upload helper: open an issue. Account, billing, or data questions: [email protected].


License

MIT covers this repository: the documentation, the examples, and the upload helper. The Layven service itself is closed source.

來源:README.md,提交 4f5374b

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

1
  1. v1.0.2最新Sep 16, 2026

評分

已滿足適用檢查項的 85%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分