A local-first bookmark API that automatically fetches metadata from URLs.
Built using agent-driven development - See AGENTS.md for the development workflow.
- 📌 Store links with auto-fetched titles and descriptions
- 🏷️ Tag-based organization
- 🔍 Search and filter
- 🖥️ CLI + REST API
- 💾 Local SQLite database (no cloud dependency)
# Setup (creates venv, installs dependencies)
make setup
# Activate virtualenv
source venv/bin/activate
# Run tests
make test
# Start dev server
make devVisit http://localhost:8000/docs for interactive API documentation.
# Add a link
curl -X POST http://localhost:8000/links \
-H "Content-Type: application/json" \
-d '{"url": "https://fastapi.tiangolo.com", "tags": ["dev", "python"]}'
# Response:
# {
# "id": 1,
# "url": "https://fastapi.tiangolo.com/",
# "title": "FastAPI",
# "description": "FastAPI framework, high performance, easy to learn...",
# "tags": ["dev", "python"],
# "created_at": "2026-02-06T11:00:00"
# }
# List links
curl http://localhost:8000/links
# List with filters
curl http://localhost:8000/links?tags=python&limit=10
# Search by title or description
curl http://localhost:8000/links?search=fastapi
# Get single link
curl http://localhost:8000/links/1
# Health check
curl http://localhost:8000/health# Activate virtualenv first
source venv/bin/activate
# Add a link
python -m app.cli add https://fastapi.tiangolo.com --tags dev,python
# List links
python -m app.cli list
# List with tag filter
python -m app.cli list --tags python
# Search by title or description
python -m app.cli search "fastapi"
# Show full details for a link
python -m app.cli show 1
# Get help
python -m app.cli --helpThis project follows the "Agent Captain" workflow (see AGENTS.md):
- Read AGENTS.md first
- Make small, tested changes
- Run
make testafter every change - Keep diffs minimal and readable
make setup # Install dependencies
make dev # Run dev server
make test # Run tests
make lint # Check code quality
make fmt # Auto-format code
make clean # Remove generated files- FastAPI - Modern Python web framework
- SQLite - Embedded database
- BeautifulSoup4 - HTML parsing for metadata
- Pytest - Testing framework
linkvault/
├── AGENTS.md # Agent development guide
├── README.md # This file
├── Makefile # Golden commands
├── requirements.txt # Python dependencies
├── app/ # Application code
│ ├── main.py # FastAPI app
│ ├── models.py # Database models
│ ├── database.py # DB setup
│ ├── scraper.py # Metadata fetching
│ └── cli.py # CLI interface
└── tests/ # Test suite
├── test_api.py
├── test_scraper.py
└── test_cli.py
Problem: "database is locked" errors
Solution: Close any other processes accessing linkvault.db
Problem: Tests fail with database errors
Solution: Run make clean to remove old database files
Problem: Some sites don't return metadata
Solution: This is normal - some sites block scrapers or don't have meta tags. The link will still be saved with null title/description.
Problem: Timeout errors
Solution: Default timeout is 10s. Some sites are slow. The link won't be saved on timeout.
- URL: Max 2048 characters
- Title: Max 500 characters (auto-truncated)
- Description: Max 2000 characters (auto-truncated)
- Tags: Max 20 tags, 50 chars each
These limits prevent memory issues and DoS attacks.
MIT
This is a learning project demonstrating agent-driven development. PRs welcome!
See AGENTS.md for development guidelines.