Perkoon — The Agent Data Layer
File transfer for humans and the things replacing them.
Your agent has compute, memory, and context. What it lacks is a jump gate to the physical world. Perkoon is that gate — P2P file transfer over WebRTC, engineered for autonomous machines from day one.
Not "AI-ready" the way a gas station is gourmet-ready. Actually built for machines — JSON event streams, structured exit codes, MCP native tools, an A2A protocol endpoint, and a state machine that doesn't need a browser, a mouse, or a soul.
Four integration methods — pick the one that fits your runtime:
| Method | Best for | Install size |
|---|
| MCP Server | Coding agents (Claude Code, Cursor, Windsurf, VS Code Copilot) | ~8 MB |
| CLI |
Agents with shell access | ~8 MB |
|
A2A Protocol | Agents with HTTP but no shell (ChatGPT, web agents) | Zero — just POST |
|
Browser Automation | Full UI control via Playwright/Puppeteer | ~200 MB (Chromium) |
Three supported flight paths:
- - Agent → Human: Your agent sends a file. The human opens a link in any browser. No install on their end.
- Agent → Agent: CLI to CLI, MCP to MCP, or A2A to A2A. Two machines, no humans in the loop.
- Agent → Pipeline: Stream received files to stdout, pipe into processing. No disk writes required.
P2P transfers are free, unlimited, and encrypted. Both ends need to be online — that's the only constraint. For sensitive files, always use --password — without it, anyone with the share link can download.
METHOD 1: MCP Server (recommended for coding agents)
If your host supports MCP, this is the fastest path. Three native tools, zero shell commands.
Install: npx -y @perkoon/mcp@0.1.3 (stdio transport, pinned version)
Tools provided:
- -
send_file — Send a file. Returns session code + share URL. Waits for receiver. - INLINECODE3 — Receive files from a session code. Saves to disk.
- INLINECODE4 — Check if a session is active, expired, or not found.
Configuration for common hosts:
CODEBLOCK0
- - Claude Code: Add to
.mcp.json in your project - Claude Desktop: Add to INLINECODE6
- Cursor / VS Code / Windsurf: Settings → MCP → Add Server → INLINECODE7
Once configured, just call the tools directly — no bash, no log polling, no background processes.
METHOD 2: CLI (for agents with shell access)
IMPORTANT: Use npx -y perkoon@0.3.6 (pinned version) to avoid dynamic fetching of unaudited code.
SENDING a file
Step 1: Confirm the file path with the user, then start send
Before sending, confirm the file path and name with the user. Do not send files from sensitive directories without explicit user approval.
Replace /path/to/file with the actual file path:
CODEBLOCK1
Output: INLINECODE10
Once session_created appears, share the URL with the user. Example: "Here's your file — open this link on any device to download it: https://perkoon.com/K7MX4QPR9W2N"
The receiver doesn't need to install anything. The link works in any browser.
For password-protected sends, add --password SECRET and share both the URL and password.
Step 2: Monitor until complete — then REPORT BACK
You MUST run this after sharing the link. Do NOT skip this step.
CODEBLOCK2
- -
===TRANSFER COMPLETE=== → Tell the user: "File sent successfully!" Include speed and duration from the JSON. ===TRANSFER FAILED=== → Tell the user what went wrong.- You MUST tell the user the outcome. Never finish silently.
SENDING into a pre-created session (Agent → Agent)
When another agent creates a session via A2A and gives you a session code + sender key:
CODEBLOCK3
Then monitor with the same Step 2 above. This joins an existing session as sender instead of creating a new one. The receiving agent runs npx -y perkoon@0.3.6 receive CODE --json on their end.
RECEIVING a file
Replace CODE with the 12-character session code:
CODEBLOCK4
For password-protected sessions, add --password SECRET.
- -
===TRANSFER COMPLETE=== → Tell the user: "File received!" and the save path. ===TRANSFER FAILED=== → Tell the user what went wrong.- You MUST tell the user the outcome. Never finish silently.
Files are saved to /home/openclaw/.openclaw/workspace/received/.
Pipe to stdout
Stream a received file directly into another process — no disk write:
CODEBLOCK5
METHOD 3: A2A Protocol (for agents with HTTP, no shell)
If you can make HTTP requests but can't run shell commands, use the A2A endpoint directly.
Endpoint: POST https://perkoon.com/a2a
Protocol: JSON-RPC 2.0
Agent Card: INLINECODE22
Discover capabilities
CODEBLOCK6
Create a send session
CODEBLOCK7
Returns sender_url (for browser upload) + CLI commands + sender_key for A2A sender joining.
If you have shell access, run the CLI command from the response. If not, share the sender_url with your user — they open it in any browser to upload.
Join a session as receiver
CODEBLOCK8
Check session status
CODEBLOCK9
Runtime hints
Include clientCapabilities in your DataPart to get optimized instructions:
CODEBLOCK10
Agents declaring shell access get CLI commands. Web-only agents get browser URLs.
METHOD 4: Browser Automation (Playwright/Puppeteer)
For agents that need full browser UI control. Heavier than CLI but gives visual verification.
Ready-to-run scripts (requires npm install playwright):
CODEBLOCK11
Manual sender flow
- 1. Navigate to
https://perkoon.com/create, accept TOS, click Start - Skip confirmation modals:
localStorage.setItem('perkoon_skip_confirm_direct-confirm', 'true') and INLINECODE30 - Add files: INLINECODE31
- Share session code with recipient
- Wait for receiver: INLINECODE32
- Click INLINECODE33
- Wait: INLINECODE34
Manual receiver flow
- 1. Register download handler: INLINECODE35
- Navigate to INLINECODE36
- Accept transfer: wait for
[data-testid="transfer-accept"], click [data-testid="transfer-tos-checkbox"] if visible, then click INLINECODE39 - Wait: INLINECODE40
- Save: INLINECODE41
CLI reference
| Flag | Description |
|---|
| INLINECODE42 | Machine-readable JSON events (always use for automation) |
| INLINECODE43 |
Join an existing session as sender (A2A agent-to-agent) |
|
--sender-key <key> | Auth key for
--session (provided by session creator) |
|
--password <pw> | End-to-end password protection |
|
--timeout <sec> | Peer wait time (default: 300, use 1800 for sends) |
|
--output <dir> | Save directory (default: ./received) |
|
--output - | Stream to stdout (no disk write) |
|
--overwrite | Replace existing files |
|
--quiet | Suppress human-readable output |
JSON event stream
Events appear in order on stdout when using --json:
| Event | Meaning | Key fields |
|---|
| INLINECODE53 | Ready — share the link now | INLINECODE54 , INLINECODE55 |
| INLINECODE56 |
Peer joined | |
|
webrtc_connected | Direct P2P link established | |
|
progress | Transfer in progress |
percent,
speed,
eta |
|
transfer_complete | Done |
duration_ms,
speed |
|
error | Failed |
message,
exit_code |
Exit codes
Bad arguments |
| 2 | File not found |
| 3 | Network/session error |
| 4 | Wrong password |
| 5 | Timeout — no peer joined |
Rules
- 1. ALWAYS use
--json for parseable output - ALWAYS confirm the file path with the user before sending
- Once
session_created appears, share the URL with the user - ALWAYS use
--timeout 1800 for sends (30 min for the human to open the link) - ALWAYS use
--overwrite for receives - ALWAYS monitor until
transfer_complete or error — then tell the user the result - NEVER kill the process mid-transfer
- The receiver does NOT need perkoon installed — the browser link works for everyone
- Use pinned versions:
npx -y perkoon@0.3.6 — never use INLINECODE75 - NEVER send files from sensitive directories (~/.ssh, ~/.gnupg, /etc) without explicit user approval
Discovery endpoints
| URL | What it is |
|---|
| INLINECODE76 | A2A agent card (machine-readable capabilities) |
| INLINECODE77 |
Full agent integration guide |
|
https://perkoon.com/automate | Human-readable automation docs |
|
https://www.npmjs.com/package/@perkoon/mcp | MCP server package |
|
https://www.npmjs.com/package/perkoon | CLI package |
Perkoon — 代理数据层
为人类及其替代者设计的文件传输工具。
你的代理拥有计算能力、记忆和上下文。它所缺少的是通往物理世界的跳跃门。Perkoon 就是那扇门——基于WebRTC的P2P文件传输,从第一天起就为自主机器设计。
不是像加油站自称美食级那样的AI就绪。而是真正为机器构建——JSON事件流、结构化退出码、MCP原生工具、A2A协议端点,以及一个不需要浏览器、鼠标或灵魂的状态机。
四种集成方式——选择适合你运行环境的那一种:
| 方式 | 最佳适用场景 | 安装大小 |
|---|
| MCP服务器 | 编码代理(Claude Code、Cursor、Windsurf、VS Code Copilot) | ~8 MB |
| CLI |
具有shell访问权限的代理 | ~8 MB |
|
A2A协议 | 有HTTP但无shell的代理(ChatGPT、网页代理) | 零——只需POST |
|
浏览器自动化 | 通过Playwright/Puppeteer实现完整UI控制 | ~200 MB(Chromium) |
三种支持的传输路径:
- - 代理 → 人类:你的代理发送文件。人类在任何浏览器中打开链接。接收方无需安装。
- 代理 → 代理:CLI到CLI、MCP到MCP或A2A到A2A。两台机器,无需人类参与。
- 代理 → 管道:将接收到的文件流式输出到stdout,通过管道传输到处理程序。无需磁盘写入。
P2P传输免费、无限制且加密。两端需要同时在线——这是唯一的限制条件。对于敏感文件,始终使用--password——否则任何拥有分享链接的人都可以下载。
方法1:MCP服务器(推荐用于编码代理)
如果你的主机支持MCP,这是最快的路径。三个原生工具,零个shell命令。
安装:npx -y @perkoon/mcp@0.1.3(stdio传输,固定版本)
提供的工具:
- - sendfile — 发送文件。返回会话码+分享URL。等待接收方。
- receivefile — 从会话码接收文件。保存到磁盘。
- check_session — 检查会话是否活跃、已过期或未找到。
常见主机的配置:
json
{
mcpServers: {
perkoon: {
command: npx,
args: [-y, @perkoon/mcp@0.1.3]
}
}
}
- - Claude Code:添加到项目中的.mcp.json
- Claude Desktop:添加到claudedesktopconfig.json
- Cursor / VS Code / Windsurf:设置 → MCP → 添加服务器 → npx -y @perkoon/mcp@0.1.3
配置完成后,直接调用工具即可——无需bash、无需日志轮询、无需后台进程。
方法2:CLI(适用于具有shell访问权限的代理)
重要提示:使用npx -y perkoon@0.3.6(固定版本)以避免动态获取未经审计的代码。
发送文件
步骤1:与用户确认文件路径,然后开始发送
在发送之前,与用户确认文件路径和名称。未经用户明确批准,不得从敏感目录发送文件。
将/path/to/file替换为实际文件路径:
bash
rm -f /tmp/perkoon-send.log /tmp/perkoon-send.pid
npx -y perkoon@0.3.6 send /path/to/file --json --timeout 1800 > /tmp/perkoon-send.log 2>&1 &
echo $! > /tmp/perkoon-send.pid
等待会话码(最多30秒)
for i in $(seq 1 30); do
if grep -q session_created /tmp/perkoon-send.log 2>/dev/null; then
grep session_created /tmp/perkoon-send.log
break
fi
if grep -q event:error /tmp/perkoon-send.log 2>/dev/null; then
echo ===发送失败=== && cat /tmp/perkoon-send.log
break
fi
sleep 1
done
输出:{event:sessioncreated,sessioncode:K7MX4QPR9W2N,share_url:https://perkoon.com/K7MX4QPR9W2N}
一旦出现session_created,与用户分享URL。例如:这是你的文件——在任何设备上打开此链接即可下载:https://perkoon.com/K7MX4QPR9W2N
接收方无需安装任何东西。该链接在任何浏览器中均可使用。
对于密码保护的文件发送,添加--password SECRET并同时分享URL和密码。
步骤2:监控直到完成——然后报告结果
分享链接后必须运行此步骤。不得跳过。
bash
for i in $(seq 1 360); do
if grep -q transfer_complete /tmp/perkoon-send.log 2>/dev/null; then
echo ===传输完成=== && grep transfer_complete /tmp/perkoon-send.log
break
fi
if grep -q event:error /tmp/perkoon-send.log 2>/dev/null; then
echo ===传输失败=== && grep error /tmp/perkoon-send.log
break
fi
if [ $((i % 30)) -eq 0 ]; then
grep progress /tmp/perkoon-send.log 2>/dev/null | tail -1
fi
sleep 5
done
- - ===传输完成=== → 告诉用户:文件发送成功! 包含JSON中的速度和持续时间。
- ===传输失败=== → 告诉用户出了什么问题。
- 你必须告知用户结果。绝不能静默结束。
发送到预先创建的会话(代理到代理)
当另一个代理通过A2A创建会话并给你一个会话码和发送者密钥时:
bash
rm -f /tmp/perkoon-send.log /tmp/perkoon-send.pid
npx -y perkoon@0.3.6 send /path/to/file --session CODE --sender-key KEY --json --timeout 1800 > /tmp/perkoon-send.log 2>&1 &
echo $! > /tmp/perkoon-send.pid
然后使用上述步骤2进行监控。这将作为发送者加入现有会话,而不是创建新会话。接收代理在其端运行npx -y perkoon@0.3.6 receive CODE --json。
接收文件
将CODE替换为12字符的会话码:
bash
rm -f /tmp/perkoon-recv.log /tmp/perkoon-recv.pid
npx -y perkoon@0.3.6 receive CODE --json --overwrite --output /home/openclaw/.openclaw/workspace/received/ > /tmp/perkoon-recv.log 2>&1 &
echo $! > /tmp/perkoon-recv.pid
for i in $(seq 1 360); do
if grep -q transfer_complete /tmp/perkoon-recv.log 2>/dev/null; then
echo ===传输完成=== && grep transfer_complete /tmp/perkoon-recv.log
break
fi
if grep -q event:error /tmp/perkoon-recv.log 2>/dev/null; then
echo ===传输失败=== && grep error /tmp/perkoon-recv.log
break
fi
sleep 5
done
对于密码保护的会话,添加--password SECRET。
- - ===传输完成=== → 告诉用户:文件已接收! 以及保存路径。
- ===传输失败=== → 告诉用户出了什么问题。
- 你必须告知用户结果。绝不能静默结束。
文件保存到/home/openclaw/.openclaw/workspace/received/。
管道到stdout
将接收到的文件直接流式传输到另一个进程——无需磁盘写入:
bash
npx -y perkoon@0.3.6 receive CODE --output - > /path/to/destination
方法3:A2A协议(适用于具有HTTP但无shell的代理)
如果你可以发送HTTP请求但不能运行shell命令,请直接使用A2A端点。
端点: POST https://perkoon.com/a2a
协议: JSON-RPC 2.0
代理卡片: https://perkoon.com/.well-known/agent.json
发现能力
json
{
jsonrpc: 2.0,
method: message/send,
id: