局域网语音输入中转工具 - 本地传送门
Project description
Local Portal (lportal)
📖 中文文档
A real-time LAN text relay tool —— the Local Portal
Features
- Phone Input → PC Clipboard Sync: Type on your phone, and the content instantly appears on your computer clipboard
- File Transfer: Send images and videos from your phone directly to your computer's download folder
- Copy Mode Switching: Supports cover mode (default) and append mode; multiple messages are automatically merged in append mode
- Text Beautification: Use LLM to convert colloquial input into structured documents, with streaming output and reasoning chain display
- Multi-Device Isolation: Each device registers independently with isolated sessions; messages and history are completely separated
- Device Session Mode: The server can establish dedicated sessions with specific devices for bidirectional messaging
- Pure Browser Solution: No app installation required on the phone; just open the browser and go
- Interactive CLI: The computer side provides a CLI terminal with slash command support
- Pairing Code Security: 4-digit numeric pairing code prevents unauthorized access
Use Cases:
- Quickly send URLs, verification codes, or long text to your computer
- Transfer photos and videos directly from your phone to your computer
- Temporary note and to-do transmission
- Type on your phone, paste on your computer
- Convert voice input into professionally structured documents with one click
- Multiple devices connected simultaneously with completely isolated data
- Server actively pushes messages and notifications to specified devices
Installation
Recommended: Install from PyPI
pip install localportal
Then run:
lportal
Alternative: Global Install with uv
If you use uv, you can also install globally as a tool:
uv tool install localportal
uv tool installs the package into an isolated environment (e.g. %APPDATA%\uv\tools\lportal\ on Windows, ~/.local/share/uv/tools/lportal/ on Linux/macOS) and creates an executable in your user's script directory, so it won't pollute your system Python.
Upgrade / Uninstall:
uv tool upgrade localportal # upgrade
uv tool uninstall localportal # uninstall
Development
If you want to run from source or contribute:
With uv:
uv sync # install dependencies
uv run lportal # run
With pip (editable):
# Create virtual environment (recommended)
python -m venv .venv
# Activate virtual environment
# Windows:
.venv\Scripts\activate
# Linux/Mac:
source .venv/bin/activate
# Install in editable mode
pip install -e .
# Run
lportal
Build & install a local wheel:
python -m build
pip install dist/localportal-*.whl
lportal
Usage
# Default start (port 14554)
lportal
# Specify port
lportal --port 8080
# Disable auto-copy
lportal --no-auto-copy
# Set max history entries
lportal --max-history 20
Set Download Directory
Files (images, videos) are saved to the system download directory (~/Downloads) by default. You can customize the download path via the LPORTAL_DOWNLOAD_DIR environment variable:
# Windows PowerShell
$env:LPORTAL_DOWNLOAD_DIR="D:\\MyDownloads"
lportal
# Windows CMD
set LPORTAL_DOWNLOAD_DIR=D:\\MyDownloads
lportal
# Linux / Mac
export LPORTAL_DOWNLOAD_DIR=/home/user/MyDownloads
lportal
LLM Configuration (Text Beautification)
The /beauty command requires an OpenAI-compatible API. Create a .env file in one of the following locations:
Option 1: User Config Directory (Recommended for global install users)
# Windows
mkdir "%APPDATA%\localportal"
echo OPENAI_BASE_URL=https://api.openai.com/v1 > "%APPDATA%\localportal\.env"
echo OPENAI_API_KEY=sk-xxxxxx >> "%APPDATA%\localportal\.env"
echo OPENAI_MODEL=gpt-4o-mini >> "%APPDATA%\localportal\.env"
# macOS
mkdir -p ~/Library/Application\ Support/localportal
cat > ~/Library/Application\ Support/localportal/.env << EOF
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY=sk-xxxxxx
OPENAI_MODEL=gpt-4o-mini
EOF
# Linux
mkdir -p ~/.config/localportal
cat > ~/.config/localportal/.env << EOF
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY=sk-xxxxxx
OPENAI_MODEL=gpt-4o-mini
EOF
Option 2: Current Working Directory (Good for development & debugging)
Create a .env file in the project directory or any working directory:
OPENAI_BASE_URL=https://api.openai.com/v1/chat/completions
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
OPENAI_MODEL=gpt-4o-mini
Note: The .env in the current working directory takes precedence over the user config directory.
The system prompt is located at src/prompt/text-beauty.md; feel free to modify it as needed.
Device Registration
The mobile side must pass two verification steps after connecting:
- Pairing Code Verification: Enter the 4-digit pairing code displayed on the computer
- Device Registration: Enter a device name (must be unique among currently online devices). After successful registration, a unique
login_idis assigned
- When the same device reconnects, as long as the server has not restarted, the
login_idremains unchanged and history can be restored - Use the
/devicescommand to view all online devices
Pairing Code Security
A 4-digit pairing code is generated on startup; the mobile side must enter the correct code to connect.
- Scan to connect: Use the
/qrcommand to display a QR code; scanning it auto-fills the pairing code - Manual connect: Open the browser address and enter the pairing code
- Refresh pairing code: Use
/refresh-qrcode(/rq) to generate a new pairing code; old connections will be disconnected - Switch copy mode: Use
/mode [cover|add]to switch between cover and append modes; changes are synchronized to all online devices - Refresh session: In append mode, use
/new-sessionto start a new session - Text beautification: Use
/beauty [N]to structure and polish the Nth history message via LLM
Commands
| Command | Description |
|---|---|
/auto [on|off] |
Toggle auto-copy mode |
/copy [N] |
Copy history message (N=1-10, no arg = most recent) |
/list (/ls) |
List history messages |
/status |
Show service status (including pairing code) |
/open |
Open the main page in browser |
/qrcode (/qr) |
Display ASCII QR code (scan to connect) |
/downloads |
Open download folder |
/refresh-qrcode (/rq) |
Refresh pairing code (disconnects all connections) |
/mode [cover|add] |
Switch copy mode: cover = overwrite, add = append |
/new-session |
Refresh session in append mode (clear buffer) |
/beauty [N] |
Beautify the Nth history message via LLM (default: most recent) |
/beauty-history |
View the last 10 text beautification tasks |
/beauty-copy [N] |
Copy the Nth beautification result (default: most recent) |
/devices |
View all logged-in devices (name, login_id, login time) |
/link <name|id> |
Enter session mode with a specific device; prompt becomes lportal[device]> |
/unlink |
Exit device session mode |
/send <filepath> |
Send a file to the current session device (use after /link) |
/help |
Show help |
/exit |
Exit the program |
Device Session Mode
After entering session mode, you can directly type text to send to the device without slash commands. You can also use /send to transfer files:
lportal> /link iPhone
[OK] Entered device session mode: iPhone (a3f9b2c1)
lportal[iPhone]> Hello, this is a server message
[11:30:15] -> iPhone: Hello, this is a server message...
lportal[iPhone]> /send C:\Users\xx\Documents\file.pdf
[OK] File sent to iPhone: file.pdf (123.4KB)
lportal[iPhone]> /unlink
[OK] Exited session mode with iPhone
Tech Stack
- Python 3.9+
- aiohttp (HTTP/WebSocket)
- typer (CLI)
- prompt_toolkit (Interactive terminal)
- rich (Terminal styling)
- pyperclip (Clipboard)
TODO
- Image transfer support
- Video transfer support
- Copy mode switching (cover / add)
- Session management (grouped display in append mode)
- Message persistent storage
- Multi-device online management
- Encrypted transmission support
- Web dark / light theme switching
License
MIT
Project details
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 localportal-0.2.0.tar.gz.
File metadata
- Download URL: localportal-0.2.0.tar.gz
- Upload date:
- Size: 57.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dd6c4c5687f3f10cd96ad23c15c4ec84aa579d08159dd0264b818b80d6bb4b6
|
|
| MD5 |
498c9794424c7d40f3cfb244c616fae2
|
|
| BLAKE2b-256 |
32a13bd65232fc29b08169e9408e8b94569882c3e42b4ba5f59400f97d868022
|
File details
Details for the file localportal-0.2.0-py3-none-any.whl.
File metadata
- Download URL: localportal-0.2.0-py3-none-any.whl
- Upload date:
- Size: 55.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df1145e7e6a1ff9d6f739e9399c790aae6d067061d5a2e63dcf37512ad469e65
|
|
| MD5 |
bd349082363ff031e5a801e0f51735c1
|
|
| BLAKE2b-256 |
12bdb6585d7124d6162581b9fac2c506535ba2b2c39d6eb1126a2ead25b6d0ef
|