[feat] add MCP file browsing and cancellable transfers

This commit is contained in:
dijunkun
2026-11-06 20:36:48 +08:00
parent 0aed57ed4d
commit 6bfcd5cf3d
20 changed files with 537 additions and 23 deletions
+12
View File
@@ -788,6 +788,18 @@ private:
} else if (method == "action") {
StartAction(j, id);
return false;
} else if (method == "files") {
Fields(j, {"id", "method", "operation", "operation_id", "path", "paths",
"destination", "request_id", "offset"});
const auto operation = String(j, "operation", 16);
const bool existing = operation == "status" || operation == "cancel" ||
operation == "list_result" || operation == "list_cancel";
if (!allowed_ || (!existing && (paused_ || !session_.ControlEnabled())))
throw std::invalid_argument("CONTROL_DENIED");
auto request = j;
request.erase("id"); request.erase("method");
Reply(id, session_.Files(request));
return false;
} else if (method == "clipboard") {
Fields(j, {"id", "method", "operation", "operation_id", "text"});
if (!allowed_ || paused_ || !session_.ControlEnabled())
+6
View File
@@ -145,3 +145,9 @@ Updated desktop hosts answer the versioned `automation` capability handshake. Wh
## Clipboard
`clipboard` accepts `operation: get | set`. Writes additionally require `operation_id` and `text` (up to 16384 UTF-8 bytes, including an empty string to clear). Reads return up to 128 KiB of text. The existing chunked `web-clipboard` stream carries values and applied/rejected replies. Additive `read`, `empty`, and `clear` frames are enabled by the remote `clipboard` capability. Clipboard access requires control permission and respects human pause. Cancellation of an issued write reports an uncertain effect. Repeated write operation IDs retrieve the cached result.
## File operations
`files` supports `list`, `list_result`, `list_cancel`, `upload`, `download`, `status`, and `cancel`. Listing requests return a numeric `request_id`. Transfer requests require an `operation_id`, absolute `paths`, and an existing absolute `destination` directory. Progress and listing pages use `offset` and return `next_offset` with at most 256 entries.
The desktop and CLI share `FileBrowser` and the existing file transfer engine. Preparation and completion messages carry a transfer identifier to bind incoming files to the requested destination. A cancelled transfer cleans unfinished staging files. The capability handshake advertises `files` on compatible hosts. Queries and cancellation of existing tasks remain available during human pause.
+2 -1
View File
@@ -12,12 +12,13 @@ end
target("crossdesk_controller")
set_kind("static")
add_deps("minirtc", "crossdesk_wire")
add_deps("minirtc", "crossdesk_wire", "crossdesk_file_browser")
add_packages("spdlog", "libpng", "libyuv")
add_includedirs(path.join(controller_dir, "include"),
path.join(minirtc_dir, "src/api"), {public = true})
add_includedirs(path.join(minirtc_dir, "src/log"))
add_files(path.join(controller_dir, "src/*.cpp"))
remove_files(path.join(controller_dir, "src/file_browser.cpp"))
target_end()
target("crossdesk_terminal")