Everything you want to come back to.
Your self-hosted personal library for the links, watchlists, wishlists, notes, and files worth remembering.
Marka is a self-hosted personal library for everything you want to remember or revisit, not just browser bookmarks. Keep the things that would otherwise be scattered across apps, tabs, and devices in one visual library you control.
Maybe it is a movie you want to watch, a product you might buy, a TikTok place or hotel, an Instagram career tip, an engineering article, a UI reference, or course material you will need again. Marka brings those saved things together so they do not become a pile of forgotten links.
Save links, notes, images, PDFs, and web pages in one library. Bring material in through the browser extension, RSS, CLI, API, and MCP tooling.
Marka can retain titles, descriptions, previews, screenshots, archived content, tags, highlights, and readable page content. Later, you can recognize why something mattered without reopening every source.
Browse visual cards, organize with lists, tags, rules, and sharing, then search across your saved material when you need it. Optional AI tagging and summaries can help you get the point before reading the whole thing again.
Run Marka on your own infrastructure and use the library through the web app and PWA. Your saved material stays in the setup you control.
Install Marka's agent skill, then configure the official CLI to access your instance:
npx skills add absolutepraya/marka
npm install --global @absolutepraya/marka
marka auth initCreate an API key in your Marka instance under Settings > API Keys. During
marka auth init, enter your instance address and key. The CLI stores the
key locally with file mode 0600; verify the connection with
marka whoami. Skill installation provides agent instructions only. See the
agent integration guide for
environment-based setup and the REST API option.
For a Linux amd64 host with Docker Engine, Docker Compose v2, and OpenSSL already installed:
curl -fsSLo /tmp/marka-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/marka-setup.shThe guided installer configures the application, search, browser rendering, and optional AI. It writes secrets to restricted env files, validates the generated Compose stack, and starts the deployment.
The default listener is 127.0.0.1:3000. For an Internet-facing deployment, put a reverse proxy with TLS in front of it. The installer does not install Docker, configure DNS, change firewall rules, or provision certificates.
For reproducible setup, replace main with a reviewed release tag or commit SHA:
REF=<tag-or-commit-sha>; curl -fsSLo /tmp/marka-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/marka-setup.shRead the guided installation guide for all configuration modes and rollback details.
Marka web and workers releases share an annotated vMAJOR.MINOR.PATCH Git tag.
The production Compose file and guided installer follow the paired stable
channel. Each release also keeps immutable version and source-commit image tags
so operators can roll back web and workers together.
After a successful CI run on main, the automatic release workflow classifies
the merged Conventional Commit messages. It creates the next annotated release
tag only for release-worthy changes, then the tag workflow publishes the paired
images and GitHub Release. Documentation-only and other explicitly non-release
changes do not create a version. Package manifest versions remain independent.
Start with CONTRIBUTING.md for contribution rules and docs/operator-setup.md for local development and deployment workflows.
The supported local development runtime is:
- Node.js 24.18.1 from
.nvmrc - pnpm 11.2.1 through Corepack, as pinned in
package.json - Git and a Docker-compatible runtime, such as OrbStack on macOS
wtfor isolated worktrees
After the repository is configured, the normal development command is:
pnpm dev:startpnpm dev:start runs the current worktree's web and workers processes. It reuses one machine-level Chrome/CDP service at 127.0.0.1:9250 and one Meilisearch service at 127.0.0.1:7700. Each worktree keeps its own SQLite/assets directory, web port, and Meilisearch index namespace. Worktree slot 1 uses web port 3100, slot 2 uses 3200, and so on. Shared Chrome can be moved with MARKA_DEV_CHROME_PORT when the default port is occupied.
The repository is supported by wt:
wt new ui-polish
wt lsThe project configuration in .wt/config.toml prepares isolated
dependencies, data, ports, and Meilisearch namespaces for each worktree. WT and T3
share lifecycle logic in scripts/dev-worktree.sh. WT
runs the project-root copy, while T3 runs the target worktree's copy so setup
tracks that worktree's checkout. Each tool keeps its own allocation rules.
T3 Code can import the project actions in t3.json through Project
settings. Its automatic Setup worktree action imports production state, prepares
the isolated environment, and starts the detached development server.
Use the safe dry run first:
pnpm prod:pull-state --dry-runThe command reads the root .env, connects to the personal VPS, and replaces the current worktree's local data only when run without --dry-run. It backs up the existing DATA_DIR before restoring the full production /data volume.
The personal VPS compose project is /home/praya/marka, configured through KARAKEEP_PROD_COMPOSE_DIR. The service and export image have documented defaults in the script, while machine-specific values belong in .env and must not be committed.
Open the editable Excalidraw source
Marka is licensed under AGPL-3.0.
Marka builds on the open-source Karakeep project.

