Skip to main content

joplin-md-sync

Safe two-way synchronization between the local Joplin desktop application and an ordinary directory of Markdown files — built primarily for autonomous coding agents (deterministic JSON output, stable exit codes, explicit conflict handling), and perfectly usable by humans.

Documentation: joplin-mcp.romancello.net

Safety first. The tool never overwrites divergent edits, never deletes anything without an explicit flag, never uses permanent deletion in Joplin, verifies every write after applying it, and journals every mutating run so interrupted syncs are recoverable. diff never mutates anything.

The test-backed definitions of these guarantees live in the contract catalog.

If you are an agent (or configuring one), start with AGENTS.md.

How it works

  • Notes are plain .md files; each carries a one-line metadata header with the Joplin id, title, and tags. Notebooks are directories with a .joplin-folder.json.
  • Sync state (base snapshots for true three-way comparison) lives in .joplin-sync/state.sqlite3 inside the workspace — never committed to Git.
  • All communication uses the documented local Joplin Data API (Web Clipper service); Joplin's own database and sync targets are never touched.

Installation

Source, wheel, and zipapp installations require CPython >= 3.13 on Windows or Linux. Native release executables include Python and have no external runtime dependencies.

python -m pip install "joplin-md-sync==1.5.5"
# or: pipx install "joplin-md-sync==1.5.5"
# or download joplin-md-sync.pyz from a release and: python joplin-md-sync.pyz --help

Native GitHub Release assets:

Platform Architecture Asset
Linux AMD64 joplin-md-sync-linux-amd64
Linux ARM64 joplin-md-sync-linux-arm64
Windows AMD64 joplin-md-sync-windows-amd64.exe

On Linux, mark the downloaded executable as executable before running it:

chmod +x joplin-md-sync-linux-amd64
./joplin-md-sync-linux-amd64 version

From a checkout, everything is driven by the Makefile:

make venv        # runtime venv/ with the CLI installed (venv/bin/joplin-md-sync)
make venv-dev    # Linux quality tools (ruff, mypy, Bandit, pip-audit)
make venv-test   # cross-platform pytest tools
make venv-package # cross-platform PyInstaller and build tools
make check       # lint + typecheck + full test suite
make freeze-check # verify all generated dependency locks are current
make test-live   # opt-in real-Joplin MCP + GPT Actions suites; reads ./token
make test TEST_WORKERS=8  # override automatic parallel test workers
make package     # wheel, sdist, .pyz, current-platform executable, checksums
make help        # all targets

The version's single source is the root .version file; runtime dependencies are declared in pyproject.toml (none by design). Direct tools are pinned to their latest stable compatible releases in purpose-specific quality, test, package, and docs groups. The four committed pip-compile locks include SHA-256 hashes and are checked for drift in CI; Windows jobs install only the cross-platform test or package lock they need.

Five-minute quick start

  1. In Joplin: Tools > Options > Web Clipper — enable the service, copy the authorization token.
  2. export JOPLIN_TOKEN=<your token>          # Windows: set JOPLIN_TOKEN=...
    joplin-md-sync init --root ./notes
    joplin-md-sync pull --root ./notes
    
    The token is the only required configuration: the default endpoint http://127.0.0.1:41184 is built in (override with JOPLIN_BASE_URL, JOPLIN_PORT, --base-url, or --port when needed).
  3. Edit files under ./notes, then:
    joplin-md-sync diff --root ./notes
    joplin-md-sync push --root ./notes --dry-run
    joplin-md-sync push --root ./notes
    
  4. If both sides changed the same note, you get exit code 2 and a conflict bundle: joplin-md-sync conflicts list / conflicts resolve ID --take-local|--take-remote|--merged-file PATH.

Agent notes repository template

examples/agent-notes-repository/ is a copyable starter repository for users who want an agent to work on their Joplin notes as ordinary Markdown files. It includes:

  • a repository-specific AGENTS.md with the guarded pull/edit/diff/dry-run/push workflow and an optional MCP setup path;
  • a human runbook that starts with enabling Web Clipper in Joplin Desktop and storing its token outside the sync workspace;
  • a .gitignore for credentials, the local standalone binary, and all sync state; and
  • a standard-library installer that downloads the latest compatible native release into .tools/, verifies SHA256SUMS.txt, and validates the binary before replacing an existing installation.

