{"id":13771256,"url":"https://github.com/rschroll/rmfuse","last_synced_at":"2026-01-18T13:34:40.933Z","repository":{"id":45297939,"uuid":"336712904","full_name":"rschroll/rmfuse","owner":"rschroll","description":"FUSE access to the reMarkable Cloud","archived":false,"fork":false,"pushed_at":"2024-04-08T11:49:18.000Z","size":227,"stargazers_count":99,"open_issues_count":22,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-09-03T03:31:11.811Z","etag":null,"topics":["remarkable-tablet"],"latest_commit_sha":null,"homepage":"","language":"Python","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/rschroll.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2021-02-07T05:57:14.000Z","updated_at":"2025-08-01T13:33:13.000Z","dependencies_parsed_at":"2024-08-03T17:14:28.451Z","dependency_job_id":null,"html_url":"https://github.com/rschroll/rmfuse","commit_stats":{"total_commits":70,"total_committers":4,"mean_commits":17.5,"dds":0.09999999999999998,"last_synced_commit":"3796b8610c8a965a60a417fc0bf8ea5200b71fd2"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/rschroll/rmfuse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rschroll%2Frmfuse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rschroll%2Frmfuse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rschroll%2Frmfuse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rschroll%2Frmfuse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rschroll","download_url":"https://codeload.github.com/rschroll/rmfuse/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rschroll%2Frmfuse/sbom","scorecard":{"id":787031,"data":{"date":"2025-08-11","repo":{"name":"github.com/rschroll/rmfuse","commit":"3796b8610c8a965a60a417fc0bf8ea5200b71fd2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":1,"reason":"Found 2/19 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"33 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-vqfr-h8mv-ghfj","Warn: Project is vulnerable to: PYSEC-2024-60 / GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: GHSA-29gw-9793-fvw7","Warn: Project is vulnerable to: PYSEC-2022-12 / GHSA-pq7m-3gw7-gq5x","Warn: Project is vulnerable to: GHSA-55x5-fj6c-h6m8","Warn: Project is vulnerable to: PYSEC-2021-19 / GHSA-jq4v-f5q6-mjqq","Warn: Project is vulnerable to: PYSEC-2022-230 / GHSA-wrxv-2j5q-m38w","Warn: Project is vulnerable to: GHSA-3f63-hfp8-52jq","Warn: Project is vulnerable to: GHSA-3wvg-mj6g-m9cv","Warn: Project is vulnerable to: GHSA-44wm-f244-xhp3","Warn: Project is vulnerable to: GHSA-4fx9-vc88-q2xc","Warn: Project is vulnerable to: PYSEC-2021-331 / GHSA-7534-mm45-c74v","Warn: Project is vulnerable to: PYSEC-2021-137 / GHSA-77gc-v2xv-rvvh","Warn: Project is vulnerable to: PYSEC-2021-92 / GHSA-7r7m-5h27-29hp","Warn: Project is vulnerable to: PYSEC-2023-227 / GHSA-8ghj-p4vj-mr35","Warn: Project is vulnerable to: PYSEC-2022-10 / GHSA-8vj2-vxx3-667w","Warn: Project is vulnerable to: GHSA-95q3-8gr9-gm8w","Warn: Project is vulnerable to: PYSEC-2021-317 / GHSA-98vv-pw6r-q6q4","Warn: Project is vulnerable to: PYSEC-2022-168 / GHSA-9j59-75qj-795w","Warn: Project is vulnerable to: GHSA-f4w8-cv6p-x6r5","Warn: Project is vulnerable to: PYSEC-2021-139 / GHSA-g6rj-rv7j-xwp4","Warn: Project is vulnerable to: PYSEC-2021-94 / GHSA-hjfx-8p6c-g7gx","Warn: Project is vulnerable to: GHSA-j7hp-h8jx-5ppr","Warn: Project is vulnerable to: GHSA-jgpv-4h4c-xhw3","Warn: Project is vulnerable to: PYSEC-2022-42979 / GHSA-m2vv-5vj5-2hm7","Warn: Project is vulnerable to: GHSA-mvg9-xffr-p774","Warn: Project is vulnerable to: PYSEC-2022-8 / GHSA-pw3c-h7wp-cvhx","Warn: Project is vulnerable to: PYSEC-2021-93 / GHSA-q5hq-fp76-qmrc","Warn: Project is vulnerable to: PYSEC-2021-138 / GHSA-rwv7-3v45-hg29","Warn: Project is vulnerable to: PYSEC-2022-9 / GHSA-xrcv-f9gm-v42c","Warn: Project is vulnerable to: PYSEC-2023-175","Warn: Project is vulnerable to: PYSEC-2023-117 / GHSA-mrwq-x4v8-fh7p","Warn: Project is vulnerable to: GHSA-9q9m-c65c-37pq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T06:21:40.296Z","repository_id":45297939,"created_at":"2025-08-23T06:21:40.296Z","updated_at":"2025-08-23T06:21:40.296Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28536761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T13:04:05.990Z","status":"ssl_error","status_checked_at":"2026-01-18T13:01:44.092Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["remarkable-tablet"],"created_at":"2024-08-03T17:00:49.567Z","updated_at":"2026-01-18T13:34:40.889Z","avatar_url":"https://github.com/rschroll.png","language":"Python","funding_links":[],"categories":["Cloud Tools"],"sub_categories":["Launchers"],"readme":"# RMfuse\n\nRMfuse provides access to your reMarkable Cloud files in the form of a\n[FUSE](https://github.com/libfuse/libfuse) filesystem.  These files are\nexposed either in their original format, or as PDF files that contain\nyour annotations.  This lets you manage files in the reMarkable Cloud\nusing the same tools you use on your local system.\n\n## Installation\n\nRMfuse requires Python 3.7 or later.  It also requires either FUSE3 and\nthe [pyfuse3 library](https://github.com/libfuse/pyfuse3), or FUSE2 and\nthe [llfuse library](https://github.com/python-llfuse/python-llfuse).\nThese can be installed from pip with RMfuse, or installed separately\nvia your system package manager.  This means that there are three main\nways to get RMfuse installed.\n\n*Confused?  Look below to see examples for several OSes.*\n\n### Install with pyfuse3 through pip\n\nPrior to installing RMfuse, you will need to install FUSE3, along with\nits header files, which are probably in a package with a name something\nlike *libfuse3-devel*.  You will also need a C build system.  Once those\nare installed, you can install RMfuse with pip:\n```\npip install rmfuse[pyfuse3]\n```\nAlternatively, you may clone this repository and install with\n[Poetry](https://python-poetry.org/):\n```\npoetry install -E pyfuse3\n```\n\n### Install with llfuse through pip\n\nPrior to installing RMfuse, you will need to install FUSE, along with\nits header files, which are probably in a package with a name something\nlike *libfuse-devel*.  You will also need a C build system.  Once those\nare installed, you can install RMfuse with pip:\n```\npip install rmfuse[llfuse]\n```\nAlternatively, you may clone this repository and install with\n[Poetry](https://python-poetry.org/):\n```\npoetry install -E llfuse\n```\n\n### Install with system FUSE packages\n\nIf your system provides either pyfuse3 or llfuse in its package system,\nyou can install one of them that way.  You can then install RMfuse\nwithout needing to specify either library:\n```\npip install rmfuse\n```\nRMfuse will find whichever library is available at runtime.  (Note that\nif you are using a venv, you will need to create it with the\n`--system-site-packages` option.  Otherwise, RMfuse will not be able to\nsee the library you installed.)\n\n### Example installations\n\nHere are some instructions for installations known to succeed.  These are\nnot the only solutions, so feel free to go another direction.  But if\nyou're confused by all of the options, you might want to start here.\n\n#### Debian-based systems\n\nInstall the FUSE3 libraries and headers with apt:\n```\nsudo apt install fuse3 libfuse3-3 libfuse3-dev build-essential\n```\nThen install RMfuse in your chosen environment:\n```\npip install rmfuse[pyfuse3]\n```\nThis was tested on Ubuntu 20.04.\n\n#### Fedora-based systems\n\nInstall FUSE3 and pyfuse3 with dnf:\n```\nsudo dnf install fuse3-libs python3-fusepy fuse3-devel python3-devel\n```\nBe sure to add `~/.local/bin` to your path.  Then install with your\nsystem's pip:\n```\npip install rmfuse\n```\nThis was tested on Fedora 33.\n\n#### Arch-based systems\n\nInstall RMfuse from this AUR package:\n[rmfuse](https://aur.archlinux.org/packages/rmfuse/)\u003csup\u003eAUR\u003c/sup\u003e.\n\n[pyfuse3](https://aur.archlinux.org/packages/python-pyfuse3/)\u003csup\u003eAUR\u003c/sup\u003e and\n[llfuse](https://archlinux.org/packages/community/x86_64/python-llfuse/) are set\nas optional. Choose the one you prefer and install it.\n\nFor example\n```\nyay -S rmfuse python-pyfuse3\n```\n\n#### MacOS\n\nInstall [macFuse](https://osxfuse.github.io/) with brew:\n```\nbrew install macfuse pkg-config\n```\nYou will need to allow a kernel extension and reboot.  Then install\nRMfuse with the llfuse package:\n```\npip install rmfuse[llfuse]\n```\n\nThere is a [known bug](https://github.com/rschroll/rmfuse/issues/18) with writing\nlarge files to RMfuse on a Mac.\n\n#### Windows\n\nRMfuse can be run on Windows via the Windows Subsystem for Linux (WSL).\nCurrently only tested on Ubuntu 20.04 under WSL2. Follow the installation\ninstructions above for your Linux distribution, then launch RMfuse using the\n`--allow-other` flag. The mounted directory will be accessible via Windows\nexplorer. For performance reasons you should choose a mount point under the WSL\nfile system. Some issues have been observed when accessing large files.\n\n## Usage\n\nRMfuse installs the script `rmfuse`.  The script takes a single argument,\nthe path at which the filesystem should be mounted.  This must be an\nexisting directory.  Any files within that directory will be hidden as\nlong as RMfuse is mounted.\n```\nmkdir ~/remarkable\nrmfuse ~/remarkable\n```\n(If you installed with Poetry, you may need to run `poetry run rmfuse`.)\n\nThe first time RMfuse is run, it will need a _one-time code_ to get\naccess to your reMarkable Cloud account.  You will be prompted to get\nthat code from https://my.remarkable.com/connect/desktop, which may\nrequire logging in to your reMarkable account.  RMfuse uses that code\nto obtain tokens which it uses in the future to authenticate itself.\n\nNote that RMfuse will not produce any output by default.  (You can use\n`-v` or `-vv` to make it more talkative.)  It does not provide a user\ninterface to your files; instead you use another terminal or a file\nbrowser to access the mounted directory.\n\nTo unmount and halt RMfuse, use the `fusermount` command:\n```\nfusermount -u ~/remarkable\n```\n\n### Modes\n\nRMfuse offers several modes to display your reMarkable Cloud files.  You\ncan choose the mode with the `-m` option.\n\n`annot`: Displays all files in PDF format, with your annotations added.\nThis is the default mode.\n\n`orig`: Displays the original file for ebooks and PDF files.  Notebooks\nare rendered as PDF files, as in the `annot` mode.\n\n`raw`: Displays all files as ZIP files, reflecting the underlying format\nused by the reMarkable Cloud.  This may be useful when working with other\ntools that expect files in this form.\n\n`meta`: Displays metadata about the files in JSON format.  Only useful for\ndebugging.\n\nRMfuse provides a special file named `.mode` in root directory.  When read,\nthis file gives the current mode.  Writing a valid mode to this file will\nswitch the mode RMfuse is in.  Additionally, writing `refresh` to this file\nwill cause RMfuse to refresh its information from the reMarkable Cloud.\n(By default, this happens every five minutes.)\n```\n~/remarkable $ cat .mode\nannot\n~/remarkable $ ls\nbook.pdf        document.pdf    notebook.pdf\n~/remarkable $ echo orig \u003e .mode\n~/remarkable $ ls\nbook.epub       document.pdf    notebook.pdf\n```\n\n### Capabilities\n\nRMfuse allows reading of all files in the reMarkable Cloud.  Since reading\nthe file requires several HTTP requests, as well as local processing, reads\nmake take some time.  Running RMfuse in verbose mode (`-v` or `-vv`) will\ndisplay information about the actions underway.  Open files are cached, to\nimprove performance.  More sophisticated caching is planned for the future.\n\nRMfuse does its best to provide accurate metadata for the files.  However,\nthe reMarkable Cloud provides only modification dates, so that is reported\nfor creation and access dates as well.  File sizes in `annot` mode are\nonly estimates until the file is read for the first time.  This metadata\nis cached locally to improve responsiveness in the future.\n\nFiles can be renamed and moved within the RMfuse filesystem.  These changes\nwill be propagated to the reMarkable Cloud.  Changes to the file extension\nwill be ignored.\n\nDeleting files from a RMfuse filesystem moves them into the reMarkable\nCloud's trash area.  These files are accessible in the `.trash` hidden\ndirectory in the root of the file system.  Deleting files within the\n`.trash` folder removes them from the reMarkable Cloud.  (_N.B._ It is\nnot known if this deletes the files from the cloud, or just hides them\nfrom clients.)\n\nEPUB and PDF files may be copied into the filesystem, and new directories\ncan be created.  These changes are uploaded to the reMarkable Cloud.\nCopying other types of files into the RMfuse filesystem will fail silently\n(unfortunately).  File extensions are ignored by RMfuse, and thus may\nchange when files are uploaded.  For instance, if `book.epub` is uploaded\nand RMFuse is in `annot` mode, it will show up in the filesystem as\n`book.pdf`.\n\nExisting files cannot be edited; they appear in read-only mode. If you\nwant to edit the contents of a file, you will need to copy it to your\nlocal filesystem, edit it, and then copy it back to the RMfuse filesystem.\nThis will cause annotations to be lost (in `orig` mode) or flattened into\nthe document itself (in `annot` mode).\n\nThere are several rendering options that affect the appearance of annotated\ndocuments.  These can be set in a config file, which by default lives at\n`~/.config/rmfuse/config.ini`.  Run `rmfuse --write-config` to create a\nconfig file with the defaults at that location.  The default mode and\nmountpoint can also be set in this file.\n\n## Known Limitations\n\n- The file size for annotated files is just an estimate before the file\nis first read.  This can confuse some tools which use the file size to\ndetermine how much to read.  After reading the file once, the file size\nwill be correctly reported going forward; rerunning these tools a second\ntime is usually enough to get them working.\n\n- To try to address this, RMfuse throws an error when a program tries to\nread past the end of a file.  This can cause \"No data available\" errors\nto be reported.  These are harmless.\n\n- Adding a file other than an EPUB or PDF silently fails.  RMfuse does\nthrow an error when it has been given an invalid file, but this comes\ntoo late for FUSE to pass the error back to the caller.  RMfuse may be\nable to throw an error earlier, based on the first bytes it receives;\nthis will be investigated in the future.\n\n- RMfuse caches open files in memory.  This is bad for large files (too\nmuch memory used) and small files (we could cache several files).  A more\nsophisticated caching system is planned.\n\n## Libraries\n\nRMfuse is powered by [rmcl](https://github.com/rschroll/rmcl), for accessing\nthe reMarkable Cloud, and by [rmrl](https://github.com/rschroll/rmrl), for\nrendering annotated documents.  The early development of RMfuse can be found\nin the [rmcl repository](https://github.com/rschroll/rmcl)\n\n## Trademarks\n\nreMarkable(R) is a registered trademark of reMarkable AS. rmrl is not\naffiliated with, or endorsed by, reMarkable AS. The use of \"reMarkable\"\nin this work refers to the company’s e-paper tablet product(s).\n\n## Copyright\n\nCopyright 2020-2021 Robert Schroll\n\nRMfuse is released under the MIT license.  See LICENSE.txt for details.\n\n## Disclaimer of Warranty\n\nRMfuse is provided without any warranty.  Users accept the risk of damages,\nincluding the loss of data on their local system, on their reMarkable\ndevice, and in the reMarkable Cloud.\n\nIf it breaks, you get to keep both halves.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frschroll%2Frmfuse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frschroll%2Frmfuse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frschroll%2Frmfuse/lists"}