{"id":32052476,"url":"https://github.com/timothepoznanski/poznote","last_synced_at":"2026-04-24T08:02:28.640Z","repository":{"id":307704580,"uuid":"1030432156","full_name":"timothepoznanski/poznote","owner":"timothepoznanski","description":"Poznote is a personal note-taking and documentation platform.","archived":false,"fork":false,"pushed_at":"2026-04-18T09:46:33.000Z","size":117865,"stargazers_count":567,"open_issues_count":0,"forks_count":22,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-18T11:44:17.216Z","etag":null,"topics":["documentation","free","note-taking","personal-wiki","self-hosted","todolist","webapp"],"latest_commit_sha":null,"homepage":"https://poznote.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timothepoznanski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"ko_fi":"timothepoznanski"}},"created_at":"2025-08-01T16:19:33.000Z","updated_at":"2026-04-18T09:46:22.000Z","dependencies_parsed_at":"2026-04-01T21:02:05.702Z","dependency_job_id":null,"html_url":"https://github.com/timothepoznanski/poznote","commit_stats":null,"previous_names":["timothepoznanski/poznote"],"tags_count":268,"template":false,"template_full_name":null,"purl":"pkg:github/timothepoznanski/poznote","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothepoznanski%2Fpoznote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothepoznanski%2Fpoznote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothepoznanski%2Fpoznote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothepoznanski%2Fpoznote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timothepoznanski","download_url":"https://codeload.github.com/timothepoznanski/poznote/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timothepoznanski%2Fpoznote/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32214420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T03:15:14.334Z","status":"ssl_error","status_checked_at":"2026-04-24T03:15:11.608Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentation","free","note-taking","personal-wiki","self-hosted","todolist","webapp"],"created_at":"2025-10-18T09:01:32.418Z","updated_at":"2026-04-24T08:02:28.598Z","avatar_url":"https://github.com/timothepoznanski.png","language":"JavaScript","funding_links":["https://ko-fi.com/timothepoznanski"],"categories":["JavaScript"],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/poznote.svg\" alt=\"Poznote Logo\" width=\"80\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003ePoznote\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![GitHub stars](https://img.shields.io/github/stars/timothepoznanski/poznote?style=flat\u0026logo=github)](https://github.com/timothepoznanski/poznote/stargazers) [![License](https://img.shields.io/github/license/timothepoznanski/poznote?style=flat)](https://github.com/timothepoznanski/poznote/blob/main/LICENCE) [![Docker GHCR](https://img.shields.io/badge/Docker-GHCR-2496ED?style=flat\u0026logo=docker\u0026logoColor=white)](https://github.com/timothepoznanski/poznote/pkgs/container/poznote)\n\n\u003c/div\u003e\n\n\u003ch3 align=\"center\"\u003e\nPoznote is a personal note-taking and documentation platform.\n\u003c/h3\u003e\nThis project started from a simple personal need: a practical way to write, organize, and synchronize my technical and personal notes. From the beginning, the priority has been simplicity and ease of use.\u003cbr\u003e\n\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://poznote.com/about.html\"\u003eLearn more about the project and its background on the Poznote About page\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/poznote-light.png\" alt=\"Poznote-light\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n### Features\n\nDiscover all the features [here](https://poznote.com/index.html#features).\nDetailed documentation of advanced features is available in [docs/FEATURES.md](docs/FEATURES.md).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/poznote-features.png\" alt=\"Poznote Features\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n## Table of content\n\n- [Install](#install)\n- [Access](#access)\n- [Change Settings](#change-settings)\n- [Update application](#update-application)\n- [Authentication](#authentication)\n- [Note types](#note-types)\n- [Personalization](#personalization)\n- [Multi-users](#multi-users)\n- [Git Synchronization](#git-synchronization)\n- [Backup / Export](#backup--export)\n- [Restore / Import](#restore--import)\n- [Public Sharing](#public-sharing)\n- [Admin Tools](#admin-tools)\n- [PWA](#pwa)\n- [Offline View](#offline-view)\n- [Multiple Instances](#multiple-instances)\n- [MCP Server](#mcp-server)\n- [Chrome Extension](#chrome-extension)\n- [API Documentation](#api-documentation)\n- [Tech Stack](#tech-stack)\n\n## Install\n\n\u003e The official image is multi-arch (linux/amd64, linux/arm64) and supports Windows/macOS via Docker Desktop, as well as ARM64 devices like Raspberry Pi, NAS systems etc.\n\nChoose your preferred installation method below:\n\n\u003ca id=\"windows\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🖥️ Windows\u003c/strong\u003e\u003c/summary\u003e\n\n#### Step 1: Prerequisite\n\nInstall and start [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)\n\n#### Step 2: Deploy Poznote\n\nCreate a new directory:\n\n```powershell\nmkdir poznote\n```\n\nNavigate to the Poznote directory:\n```powershell\ncd poznote\n```\n\nCreate the environment file:\n\n```powershell\ncurl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.template\n```\n\nEdit the `.env` file:\n\n```powershell\nnotepad .env\n```\n\nDownload the Docker Compose configuration file:\n\n```powershell\ncurl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.yml\n```\n\nDownload the latest Poznote Webserver and Poznote MCP images :\n```powershell\ndocker compose pull\n```\n\nStart Poznote containers:\n```powershell\ndocker compose up -d\n```\n\n\u003c/details\u003e\n\n\u003ca id=\"linux\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🐧 Linux\u003c/strong\u003e\u003c/summary\u003e\n\n#### Step 1: Prerequisite\n\n1. Install [Docker engine](https://docs.docker.com/engine/install/)\n2. Install [Docker Compose](https://docs.docker.com/compose/install/linux)\n\n#### Step 2: Install Poznote\n\nCreate a new directory:\n```bash\nmkdir poznote\n```\n\nNavigate to the Poznote directory:\n```bash\ncd poznote\n```\n\nCreate the environment file:\n```bash\ncurl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.template\n```\n\nEdit the `.env` file:\n```bash\nvi .env\n```\n\nDownload the Docker Compose configuration file:\n```bash\ncurl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.yml\n```\n\nDownload the latest Poznote Webserver and Poznote MCP images:\n```bash\ndocker compose pull\n```\n\nStart Poznote containers:\n```bash\ndocker compose up -d\n```\n\n\u003c/details\u003e\n\n\u003ca id=\"macos\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🍎 macOS\u003c/strong\u003e\u003c/summary\u003e\n\n#### Step 1: Prerequisite\n\nInstall and start [Docker Desktop](https://docs.docker.com/desktop/setup/install/mac-install/)\n\n#### Step 2: Deploy Poznote\n\nCreate a new directory:\n```bash\nmkdir poznote\n```\n\nNavigate to the Poznote directory:\n```bash\ncd poznote\n```\n\nDownload the environment file:\n```bash\ncurl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.template\n```\n\nEdit the `.env` file:\n```bash\nvi .env\n```\n\nDownload the Docker Compose configuration file:\n```bash\ncurl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.yml\n```\n\nDownload the latest Poznote Webserver and Poznote MCP images:\n```bash\ndocker compose pull\n```\n\nStart Poznote containers:\n```bash\ndocker compose up -d\n```\n\n\u003c/details\u003e\n\n\u003e If you encounter installation issues, see the [Troubleshooting Guide](docs/TROUBLESHOOTING.md).\n\n## Access\n\nAfter installation, access Poznote in your web browser:\n\n[http://localhost:8040](http://localhost:8040)\n\n\n- Username: `admin_change_me`\n- Password: `admin`\n- Port: `8040`\n\nRename the default administrator account and change the default password after the first login.\n\n## Change Settings\n\nMost day-to-day settings are changed from the Poznote interface. Use the `.env` file only for deployment/runtime values that are read when containers start.\n\nUse the `.env` file for:\n\n- `HTTP_WEB_PORT`\n- `POZNOTE_OIDC_CLIENT_ID`\n- `POZNOTE_OIDC_CLIENT_SECRET`\n- Optional runtime overrides such as `POZNOTE_MCP_PORT` and `POZNOTE_DEBUG`\n\nUse the UI for:\n\n- Admin/global settings such as OIDC provider settings, Git Sync enablement, import limits, and custom CSS upload\n- User/profile settings such as local account passwords, theme, font sizes, note sorting, workspace background, and hidden UI elements\n\nWith the default installation files, `.env.template` currently exposes `HTTP_WEB_PORT`, `POZNOTE_OIDC_CLIENT_ID`, and `POZNOTE_OIDC_CLIENT_SECRET`.\n\nIf a setting exists in the UI, use the UI as the source of truth. Some legacy environment fallbacks still exist internally for compatibility, but they are not the primary configuration workflow.\n\n### Modify System Settings (`.env`)\n\nNavigate to your Poznote directory:\n```bash\ncd poznote\n```\n\nStop the running Poznote containers:\n```bash\ndocker compose down\n```\n\nEdit your `.env` file with your preferred text editor (e.g., `nano .env` or `notepad .env`).\n\nSave the file and start the containers again to apply changes:\n```bash\ndocker compose up -d\n```\n\n## Update application\n\nIn most cases, updating Poznote is simple and does not require editing `.env`.\n\n### Simple update (default)\n\nUse this when the release notes do not mention changes to `.env`.\n\nNavigate to your Poznote directory:\n```bash\ncd poznote\n```\n\nDownload the latest Poznote Webserver and Poznote MCP images:\n```bash\ndocker compose pull\n```\n\nStart the updated containers:\n```bash\ndocker compose up -d\n```\n\n### If the release notes mention `.env` changes\n\nWhen a release explicitly asks you to update `.env`, refresh the reference files and compare them before restarting:\n\nNavigate to your Poznote directory:\n```bash\ncd poznote\n```\n\nStop the running containers before updating:\n```bash\ndocker compose down\n```\n\nDownload the latest Docker Compose configuration:\n```bash\ncurl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.yml\n```\n\nDownload the latest `.env.template`:\n```bash\ncurl -o .env.template https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.template\n```\n\nReview `.env.template` and add any new variables to your `.env` file if needed:\n```bash\nsdiff .env .env.template\n```\n\nDownload the latest Poznote Webserver and Poznote MCP images:\n```bash\ndocker compose pull\n```\n\nStart the updated containers:\n```bash\ndocker compose up -d\n```\n\nYour data is preserved in the `./data` directory and will not be affected by the update.\n\n## Authentication\n\nPoznote supports multiple authentication methods including local accounts and external identity providers.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eLocal Accounts Authentication\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nPoznote authenticates users against their profile using a username or email address and a password.\n\n\n#### Default account\n\nOn a fresh installation, Poznote creates one active administrator profile:\n\n- Username: `admin_change_me`\n- Password: `admin`\n\nChange the default password and rename the account after the first login.\n\n#### Password management\n\nPasswords are managed through the Poznote web interface, not through `.env`:\n\n- Users can change their own password from **Settings \u003e Change Password**.\n- Administrators can set a custom password for any user or reset it to the default from **Settings \u003e User Management**.\n- The **Remember me** option keeps the session for 30 days.\n- Changing a password invalidates existing remember-me cookies for that user.\n\n#### Default passwords\n\n- Administrator accounts: `admin`\n- Standard user accounts: `user`\n\nWhen a user has not yet changed their password, the default value above is used. Once a password is changed through the interface, a secure bcrypt hash is stored in the database and takes priority.\n\n\u003c/details\u003e\n\n\u003ca id=\"oidc\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eOIDC / SSO Authentication (Optional)\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nPoznote supports OpenID Connect (authorization code + PKCE) for single sign-on integration. This allows users to log in using external identity providers such as Auth0, Keycloak, Azure AD, or Google Identity.\n\n#### How it works\n\n1. The login page displays a `Continue with [Provider Name]` button when OIDC is enabled.\n2. Users authenticate with the OIDC authorization code flow secured by PKCE.\n3. Access can be restricted with allowed groups and, if needed, a legacy allowed users list.\n4. After authentication, Poznote links the identity in this order: `sub` (`oidc_subject`), then `preferred_username`, then `email`.\n5. If auto-create users is enabled and no profile matches, Poznote creates one automatically.\n6. If \"Disable normal login\" is enabled, the username/password form is hidden and the login page becomes SSO-only.\n\n#### Configuration\n\nOIDC is configured from the **admin UI**: go to **Settings \u003e Admin Tools \u003e OIDC / SSO**.\n\nAll settings (enabled, issuer, provider name, scopes, access control, login behavior, etc.) are managed from this page and stored in the database.\n\nOnly `POZNOTE_OIDC_CLIENT_ID` and `POZNOTE_OIDC_CLIENT_SECRET` remain in the `.env` file for security:\n\n```bash\nPOZNOTE_OIDC_CLIENT_ID=your_client_id\nPOZNOTE_OIDC_CLIENT_SECRET=your_client_secret\n```\n\n\u003e **Breaking change:** previous OIDC settings in `.env` are no longer read, except `POZNOTE_OIDC_CLIENT_ID` and `POZNOTE_OIDC_CLIENT_SECRET`. After upgrading, re-enter the other OIDC settings from the admin page.\n\n#### Access Control Example (Groups + Auto-Provision)\n\nFrom the OIDC admin page, configure:\n- **Groups claim:** `groups`\n- **Allowed groups:** `poznote`\n- **Auto-create users:** enabled\n\nIf auto-provisioning is enabled, Poznote generates a username from the OIDC claims (`preferred_username`, `nickname`, email local part, `name`, then `sub`) and stores the OIDC subject on the created profile.\n\n\u003c/details\u003e\n\n## Note types\n\nPoznote supports two primary note formats, each tailored for different workflows.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHTML Notes\u003c/strong\u003e\u003c/summary\u003e\n\u0026nbsp;\n\n*   **Editor:** Direct WYSIWYG (What You See Is What You Get) editing.\n*   **Storage:** Saved as `.html` files in the user data directory. Since they are standard HTML, they can be opened directly in any web browser.\n*   **Exclusive Features:**\n    *   **Excalidraw:** Integrated drawing board for hand-drawn diagrams and sketches.\n    *   **Rich Formatting:** Native support for text colors, highlighting, and standard HTML elements.\n    *   **Interactive UI:** Direct manipulation of elements in the editor.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMarkdown Notes\u003c/strong\u003e\u003c/summary\u003e\n\u0026nbsp;\n\n*   **Editor:** Markdown syntax editor with real-time preview.\n*   **Storage:** Saved as `.md` files in the user data directory.\n*   **Exclusive Features:**\n    *   **Mermaid Diagrams:\u003c/strong\u003e Native support for generating diagrams (flowcharts, sequence, etc.) via ` ```mermaid ` code blocks.\n    *   **Math Equations:** Robust LaTeX support for mathematical formulas using `$ inline $` and `$$ block $$` syntax.\n    *   **Portability:** Standard Markdown format compatible with any external editor or static site generator.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTask Lists\u003c/strong\u003e\u003c/summary\u003e\n\u0026nbsp;\n\n*   **Usage:** Manage tasks and projects with interactive checklists.\n*   **Workflow:** Track progress with checkboxes that can be toggled directly in the editor or the notes list.\n*   **Public Collaboration:** Task lists can be shared via a public URL. If edit permissions are granted, external collaborators can check items off the list without needing a Poznote account.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eShortcuts\u003c/strong\u003e\u003c/summary\u003e\n\u0026nbsp;\n\n*   **Functionality:** Create a reference to an existing note in another location.\n*   **Use Case:** Allows a note to be referenced in two different places simultaneously. For example, a note can live in a classification folder while its shortcut appears on a Kanban board for active tracking.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTemplates\u003c/strong\u003e\u003c/summary\u003e\n\u0026nbsp;\n\n*   **Functionality:** Create pre-filled notes to standardize your documentation.\n*   **Usage:** Notes marked as templates can be duplicated to create new notes with the same structure, tags, and content, saving time on repetitive tasks.\n\u003c/details\u003e\n\n## Personalization\n\nPoznote offers several built-in personalization options directly from the application, without requiring any configuration file changes.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDisplay Settings\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nUnder **Settings \u003e Display**, you can configure:\n\n- **Theme:** switch between light and dark mode\n- **Font size:** adjust text size for notes, sidebar, and code blocks\n- **Note sorting:** choose how notes are ordered in the list\n- **Task list insert order:** control where new tasks are inserted\n- **Show creation date:** toggle the creation date badge on notes\n- **Show folder note counts:** display the number of notes in each folder\n- **Show notes after folders:** list notes without folders below the folder list\n- **Index icon scaling:** resize icons in the note index\n- **Note content width:** control the max width of the note editor area\n- **Code block word wrap:** enable or disable word wrap in code blocks\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWorkspace Background Image\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nYou can set a background image per workspace — upload a custom image and adjust its opacity from the Display settings to give each workspace its own visual identity.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eElement Visibility\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nPoznote allows you to declutter the interface by hiding elements you don't use.\n\nConfigure it in **Settings \u003e Appearance \u003e UI Customization**.\n\n- **Granular Control:** Toggle visibility for home cards, toolbar actions, slash menu items, and more.\n- **Per-User:** Each user can have their own unique interface layout.\n- **Searchable:** Easily find the element you want to hide using the filter in the configuration modal.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCustom CSS Overrides\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nIf you want to adjust fonts, spacing, or other visual details beyond the built-in options, you can upload an extra stylesheet that is applied to every HTML page for all users.\n\nConfigure it in **Settings \u003e Appearance \u003e Custom CSS**.\n\nNotes:\n\n- Click **Upload CSS file** to select a `.css` file from your computer.\n- The file is uploaded and stored in `data/css/` (your Docker volume), so it survives image updates.\n- Click **Remove** to delete the file and disable the custom stylesheet.\n- Poznote appends a cache-busting `v=` parameter automatically.\n- The stylesheet is injected near the end of `\u003chead\u003e`, so it can override the default application styles.\n- Only administrators can upload or remove the custom CSS file.\n\n\u003c/details\u003e\n\n## Multi-users\n\nPoznote features a multi-user architecture with isolated data space for each user (ideal for families, teams, or personal personas).\n\n- **Data Isolation**: Each user has their own separate notes, workspaces, tags, folders and attachments.\n- **Hybrid Password Model**: Access uses per-profile credentials with custom passwords stored in the database. Until a password is changed in the UI, built-in defaults are used (`admin` for administrators, `user` for standard users).\n- **User Management**: Administrators can manage profiles via the Settings panel.\n\n\u003e ⚠️ **Warning:** It is not possible to share notes between users. Each user has their own isolated space. The only way to share notes or a profile is to share a common account.\n\n### Architecture \u0026 Structure\n\nPoznote uses a master database (`data/master.db`) to track profiles and global settings, and individual databases for each user.\n\n```\ndata/\n├── master.db                    # Master database (profiles, global settings)\n└── users/\n    ├── 1/                       # User ID 1 (default admin)\n    │   ├── database/poznote.db  # User's notes database\n    │   ├── entries/             # User's note files (HTML/MD)\n    │   └── attachments/         # User's attachments\n    ├── 2/                       # User ID 2\n    └── ...\n```\n\n## Git Synchronization\n\nPoznote supports automatic and manual synchronization with **GitHub** or **Forgejo**. Each user configures their own repository independently. There is no shared global repository.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow to configure Git Sync\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\n**Step 1 — Enable the feature (admin, in Settings \u003e Advanced Settings)**\n\nToggle **Git Sync** to enabled in the **Advanced Settings** section of the Settings page. This enables Git Sync globally and makes the user-level **Git Sync** card/configuration available from **Settings**.\n\n---\n\n**Step 2 — Each user configures their own repo (Settings \u003e Git Sync)**\n\n| Field | Description |\n|---|---|\n| Provider | `GitHub` or `Forgejo` |\n| API Base URL | GitHub: auto-filled (read-only). Forgejo: your instance URL, e.g. `https://forgejo.example.com/api/v1` |\n| Access Token | GitHub PAT (`ghp_...`) or Forgejo token (Settings \u003e Applications) |\n| Repository | `owner/repo` format |\n| Branch | Default: `main` |\n| Author Name / Email | Used for commit metadata |\n\n\u003e 🔒 Access tokens are encrypted at rest using AES-256-GCM. An encryption key is automatically generated and stored in `data/.app_secret`.\n\n---\n\n**Automatic sync**\n\nWhen enabled by the user, Poznote will automatically:\n- **Pull** on login\n- **Push** on every note create, update, or delete\n\nManual push/pull is also available from the **Dashboard** via the **Push** and **Pull** cards.\n\n\u003c/details\u003e\n\n## Backup / Export\n\nPoznote includes built-in Backup / Export functionality accessible through Settings.\n\n\u003ca id=\"complete-backup\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eComplete Backup to Poznote zip\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nSingle ZIP containing database, all notes, and attachments for all workspaces:\n\n  - Includes an `index.html` at the root for offline browsing\n  - Notes are organized by workspace and folder\n  - Attachments are accessible via clickable links\n\n#### Per-User vs Complete Backups\n\nPoznote provides flexible backup options:\n\n**Via Web Interface (Settings \u003e Backup/Export):**\n- **All users** can backup and restore their own profile\n- **Admins** can select which user profile to backup or restore\n- Backups contain the user's database, notes, and attachments\n\n**Via API/Script (Administrators only):**\n- Automated backups using the `backup-poznote.sh` script\n- Programmatic access via REST API v1\n- Requires admin credentials\n\n**Backup Scopes:**\n\n1. **Per-User Backups**: Created from Settings or via API. Contains *only* the data belonging to a specific user (their database, notes, and attachments).\n2. **Complete System Backup**: Created manually by backing up the entire `/data` directory. This is the only way to backup the master configuration and all users' data at once.\n\n```bash\n# Complete system backup via CLI\ntar -czvf poznote-full-backup.tar.gz data/\n```\n\n\u003c/details\u003e\n\n\u003ca id=\"export-individual-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eExport Individual Notes\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nExport individual notes using the **Export** button in the note toolbar:\n\n  - **HTML notes:** Export to HTML or PDF format\n  - **Markdown notes:** Export to HTML, Markdown or PDF format\n\n\u003c/details\u003e\n\n\u003ca id=\"automated-backups-with-bash-script\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAutomated Backups with Bash Script\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nFor automated scheduled backups via API, you can use the included `backup-poznote.sh` script.\n\n**IMPORTANT:** Only administrators can create backups via the API.\nUse the current password of the admin profile you authenticate with. On a fresh installation, that is the default admin password (`admin`) until it is changed in Poznote. Once a custom password is set, that custom password is required for API calls.\n\n**Script location:** `backup-poznote.sh` in the `tools` folder of the Poznote repository\n\n**Administrator Usage:**\n\nAdmins can backup any user profile - **no need to know user IDs**, just the username:\n\n```bash\n# Backup your own profile\nbash backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'admin' '/backups' '30'\n\n# Backup another user's profile (Nina)\nbash backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'Nina' '/backups' '30'\n```\n\n**Usage:**\n```bash\nbash backup-poznote.sh '\u003cpoznote_url\u003e' '\u003cadmin_username\u003e' '\u003cadmin_password\u003e' '\u003ctarget_username\u003e' '\u003cbackup_directory\u003e' '\u003cretention_count\u003e'\n```\n\n**Example with crontab (admin backing up Nina):**\n\n```bash\n# Add to crontab for automated backups twice daily\n0 0,12 * * * bash /root/backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'Nina' '/root/backups' '30'\n```\n\n**Parameters explained:**\n- `'https://poznote.example.com'` - Your Poznote instance URL\n- `'admin'` - Admin username for authentication (must be an admin)\n- `'admin_password'` - Current admin password for the API profile (default `admin` until changed, then the custom password)\n- `'Nina'` - Target username to backup\n- `'/root/backups'` - Parent directory where backups will be stored (creates `backups-poznote-\u003cusername\u003e` folder)\n- `'30'` - Number of backups to keep (older ones are automatically deleted)\n\n**How the backup process works:**\n\n1. The script authenticates with admin credentials\n2. Automatically looks up the user ID from the username\n3. Creates a backup via the API\n4. Calls the Poznote REST API v1 (`POST /api/v1/backups` with `X-User-ID` header)\n5. Downloads the backup ZIP locally to `backups-poznote-\u003cusername\u003e/`\n6. Automatically manages retention (keeps only the specified number of recent backups)\n\n**Note:** Each user's backups are stored in separate folders (`backups-poznote-Nina`, `backups-poznote-Tim`, etc.)\n\n\u003c/details\u003e\n\n\n## Restore / Import\n\nPoznote provides flexible restoration options through the web interface (**Settings \u003e Restore/Import**) or programmatically via the REST API for administrators. Users can restore their own profile data from a full ZIP backup or import individual files, while administrators can manage restorations across the entire system.\n\n\u003ca id=\"complete-restore\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eComplete Restore from Poznote zip backup\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nUpload the complete backup ZIP to restore everything:\n\n  - Replaces database, restores all notes, and attachments\n  - Works for all workspaces at once\n\n\u003c/details\u003e\n\n\u003ca id=\"import-individual-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImport Individual files\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nImport one or more HTML, Markdown or text notes directly:\n\n  - Support `.html`, `.md`, `.markdown` or `.txt` files types\n  - Up to 50 files can be selected at once, configurable in Settings \u003e Advanced Settings \u003e Import Limits\n\n\u003c/details\u003e\n\n\u003ca id=\"import-zip-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImport ZIP file\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nImport a ZIP archive containing multiple notes:\n\n  - Support `.html`, `.md`, `.markdown` or `.txt` files types\n  - ZIP archives can contain up to 300 files, configurable in Settings \u003e Advanced Settings \u003e Import Limits\n  - When importing a ZIP archive, Poznote automatically detects and recreates the folder structure\n\n\u003c/details\u003e\n\n\u003ca id=\"import-obsidian-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImport Obsidian Notes\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nImport a ZIP archive containing multiple notes from Obsidian:\n\n  - ZIP archives can contain up to 300 files, configurable in Settings \u003e Advanced Settings \u003e Import Limits\n  - Poznote automatically detects and recreates the folder structure\n  - Poznote automatically detects existing tags to create\n  - Poznote automatically imports images if they are at the zip file root\n\n\u003c/details\u003e\n\n\u003ca id=\"import-standard-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImport from Standard Notes\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nConvert and import your Standard Notes export to Poznote using the included conversion script:\n\n**Script location:** `standard-notes-to-poznote.sh` in the `tools` folder of the Poznote repository\n\n**Prerequisites:**\n- `jq`, `unzip`, `zip`, and `find` utilities must be installed\n\n**Usage:**\n```bash\nbash standard-notes-to-poznote.sh \u003cstandard_notes_export.zip\u003e\n```\n\n**How it works:**\n\n1. Export your notes from Standard Notes (this creates a ZIP file)\n2. Run the conversion script with your Standard Notes export ZIP as parameter\n3. The script generates a `poznote_export.zip` file compatible with Poznote\n4. Import the generated ZIP into Poznote using the \"Import ZIP file\" feature\n\n**What gets converted:**\n- All notes are converted to Markdown format with front matter\n- Note creation dates are preserved\n- Tags are automatically extracted and included in the front matter\n- Note content is preserved from the Standard Notes export\n\n**Example:**\n```bash\nbash tools/standard-notes-to-poznote.sh my_standard_notes_backup.zip\n# This creates: poznote_export.zip\n```\n\nAfter conversion, import the generated `poznote_export.zip` file into Poznote.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMarkdown Front Matter Support\u003c/strong\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nMarkdown files can include YAML front matter to specify note metadata. The following keys are supported:\n\n  - `title` — Override the note title (default: filename without extension)\n  - `folder` — Override the target folder selection (folder must exist in the workspace)\n  - `tags` — Array of tags to apply to the note. Supports both inline `[tag1, tag2]` and multi-line syntax\n  - `favorite` — Mark note as favorite (`true`/`false` or `1`/`0`)\n  - `created` — Set custom creation date (format: `YYYY-MM-DD HH:MM:SS`)\n  - `updated` — Set custom update date (format: `YYYY-MM-DD HH:MM:SS`)\n\nExample with inline array syntax:\n```yaml\n---\ntitle: My Important Note\nfolder: Projects\ntags: [important, work]\nfavorite: true\ncreated: 2024-01-15 10:30:00\nupdated: 2024-01-20 15:45:00\n---\n```\n\nExample with multi-line syntax:\n```yaml\n---\ntitle: My Important Note\nfolder: Projects\ntags:\n  - important\n  - work\nfavorite: true\ncreated: 2024-01-15 10:30:00\nupdated: 2024-01-20 15:45:00\n---\n```\n\n\u003c/details\u003e\n\n## Public Sharing\n\nPoznote allows you to share individual notes or entire folders with anyone. \n\n  - **Standard Notes:** Share in **Read-only** mode with anyone via a public link.\n  - **Task Lists:** Enhanced control with three permission levels: **Read-only**, **Just checkable** (allows checking items without full edit rights), or **Fully modifiable**.\n  - **Visibility:** Limit sharing to the public (anyone with the link) or restrict access to registered users of your Poznote instance.\n  - **Password Protection:** Secure your shared content by adding a mandatory password to the public URL for an extra layer of security.\n\n## Admin Tools\n\nAdministrators have access to a suite of maintenance and management tools under **Settings \u003e Admin Tools**:\n\n- **User Management:** Create, manage, and delete user profiles, or reset passwords.\n- **Git Sync Control:** Globally enable or disable Git synchronization features.\n- **Import Limits:** Configure the maximum number of files allowed for individual or ZIP imports.\n- **Custom CSS:** Upload a global custom stylesheet to override the application's appearance. The file is stored in your data volume (`data/css/`) and survives image updates.\n- **Rebuild Master Database:** Reconstruct the user index from data folders in case of system corruption or database loss.\n- **Base64 Image Converter:** Convert inline Base64 encoded images within notes to proper file attachments.\n- **Orphan attachments scanner:** Scan and clean up storage by identifying attachment files that are no longer referenced in any notes.\n\n## PWA\n\nPoznote can be installed as a **Progressive Web App (PWA)** in compatible browsers (Chrome, Edge, Safari on iOS, etc.).\n\n### Install on desktop\n\n1. Open your Poznote URL in the browser.\n2. Use the browser install action (for example **Install app** in the address bar/menu), or use the install button in **Settings** → **PWA Installation**.\n3. Launch Poznote from your applications list like a native app.\n\n### Install on mobile\n\n- **Android (Chrome/Edge):** open menu → **Install app** / **Add to Home screen**\n- **iPhone/iPad (Safari):** tap **Share** → **Add to Home Screen**\n\n### Offline behavior\n\nPoznote can be installed as a PWA, but this does not provide offline access to your notes content. For offline access to your notes, you must use the **Complete Backup** export feature (see section below).\n\n## Offline View\n\nThe **📦 Complete Backup** creates a standalone offline version of your notes. Simply extract the ZIP and open `index.html` in any web browser. This allows you to read your notes offline, but without the full Poznote functionality, it's a read-only export.\n\n## Multiple Instances\n\nYou can run multiple isolated Poznote instances on the same server. Each instance has its own data, port, and credentials.\n\nPerfect for:\n- Hosting for different users on the same server, each with their own separate instance and account\n- Testing new features without affecting your production instance\n\nSimply repeat the installation steps in different directories with different ports.\n\n### Example: Tom and Alice instances on the same server\n\n```\nServer: my-server.com\n├── Poznote-Tom\n│   ├── Port: 8040\n│   ├── URL: http://my-server.com:8040\n│   ├── Container: poznote-tom-webserver-1\n│   └── Data: ./poznote-tom/data/\n│\n└── Poznote-Alice\n  ├── Port: YOUR_POZNOTE_API_PORT\n  ├── URL: http://my-server.com:YOUR_POZNOTE_API_PORT\n    ├── Container: poznote-alice-webserver-1\n    └── Data: ./poznote-alice/data/\n```\n\n## MCP Server\n\nPoznote includes a Model Context Protocol (MCP) server that enables AI assistants like GitHub Copilot to interact with your notes using natural language. For example:\n\n- \"Create a new note titled 'Meeting Notes' with the content...\"\n- \"Search for notes about 'Docker'\"\n- \"List all notes in my Poznote workspace\"\n- \"Update note 42 with new information\"\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/mcp-poznote.gif\" alt=\"Poznote MCP Server demo\" width=\"100%\"\u003e\n\u003c/p\u003e\n\nFor setup and usage instructions, see the [MCP Server documentation](docs/MCP-SERVER.md).\n\nThe MCP server uses default settings (port `8045`, debug off). To override:\n\n```bash\nPOZNOTE_MCP_PORT=9000 POZNOTE_DEBUG=true docker compose up -d --force-recreate mcp-server\n```\n\nThese are container/runtime overrides, not Poznote UI settings. You can pass them inline as shown above or place them in `.env` before recreating the `mcp-server` container.\n\nOnly the exact lowercase values `true` and `false` are recognized for `POZNOTE_DEBUG`. After changing settings, recreate the container; a simple restart does not reload environment variables.\n\n## Chrome Extension\n\nThe **Poznote URL Saver** is a browser extension that allows you to quickly save the URL or even a full-page screenshot of the current page to your Poznote instance with a single click.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/chrome-extension.png\" alt=\"Poznote Chrome Extension\" width=\"50%\"\u003e\n\u003c/p\u003e\n\nInstall the extension directly from the Chrome Web Store → [Install extension](https://chromewebstore.google.com/detail/bmjclfamahegmgillaghhmnbkjebipbh?utm_source=item-share-cb)\n\n## API Documentation\n\nPoznote provides a comprehensive RESTful API v1 for programmatic access to notes, folders, workspaces, tags, attachments, backups, settings, and more.\n\nFor the complete API reference with all endpoints, parameters, and curl examples, see the **[REST API Documentation](docs/API-REST.md)**.\n\n### Quick Start\n\n```bash\n# List all notes for user ID 1\ncurl -u 'username:password' -H \"X-User-ID: 1\" \\\n  http://YOUR_SERVER/api/v1/notes\n\n# Create a note\ncurl -X POST -u 'username:password' -H \"X-User-ID: 1\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"heading\": \"My Note\", \"content\": \"Hello!\", \"type\": \"markdown\"}' \\\n  http://YOUR_SERVER/api/v1/notes\n```\n\n### Interactive Documentation (Swagger)\n\nAccess the **Swagger UI** directly from Poznote at `Settings \u003e API Documentation` to browse all endpoints, view request/response schemas, and test API calls interactively.\n\n## Tech Stack\n\nPoznote prioritizes simplicity and portability - no complex frameworks, no heavy dependencies. Just straightforward, reliable web technologies that ensure your notes remain accessible and under your control.\n\n**Privacy-First Architecture:** Poznote operates entirely locally with no external connections required for functionality. All libraries (Excalidraw, Mermaid, KaTeX) are bundled and served from your own instance. The only outbound connection is a daily update check.\n\n\u003cdetails\u003e\n\u003csummary\u003eIf you are interested in the tech stack on which Poznote is built, \u003cstrong\u003ehave a look here.\u003c/strong\u003e\u003c/summary\u003e\n\n### Backend\n- **PHP 8.x** - Server-side scripting language\n- **SQLite 3** - Lightweight, file-based relational database\n\n### Frontend\n- **HTML5** - Markup and structure\n- **CSS3** - Styling and responsive design\n- **JavaScript (Vanilla)** - Interactive features and dynamic content\n- **React + Vite** - Build toolchain for Excalidraw component (bundled as IIFE)\n- **AJAX** - Asynchronous data loading\n\n### Libraries\n- **Excalidraw** - Virtual whiteboard for sketching diagrams and drawings\n- **Mermaid** - Client-side JavaScript library for diagram and flowchart generation from text\n- **KaTeX** - Client-side JavaScript library for fast math typesetting and rendering mathematical equations\n- **Sortable.js** - JavaScript library for drag-and-drop sorting\n- **highlight.js** - Syntax highlighting for code blocks\n- **Swagger UI** - Interactive API documentation and testing interface\n\n### Storage\n- **HTML/Markdown files** - Notes are stored as plain HTML or Markdown files in the filesystem\n- **SQLite database** - Metadata, tags, relationships, and user data\n- **File attachments** - Stored directly in the filesystem\n\n### Infrastructure\n- **Nginx + PHP-FPM** - High-performance web server with FastCGI Process Manager\n- **Alpine Linux** - Secure, lightweight base image\n- **Docker** - Containerization for easy deployment and portability\n- **Python 3.12 (Alpine)** - MCP server runtime with httpx, uvicorn, fastmcp, and mcp libraries for AI assistant integration\n\u003c/details\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimothepoznanski%2Fpoznote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimothepoznanski%2Fpoznote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimothepoznanski%2Fpoznote/lists"}