NotePlan / NotePlan/noteplan-mcp
Space notes created after server start are readable but not writable
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 16
- Forks
- 4
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Any teamspace note created after the MCP server starts can be read but cannot be
written. Every write form fails with Note not found: <id> — including the exact id
that a read returns successfully seconds earlier. Restarting the MCP server fixes it
until the next note is created.
In practice this means: create a note in a space, then try to write to it in the same
session, and the write fails.
Reproduce
- Start the MCP server.
- In NotePlan (or any other process), create a note in a teamspace — e.g. let a
scheduled job write today's teamspace calendar note. noteplan_get_notesby that note's id → succeeds, full content returned.noteplan_edit_content(append/insert) on the same note → fails,
Note not found: <id>. Same fornoteplan_paragraphs(which surfaces it as
Cannot read properties of undefined (reading 'toLowerCase')).
Addressing by date, filename,spaceId, or direct id all fail identically.- Restart the MCP server, retry step 4 unchanged → succeeds.
Possible Cause
Space reads go through the HTTP bridge to the running app, so they are always
fresh. Space writes resolve the row through sql.js
(sqlite-writer.ts → getSpaceNode() → sqlite-reader.ts getDatabase()).
Per sqlite-loader.ts's own comment, sql.js is in-memory and "loaded at startup after
checkpointing the WAL". That snapshot is taken once and never refreshed, while NotePlan
continues writing to the real file via WAL. So rows the host app creates after startup
are permanently invisible to the writer, and getSpaceNode() throws Note not found.
Suggested fix
Re-checkpoint and reload on a miss, using the machinery already present:
closeDatabase()— also resetdbChecked = falseandcachedDbPath = null, so a
subsequentgetDatabase()genuinely reopens.getSpaceNode()— on a miss, reload the snapshot (checkpointWal()+ reopen) and
re-query once before throwing.
Both changes sit on the failure path, which today is an unconditional throw, so they
can't regress the success path. A cheaper variant, if a reload per miss is too eager:
reload at most once per N seconds.
Environment
- NotePlan 3.21.1 (build 1512), Setapp
- macOS 26.5.2 (arm64)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read sqlite-loader.ts, sqlite-writer.ts around getSpaceNode(), and sqlite-reader.ts around getDatabase(); trace how the startup WAL snapshot is opened and how a missing row is handled. Reproduce the post-start teamspace-note workflow, then verify that a miss refreshes the snapshot and the same note can be written without restarting the MCP server.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite, typescript
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100