A minimal bidirectional SCP server for network automation
Project description
TinySCP
A minimal, embeddable SCP server for network automation workflows.
Why TinySCP?
There are plenty of SCP clients for Python, but no lightweight SCP server. TinySCP fills that gap—a simple, drop-in SCP server you can embed in your automation workflows or run standalone for:
- Firmware staging — Network devices push/pull images
- Config distribution — Centralized config server for network gear
- File collection — Devices upload logs, captures, or backups
- Lab environments — Quick file server without spinning up full SSH infrastructure
Installation
pip install tinyscp
For YAML config file support:
pip install tinyscp[yaml]
Quick Start
CLI Usage
# Generate a config file
tinyscp --init-config config.yaml
# Edit config.yaml to set your users, then run:
tinyscp
# Or run without config file:
tinyscp --no-config -u admin:secret -p 2222
Development Mode
If running from source without installing:
# Clone and setup
git clone https://github.com/scottpeterman/tinyscp.git
cd tinyscp
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
pip install -e ".[yaml]"
# Run via module
python -m tinyscp.cli --help
python -m tinyscp.cli --init-config config.yaml
python -m tinyscp.cli -d
Client Usage
Modern macOS/Linux defaults to SFTP mode for scp. Use -O to force legacy SCP protocol:
# Upload to server
scp -O -P 2222 firmware.bin admin@server:/uploads/
# Download from server
scp -O -P 2222 admin@server:/downloads/startup-config.txt ./
Python API
from tinyscp import TinySCPServer
# Basic usage
server = TinySCPServer(
port=2222,
users={'admin': 'secret'},
upload_dir='./uploads',
download_dir='./downloads'
)
server.start()
# With callbacks for post-transfer actions
def on_upload(filepath, size, filename):
print(f"Received {filename}, verifying checksum...")
# Validate firmware, trigger deployment, etc.
server = TinySCPServer(
port=2222,
users={'admin': 'secret'},
on_upload_complete=on_upload
)
server.start()
# Non-blocking mode
server.start(blocking=False)
# ... do other things ...
server.stop()
Configuration
Config File (YAML)
host: 0.0.0.0
port: 2222
host_key: ./tinyscp_host_key
upload_dir: ./uploads
download_dir: ./downloads
users:
admin: changeme
neteng: firmware123
backup_svc: b4ckup!
CLI Options
usage: tinyscp [-h] [-d] [-p PORT] [-H HOST] [-c CONFIG] [--no-config]
[--init-config FILE] [-u USER:PASS] [--upload-dir DIR]
[--download-dir DIR] [--host-key FILE] [-v]
Options:
-d, --debug Enable debug output
-p, --port PORT Port to listen on (default: 2222)
-H, --host HOST Host to bind to (default: 0.0.0.0)
-c, --config FILE Path to YAML config file (default: config.yaml)
--no-config Ignore config file, use CLI args only
--init-config FILE Generate a default config file and exit
-u, --user USER:PASS Add user credentials (can be repeated)
--upload-dir DIR Directory for uploads (default: ./uploads)
--download-dir DIR Directory for downloads (default: ./downloads)
--host-key FILE Path to host key file
-v, --version Show version and exit
Features
- Bidirectional transfers — Both upload (sink) and download (source) modes
- Persistent host keys — No more "host key changed" warnings on restart
- YAML configuration — Simple config file for users and settings
- Callback hooks — Trigger actions on upload/download completion
- Path traversal protection — Filenames are sanitized
- Concurrent connections — Threaded client handling
- Embeddable — Use as a library in your own applications
- No dependencies — Just Paramiko (PyYAML optional for config files)
Security Considerations
TinySCP is designed for trusted network environments (labs, internal infrastructure, automation pipelines). It is not intended as a public-facing service.
- Passwords are stored in plain text in config files
- No rate limiting or brute-force protection
- No chroot/jail for uploaded files (though path traversal is blocked)
For production use, consider:
- Running behind a firewall
- Using SSH key authentication (PR welcome!)
- Restricting to specific source IPs
Contributing
Contributions welcome! Areas of interest:
- SSH key authentication
- SFTP subsystem support
- Transfer progress callbacks
- Recursive directory transfers
- Upload size limits / quotas
License
MIT License - See LICENSE for details.
Author
Scott Peterman (@scottpeterman)
Part of the network automation toolkit alongside:
- Secure Cartography — Network discovery and mapping
- UglyPTY — SSH terminal with session management
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tinyscp-0.1.0.tar.gz.
File metadata
- Download URL: tinyscp-0.1.0.tar.gz
- Upload date:
- Size: 13.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
883d690a7dcf4c940cbe84537d0bb2828586b5406c2e72a5b5dbe3d151255ce5
|
|
| MD5 |
9ef78ac682f226d06e4b72c986292204
|
|
| BLAKE2b-256 |
ba3bfdd3b1463c7fc3fdb17579f7b6c5cc4972a415713221faabff5f5242de78
|
File details
Details for the file tinyscp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tinyscp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02578e8245367c9f93ae9eb129e24b1e7d27c70ff7b965cd2c9f89c57ecc48ef
|
|
| MD5 |
b2dde1481abaa7b7a3ca6cd42174489e
|
|
| BLAKE2b-256 |
44206df2d5126d66540a319e7d0b8251d389fade14f687717c2bb08568690879
|