Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>SerialCP — Serial File TransferNew to Visual Studio Code? Get it now.
SerialCP — Serial File Transfer

SerialCP — Serial File Transfer

Bughht

| (0) | Free
Resumable, MD5-verified file transfer and a remote file explorer over a serial console.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

SerialCP

Resumable, MD5-verified file transfer and a remote file explorer over a serial console, inside VS Code.

Built for the case where rz/sz in a terminal emulator keeps stalling on large files and an unstable line means a transfer that dies at 90% has to start again from zero.

SerialCP

What you get

  • Port and baud picker — choose the port, baud rate, parity and flow control from the command palette; settings persist per workspace.
  • Remote file tree — browse the far end like an SSH remote, with sizes, timestamps and permissions.
  • Drag and drop — drop files or whole folders from Explorer or the desktop onto a remote directory to upload; drag within the tree to move.
  • Resume (断点续传) — an interrupted transfer picks up from the last verified block instead of restarting. Pull the cable and plug it back in; the transfer carries on.
  • MD5 end to end — every block is CRC32-checked on the wire and the whole file is MD5-compared before the .scpart is renamed into place. A file that arrives is a file that matched.
  • A terminal that keeps working — the remote shell runs over the same port as the transfer, with keystrokes prioritised over bulk data.
  • Edit remote files in place — remote paths mount as serialcp:/…, so small files open, edit and save in the editor.
  • Status bar — live progress, rate and ETA, and a visible warning when the link drops and a transfer is waiting to resume.

Requirements

  • The far end runs Linux with python3 on PATH. Nothing needs to be installed there: SerialCP streams a ~37 KB agent over the console on first connect and caches it under /tmp/.serialcp.
  • You can reach a shell prompt on the console. If MobaXterm can drive it, SerialCP can.

Install

npm install
npm run compile

Then either press F5 in VS Code to launch an Extension Development Host, or package and install it:

npx @vscode/vsce package --allow-missing-repository
code --install-extension serialcp-1.0.0.vsix

Quick start

  1. SerialCP: Connect… from the command palette, then pick the port and baud rate. Close any other program holding the port first — a serial port has one owner.

    If the remote answers with a login prompt rather than a shell, run SerialCP: Open Serial Console first. That pipes the port straight to a terminal so you can log in, and the port stays open when you then connect — which matters, because closing it drops DTR and a getty will log you straight back out.

  2. The SerialCP icon in the activity bar shows the remote filesystem.

  3. Drag a file onto a folder in that tree to upload it. Right-click a remote file and choose Download… to fetch it.

  4. Open Serial Terminal gives you the remote shell, usable while a transfer runs.

How it works

On connect, SerialCP drives the login shell in plain line mode just long enough to stream a small Python agent across and start it. The agent puts the tty into raw mode and from then on the line carries a framed binary protocol rather than text.

 'S' 'C' | type u8 | flags u8 | seq u16 | len u32 | hdr-crc8 | payload | crc32

Each frame carries a header CRC8 and a payload CRC32, and the decoder resynchronises on the magic. Line noise, a burst of kernel log output on the console, or a half-written frame costs one frame rather than the session.

The link is multiplexed: terminal traffic, filesystem requests and bulk file data share it, and both ends send terminal bytes ahead of file data. Bulk frames are written in 4 KiB pieces so a keystroke never waits behind a whole block. On the board this tool was developed against, a keystroke still round -tripped in 216 ms with an upload saturating the line.

Resume

An upload writes to name.scpart on the remote and is renamed only after the whole-file MD5 matches. On a retry, SerialCP asks how much of the partial is there and compares the MD5 of its own matching prefix. If they agree it resumes at that offset; if they do not — a partial that was corrupted rather than merely truncated — it pulls a per-block digest list and rewinds to the first block that actually differs. Downloads work the same way in reverse.

Because the resume point is negotiated from scratch on every attempt, a transfer survives the link dropping repeatedly. In testing, an upload interrupted twice finished having resent 1.7% of the file.