Start with the template's README, not the development instructions for this source checkout.

MCP and ChatGPT Actions service

One foreground joplin-md-sync process exposes MCP and authenticated REST Actions from the same tool registry on different URIs. It starts while Joplin is offline and recovers on later calls without a restart.

The Actions token is mandatory when Actions are enabled and is reloaded from a protected file. MCP bearer authentication remains optional through a separate --auth-token-file. The headless installer always installs both APIs as one joplin-md-sync.service; it generates separate mandatory Actions and MCP tokens, stores them in protected files, and reports only their paths after a successful install. It never creates a separate Actions service.

Use service installation and operations for Linux, Windows, credentials, URI isolation, and live tests; MCP API for the tool contract; and the single ChatGPT Actions end-to-end setup for endpoint validation, schema export, GPT Instructions, editor configuration, and acceptance testing.

Architecture overview

cli  ->  planner (pure three-way classification: base/local/remote)
     ->  executor (guard -> apply -> verify -> commit base, journaled)
api: stdlib urllib client for the Joplin Data API (pagination, retries)
mcp/actions: two HTTP transports -> shared registry/executor -> Joplin service -> api
state: SQLite base snapshots, conflicts, tombstones, run journal
workspace: scanning, atomic writes, backups, quarantine, cross-platform lock

Details in Architecture.

Supported / not supported (v1)

Supported Out of scope
notes, notebooks (nested), tags, binary attachments editing settings, revisions, or encryption state
two-way sync with conflict bundles Nextcloud/WebDAV or any direct sync target
resource download/upload/edit through MCP replacing Joplin's own device sync
crash recovery, backups, quarantine automatic text merging (only explicit --merged-file)
Windows + Linux, Python 3.13/3.14; MCP daemon filesystem watch mode, native mobile CLI, self-update, permanent note/notebook deletion

Versioning

Semantic versioning; Git tags vX.Y.Z with GitHub releases carrying the wheel, sdist, .pyz, native executables, and SHA-256 checksums. The same wheel and sdist are published to PyPI through Trusted Publishing. joplin-md-sync update-check --json compares the installed version against the latest stable release (exit 8 when outdated). JSON output, exit codes, and the state schema are versioned and stable across patch releases. See CHANGELOG.md.

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

joplin_md_sync-1.5.5.tar.gz (200.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

joplin_md_sync-1.5.5-py3-none-any.whl (99.6 kB view details)

Uploaded Python 3

File details

Details for the file joplin_md_sync-1.5.5.tar.gz.

File metadata

  • Download URL: joplin_md_sync-1.5.5.tar.gz
  • Upload date:
  • Size: 200.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for joplin_md_sync-1.5.5.tar.gz
Algorithm Hash digest
SHA256 b69969705593d0f7ae8a9919f701edaf666729fca8e60e9e2a0fd5dd386f7097
MD5 25fe1a6e19aa37848e4205c54e3f135a
BLAKE2b-256 a286602394b5382e66732f3445bc64676d6b0e672ef3927a34ad387cbaf864db

See more details on using hashes here.

Provenance

The following attestation bundles were made for joplin_md_sync-1.5.5.tar.gz:

Publisher: release.yml on kogeler/joplin-md-sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file joplin_md_sync-1.5.5-py3-none-any.whl.

File metadata

  • Download URL: joplin_md_sync-1.5.5-py3-none-any.whl
  • Upload date:
  • Size: 99.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for joplin_md_sync-1.5.5-py3-none-any.whl
Algorithm Hash digest
SHA256 7a0d032650e41c1d5df0cad5861ae2534eff8fe8bf721eb46e80e2da51cbe0e5
MD5 1870baab10fb3ed08e542a047f286b1e
BLAKE2b-256 027429287cb46f27c30d96a62ceff41ea150d0f39997d6aa85185b51f4b746ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for joplin_md_sync-1.5.5-py3-none-any.whl:

Publisher: release.yml on kogeler/joplin-md-sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.6.0

2 files

1.5.6

2 files

This release

1.5.5 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page