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
Metadata
Release files for tinyscp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tinyscp-0.1.0.tar.gz | 13.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tinyscp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.2 kB
Release files / tinyscp-0.1.0.tar.gz
| Download URL | tinyscp-0.1.0.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
883d690a7dcf4c940cbe84537d0bb2828586b5406c2e72a5b5dbe3d151255ce5
|
|
BLAKE2b-256 checksum How to use checksums |
ba3bfdd3b1463c7fc3fdb17579f7b6c5cc4972a415713221faabff5f5242de78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / tinyscp-0.1.0-py3-none-any.whl
| Download URL | tinyscp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02578e8245367c9f93ae9eb129e24b1e7d27c70ff7b965cd2c9f89c57ecc48ef
|
|
BLAKE2b-256 checksum How to use checksums |
44206df2d5126d66540a319e7d0b8251d389fade14f687717c2bb08568690879
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|