nsync
Claude plugin that treats your Notion workspace like a git repository: pull, edit locally, diff, commit.
The problem
If you work on Notion docs alongside Claude, you've felt this:
- Every new chat starts with you pasting the same Notion page URLs in. Context that should be ambient becomes a chore.
- When Claude edits a doc, either it lands in Notion immediately (no preview, no rollback), or it sits in a transcript you'll lose the next time the window closes.
- Between sessions, there's no version trail. A subtle hallucination (a fabricated paragraph, a regression on a careful edit) has nothing standing between it and your team's published docs.
nsync makes the seam between Claude and Notion behave like git. Pull your tree once, edit locally with the tools you already use, see a real diff before changes go live, and let content hashes catch surprises before they ship.
What you get
- Pull once, work locally. No more pasting Notion URLs every chat. After
/nsync:init, the sub-tree lives next to your code as plain .md files. Claude works on the whole repo at once.
- Diff before you ship.
/nsync:diff is a real dry-run: exact unified diff of what would land in Notion, with rich blocks rendered as placeholders so the markdown change reads clearly. Catch hallucinations before they reach your team.
- Per-page version tracking. Content hashes for every page; both-sides-changed lands in an interactive conflict prompt (
[L]ocal / [R]emote / [E]dit-in-scratch / [S]kip), never a silent overwrite. Pure metadata bumps (someone tweaked a callout color) don't trigger noise.
- Whole-tree Claude context. Instead of fetching one Notion page per URL, Claude greps the full sync root in a single read: bigger context, fewer tokens, no losing track in the linked-doc-of-a-linked-doc rabbit hole.
Mental model
Like git, but the remote is a Notion page tree.
my-docs/ ← sync root (your local working dir)
├── .nsync/ ← like .git/; local state, do not edit
│ ├── config.json ← parent page identity
│ ├── manifest.json ← per-page UUID + hashes
│ ├── ignore ← which .md files to skip
│ └── snapshots/<id>.md ← last-synced baselines (drive safe updates)
├── welcome.md ← mirror of a Notion page
└── engineering/
├── index.md ← body of "Engineering" page itself
├── standards.md
└── onboarding.md
local_hash and remote_hash in the manifest are your indices. The snapshots are the staging baseline used to compute commits that touch only the markdown, never rich blocks.
Install
Prerequisite: Python 3
nsync shells out to a small bundled helper (scripts/nsync.py) for the deterministic work (content hashing, markdown normalization, diffing), so the model never does it by hand (slow, and unreliable for hashing). You need Python 3 on your PATH (python3 --version should print 3.x). It's standard-library only: no pip install, no virtualenv. macOS and most Linux distros already ship it.
Prerequisite: connect Notion
The plugin uses Anthropic's built-in Notion connector. Connect it once before installing:
- Claude Code (CLI / desktop app / IDE extensions): type
/connectors in a session (or open Settings → Connectors in the desktop app / IDE extension), select Notion, click Connect, and approve workspace access via OAuth.
- Claude Cowork (claude.ai/code web app): open your workspace's Connectors panel, select Notion, click Connect, and approve workspace access via OAuth.
You only do this once per workspace. No environment variables, no integration tokens, no per-page sharing; the OAuth connector handles all of that.
Claude Code
claude plugin marketplace add stanleynguyen/nsync-skill
claude plugin install nsync@nsync
Restart your session so the slash commands register. Verify with claude plugin list; nsync@nsync should appear as enabled.
Claude Cowork
- Open the Plugins panel in your Cowork workspace.
- Add a marketplace and paste
stanleynguyen/nsync-skill (or the full URL https://github.com/stanleynguyen/nsync-skill).
- Once the marketplace appears, install the
nsync plugin from it.
- Reload the workspace so the slash commands surface in
/help.
Local development
If you've cloned the repo locally, point the marketplace at the checked-out path:
claude plugin marketplace add /path/to/nsync-skill
claude plugin install nsync@nsync
Your first sync
Five-minute walkthrough. Pick a parent page in Notion you're willing to experiment on (or create a throwaway one) and copy its URL.
mkdir my-docs && cd my-docs
/nsync:init https://www.notion.so/workspace/My-Docs-fb1d8c3a5e214f708a239c4b6d8e1f02