Speed

Blocks are deflated before they go out and sent raw if they do not shrink, so already-compressed data costs nothing extra. On a 921600 line the board saw 173 KB/s effective on mixed data — above the 92 KB/s the wire can carry — and an identical file already on the far end is detected by MD5 and skipped outright.

Settings worth knowing

Setting Default Why you would change it
serialcp.baudRate 921600 Must match the remote console.
serialcp.rtscts false Turn on above 921600 if your cable wires RTS/CTS; it stops the remote UART overrunning.
serialcp.blockSize 16384 Also the resume granularity. Smaller loses less on a bad line; larger is marginally faster on a good one.
serialcp.window 8 Blocks in flight. Higher hides latency, too high can overrun a remote with no flow control.
serialcp.compression 6 0 disables. Blocks that do not shrink are sent raw anyway.
serialcp.agentDir /tmp/.serialcp Point at something persistent, e.g. /var/lib/serialcp, to survive a reboot without re-uploading the agent.
serialcp.maxAttempts 100 How many times a transfer may resume before giving up.
serialcp.bootstrap.lineDelayMs 8 Raise if the agent fails its md5 check while uploading on a lossy line.

Troubleshooting

"Agent upload kept failing its md5 check" — the console is losing characters during bootstrap. Lower serialcp.bootstrap.chunkSize to 128 and raise serialcp.bootstrap.lineDelayMs to 20.

"No python3 on the remote" — set serialcp.pythonCommand to the full path if the interpreter is somewhere unusual.

The port will not open — something else has it. A serial port has exactly one owner; close the MobaXterm session first.

The console goes quiet and nothing responds — an agent may still be holding the tty from a previous session. Connecting again clears it: SerialCP opens with a handshake, adopts a live agent, and sends a BYE to free a wedged one. If it is still silent, the login session on the far end has gone; replug the adapter, and power-cycle the board if that does not bring it back.

The file tree goes blank and uploads stop responding — most often the line is saturated by a program producing heavy terminal output, so listings queue behind it. The tree now says so rather than showing nothing, and requests are re-sent automatically. Terminal output is backpressured, so a chatty program slows down instead of growing the agent without bound.

Transfers are slower than expected — check SerialCP: Show Link Statistics for resyncs and bad CRCs. A nonzero count means the line is corrupting data and blocks are being resent; try a lower baud rate or enable RTS/CTS.

Development

npm run compile          # build, embedding the agent
npm run watch            # rebuild on change

Three test suites, in increasing order of realism:

wsl python3 scripts/test_agent.py      # the agent alone, over a real pty
node scripts/test-host.js              # the whole host stack against bash in WSL
node scripts/test-reconnect.js         # reconnect and resume, with a paced pipe

And against real hardware, which needs a board on the other end:

node scripts/probe-port.js COM5 921600     # is anything alive on the line
node scripts/probe-remote.js COM5 921600   # what tools does the remote have
node scripts/test-serial.js COM5 921600    # full end-to-end on the real port
node scripts/test-resilience.js COM5 921600

test-resilience.js deliberately closes the port mid-transfer. On a console whose modem-control lines are wired through, that can drop DTR and take the remote login session with it, which may need a replug or a power cycle to recover. Run it knowingly.

The agent is a single dependency-free Python file, agent/serialcp_agent.py. scripts/build-agent.js deflates it into src/core/agentSource.ts at build time, so editing the agent and rebuilding is all it takes — the remote picks up the new one automatically, since the cache is keyed by content hash.

Layout

agent/serialcp_agent.py   the remote agent: framing, pty, fs ops, transfers
src/core/frame.ts         the same codec on the host side
src/core/shell.ts         drives the login shell until the agent is up
src/core/bootstrap.ts     streams, verifies and caches the agent remotely
src/core/session.ts       multiplexing, requests, keepalive, reconnection
src/core/transfer.ts      resume negotiation, block windows, verification
src/ui/                   tree, transfers view, terminal, status bar, fs provider

Licence

MIT.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft