links.sh
A CLI tool for managing bookmarks as plain Markdown files, with an optional HTTP server for syncing across machines.
Links are stored in one .md file per topic:
- [Go Spec](https://go.dev/ref/spec) — 2026-03-05
Reference for language semantics
- [Effective Go](https://go.dev/doc/effective_go) — 2026-03-05
Quick Start
Requirements
Install
go install code.as/matt/links.sh@latest
Or build from source:
git clone https://code.as/matt/links.sh
cd links.sh
go build
Create ~/.config/links.sh/links.toml:
# Directory where your .md topic files live
links_dir = "/home/you/Documents/links"
# Only needed for sync
server_url = "https://links.example.com"
token = "your-secret-token"
The links_dir defaults to ~/Documents/links if the config file is absent.
Shell completion
# bash — load for current session
source <(links.sh completion bash)
# bash — persist
links.sh completion bash > ~/.local/share/bash-completion/completions/links.sh
# zsh
links.sh completion zsh > "${fpath[1]}/_links.sh"
# fish
links.sh completion fish > ~/.config/fish/completions/links.sh.fish
Basic Commands
Add a link
# Fetches the page title automatically
links.sh add https://go.dev/doc/effective_go
# Specify a topic (default topic is "links")
links.sh add https://go.dev/doc/effective_go --topic go
# Add with a note
links.sh add https://go.dev/doc/effective_go --topic go --note "must re-read"
# Override the title
links.sh add https://go.dev/doc/effective_go --title "Effective Go" --topic go
List links
# All topics
links.sh list
# One topic
links.sh list go
Search
# Case-insensitive substring match across title, URL, and notes
links.sh search "effective"
Open in browser
# Opens the first matching link
links.sh open "effective go"
Show topics
links.sh topics
Server Setup
Run the server on your central machine (the links_dir it serves is the same format — plain .md files).
# Using the config file for links_dir and token
links.sh serve
# Override the listen address
links.sh serve --addr :8765
The server exposes three endpoints, all requiring Authorization: Bearer <token>:
| Method |
Path |
Description |
GET |
/topics |
List topic names |
GET |
/topics/{topic} |
Download a topic file |
PUT |
/topics/{topic} |
Upload/replace a topic file |
Run as a systemd service
# /etc/systemd/system/links.service
[Unit]
Description=links.sh sync server
[Service]
ExecStart=/usr/local/bin/links.sh serve --addr :8765
Restart=always
User=you
[Install]
WantedBy=multi-user.target
systemctl enable --now links
Sync
Sync pulls remote files that are newer than local, then pushes local files that are newer than remote (last-write-wins per file).
links.sh sync
Requires server_url and token in the config.
- [Title](url) — YYYY-MM-DD
Optional note (indented two spaces)
Files are plain Markdown — readable and editable by hand or any text editor.