Show HN: Giving Claude Code "hands" to deliver local files (P2P, No Cloud)
github.comHi HN,
I've been using Claude Code (CLI) heavily, but I hit a major friction point: When Claude generates artifacts locally (like a specific SQLite dump, build logs, or a patch), it has no easy way to "hand" them to a coworker.
I didn't want to upload sensitive local files to a third-party cloud (S3/Drive) just to send a temporary file to a teammate sitting virtually next to me.
So, I built an MCP server (ffl-mcp) that gives Claude the capability to share files directly via P2P.
The Workflow:
1. I ask Claude: "Zip the logs and send them to Bob."
2. Claude uses the tool to generate a one-time P2P link.
3. My coworker clicks the link to download immediately (streaming transfer, E2EE).
Under the hood:
It wraps ffl [0], a CLI tool I built for NAT traversal (WebRTC, relay if failed). (I packaged the core tool as an "Actually Portable Executable" so it runs as a single binary across platforms without Python environment headaches).
It's open source and you can try it with uvx: https://github.com/nuwainfo/ffl-mcp
[0] The core ffl tool: https://github.com/nuwainfo/ffl
>> 1. I ask Claude: "Zip the logs and send them to Bob."
>> 2. Claude uses the tool to generate a one-time P2P link.
>> 3. My coworker clicks the link to download immediately
It is not clear how DOES the co-worker get the link?
Oh, in this demo the right panel is just simulating the co-worker. In a real case, I would send the link to him via IM (for example, Slack). Since this is only a demo, I’m playing both roles myself. :p
APE is referenced a few times. Can you expand on how you leverage it in the underlying transfer tool? Seems all python—i expected some C
I actually wrote a section about this here: https://github.com/nuwainfo/ffl?tab=readme-ov-file#porting-t.... In short, I used superconfigure the project’s ported Python APE, rewrote all C extensions into Python APE as built-in extensions, modified libraries like aiortc to use them, and finally resolved several tricky porting issues across platforms. It was a tough process, but I managed to get it working successfully :)