LinkCovery is a modern, fast, and intuitive bookmark management tool built with Python. It provides a beautiful command-line interface that makes managing, searching, and organizing your links effortless.
Browser bookmarks quickly become cluttered and inefficient. LinkCovery helps you intelligently manage and organize your links from the terminal—the place where you, as a developer, spend most of your time. With powerful search capabilities, tagging systems, and data portability, LinkCovery transforms how you interact with your saved links, making them truly useful rather than just saved.
- Smart Link Management: Add, edit, delete, and organize links with ease
- Powerful Search: Search by URL, description, tags, domain, or read status
- Data Portability: Import and export your bookmarks in JSON, HTML, or TXT format
- Read Tracking: Keep track of which links you've read
- Rich Statistics: Get insights into your bookmark collection
- Web UI: Lightweight FastAPI interface for CRUD and previews
- Modern Architecture: Clean separation of concerns with service layers
- Type Safety: Full Pydantic validation and type hints throughout
- Error Handling: Comprehensive error handling with helpful messages
- Beautiful UI: Rich terminal interface with tables and colors
- Configuration: Flexible configuration system with file-based storage
- Cross-Platform: Works seamlessly on macOS, Linux, and Windows
- Python 3.13 or higher
- uv package manager (recommended)
git clone https://github.com/arian24b/linkcovery.git
cd linkcovery
uv syncuv add linkcoveryAfter installation, you can use the linkcovery command directly:
uv run linkcovery add "https://github.com/arian24b/linkcovery" \
--desc "LinkCovery GitHub Repository" \
--tag "github,project"uv run linkcovery listuv run linkcovery webuiuv run linkcovery webui --background# Search by keyword
uv run linkcovery search github
# Search by domain
uv run linkcovery search --domain github.com
# Search by tag
uv run linkcovery search --tag projectuv run linkcovery export my-bookmarks.jsonuv run linkcovery import my-bookmarks.jsonadd <url>- Add a new bookmark--desc, -d- Description for the link--tag, -t- Tag to categorize the link (can be used multiple times)--read, -r- Mark as already read--interactive, -i- Interactive mode with prompts
list- List all bookmarks--limit, -l- Maximum number of links to show--full- Show full descriptions--read-only- Show only read links--unread-only- Show only unread links
search [query]- Search bookmarks--domain- Filter by domain--tag, -t- Filter by tag--read-only- Show only read links--unread-only- Show only unread links--limit, -l- Maximum results--interactive, -i- Interactive selection mode
show <id>- Show detailed link informationedit <id>- Edit an existing link--url- New URL--desc, -d- New description--tag, -t- New tags--read- Mark as read--unread- Mark as unread--interactive, -i- Interactive mode with prompts
delete <id>- Delete a link--force, -f- Skip confirmation
mark <id>- Mark links as read or unread--read- Force read--unread- Force unread- (If neither specified, toggles current status)
open <id>- Open links in web browsernormalize <id>- Normalize link URLs--all, -a- Normalize all links
read-random- Read random links from bookmarks
ls- Alias forlistfind- Alias forsearchnew- Alias foraddrm- Alias fordelete
export <file>- Export links to JSON--force, -f- Overwrite existing file
import <file>- Import links from JSON, HTML, or TXT
config show- Show current configurationconfig get <key>- Get a specific configuration valueconfig set <key> <value>- Set a configuration valueconfig edit- Open config file in default editorconfig validate- Validate configurationconfig reset- Reset to default configuration
stats- Show bookmark statisticspaths- Show all LinkCovery file pathsversion- Show version information
LinkCovery stores its configuration in your system's config directory:
- macOS:
~/Library/Application Support/linkcovery/config.json - Linux:
~/.config/linkcovery/config.json - Windows:
%APPDATA%/linkcovery/config.json
| Setting | Default | Description |
|---|---|---|
app_name |
"LinkCovery" | Application name |
version |
"1.0.0" | Application version |
database_path |
(auto-detected) | Custom database path |
default_export_format |
"json" | Default export format |
max_search_results |
50 | Maximum search results |
allowed_extensions |
[".json"] | Allowed file extensions |
debug |
false | Enable debug mode |
# Set maximum search results
uv run linkcovery config set max_search_results 100
# Enable debug mode
uv run linkcovery config set debug true
# View all settings
uv run linkcovery config showLinkCovery uses SQLite for data storage. The database is automatically created in your system's data directory:
- macOS:
~/Library/Application Support/linkcovery/links.db - Linux:
~/.local/share/linkcovery/links.db - Windows:
%APPDATA%/linkcovery/links.db
The links table contains:
id- Unique identifier (primary key)url- The bookmark URL (unique, required)domain- Extracted domain name (required)description- Optional description texttag- Associated tag for categorizationis_read- Boolean read statuscreated_at- ISO timestamp of creationupdated_at- ISO timestamp of last update
linkcovery/
├── main.py # Application entry point
├── linkcovery/
│ ├── cli/ # Command-line interface
│ │ ├── __init__.py # Main CLI app and routing
│ │ ├── links.py # Link management commands
│ │ ├── config.py # Configuration commands
│ │ ├── data.py # Import/export commands
│ │ └── utils.py # CLI utilities and decorators
│ ├── core/ # Core business logic
│ │ ├── config.py # Configuration management
│ │ ├── database.py # Database service layer
│ │ ├── exceptions.py # Custom exception classes
│ │ ├── models.py # Pydantic and SQLAlchemy models
│ │ └── utils.py # Core utility functions
│ └── services/ # Business logic services
│ ├── link_service.py # Link management business logic
│ └── data_service.py # Import/export operations
├── pyproject.toml # Project configuration
└── README.md # This file
# Clone the repository
git clone https://github.com/arian24b/linkcovery.git
cd linkcovery
# Install with development dependencies
uv sync --all-groups
# Install pre-commit hooks (if available)
uv run pre-commit install# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=linkcovery --cov-report=html# Run linting
uv run ruff check
# Format code
uv run ruff format
# Type checking
uv run mypy linkcovery# Build binary
uv run python build_binary.py# Add a link with description and tags
uv run linkcovery add "https://docs.python.org" \
--desc "Official Python Documentation" \
--tag "python,docs,reference"
# List only unread links
uv run linkcovery list --unread-only --limit 10
# Search for Python-related links
uv run linkcovery search python
# Mark a link as read
uv run linkcovery mark 5
# Mark a link as unread
uv run linkcovery mark 5 --unread
# Edit a link's description
uv run linkcovery edit 5 --desc "Updated description"# Export all links
uv run linkcovery export my-bookmarks-$(date +%Y%m%d).json
# Import from another file
uv run linkcovery import bookmarks-backup.json
# Import from text (one link per line)
uv run linkcovery import links.txt
# View statistics
uv run linkcovery statsThe web UI is a lightweight FastAPI interface for CRUD, previews, and file import/export.
uv run linkcovery webui --host 0.0.0.0 --port 8080
uv run linkcovery webui --background- CRUD for links with quick edit and delete
- Import (JSON/HTML/TXT) and export (JSON)
- Lazy loading + infinite scroll
- Layout toggle (square vs. standard cards)
- Preview images cached locally for speed
LinkCovery uses platformdirs for cache and log storage:
- Cache (preview images):
user_cache_dir("linkcovery")/previews - Logs (web UI):
user_log_dir("linkcovery")/webui.log
# Increase search result limit
uv run linkcovery config set max_search_results 100
# View current configuration
uv run linkcovery config show
# Edit configuration file
uv run linkcovery config edit
# View all paths
uv run linkcovery paths
# Reset to defaults
uv run linkcovery config resetContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes following the project's coding standards
- Run tests and linting (
uv run pytest && uv run ruff check) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Typer for the CLI framework
- Rich for beautiful terminal output
- SQLAlchemy for database operations
- Pydantic for data validation and settings
- platformdirs for cross-platform paths
LinkCovery - Because your bookmarks deserve better organization! 🔗✨
