Skip to content

Add document notes tools (create/list/delete) - #125

Merged
baruchiro merged 3 commits into
baruchiro:mainfrom
nickponomar:add-document-notes-tools
Jul 10, 2026
Merged

Add document notes tools (create/list/delete)#125
baruchiro merged 3 commits into
baruchiro:mainfrom
nickponomar:add-document-notes-tools

Conversation

@nickponomar

@nickponomar nickponomar commented Jul 8, 2026

Copy link
Copy Markdown

What

Adds MCP tools for Paperless document notes, backed by the /api/documents/{id}/notes/ endpoint:

  • list_document_notes(id)GET /documents/{id}/notes/
  • create_document_note(id, note)POST /documents/{id}/notes/
  • delete_document_note(id, note_id)DELETE /documents/{id}/notes/?id={note_id}

Why

There was no way to add a note/comment to a document via the MCP, so the only workaround was calling the REST API directly with a token. Notes are the natural place for an audit trail (e.g. "invoice paid on X from account Y") or progress notes on an action item.

Closes #124

Implementation notes

  • New src/tools/notes.ts follows the existing registerXTools pattern (withErrorHandling, zod schemas), wired in src/server.ts.
  • Three client methods added to src/api/PaperlessAPI.ts; reuses the existing Note type in src/api/types.ts.
  • create_document_note validates a non-empty note; all three return the document's notes array (matching Paperless behaviour).

Tests

  • New src/tools/notes.test.ts (4 tests) using the in-memory MCP client harness: create/list/delete call-through and empty-note rejection.
  • Full unit suite passes (35/35), tsc --noEmit clean, npm run build clean.
  • Added a minor changeset.

🤖 Generated with Claude Code

https://claude.ai/code/session_014EoK17h8dBErKg9cwNFoLn

Summary by CodeRabbit

  • New Features
    • Added MCP Document Notes tools to list, create, and delete notes, including server-side registration so they’re available to clients.
  • Documentation
    • Updated the README “Available Tools” with detailed Document Notes tool descriptions and TypeScript examples (including delete confirm usage).
  • Bug Fixes
    • Added validation to prevent empty note creation and added a safety check requiring confirm: true before deletion.
  • Tests
    • Added a comprehensive test suite covering successful operations plus validation/error behavior.

Adds MCP tools for Paperless document notes, backed by the
/api/documents/{id}/notes/ endpoint: create_document_note,
list_document_notes, and delete_document_note. Notes are the natural
place for an audit trail or progress notes on a document.

Closes baruchiro#124

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EoK17h8dBErKg9cwNFoLn
@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 67acb95

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@baruchiro/paperless-mcp Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2e790bac-1b19-4096-ad4f-ce1810ef8856

📥 Commits

Reviewing files that changed from the base of the PR and between 417fa49 and 67acb95.

📒 Files selected for processing (1)
  • src/api/PaperlessAPI.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/api/PaperlessAPI.ts

📝 Walkthrough

Walkthrough

This PR adds document notes support to the paperless-mcp server. PaperlessAPI gains getDocumentNotes, createDocumentNote, and deleteDocumentNote methods for /documents/{id}/notes/. registerNoteTools adds list_document_notes, create_document_note, and delete_document_note, and server startup now registers them. Tests cover the new tools, and the README plus changeset document the addition.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: baruchiro

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding document note tools for create, list, and delete.
Linked Issues check ✅ Passed The PR adds the requested create, list, and delete document note tools, wires them into the server, and includes API methods and tests.
Out of Scope Changes check ✅ Passed The changes stay focused on document note tools, with only supporting README, tests, and changeset updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/api/PaperlessAPI.ts (1)

224-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add JSDoc comments to the new API methods.

As per coding guidelines, API methods in PaperlessAPI.ts should include JSDoc comments. The three new note methods (getDocumentNotes, createDocumentNote, deleteDocumentNote) lack JSDoc.

📝 Suggested JSDoc additions
   // Document note operations
+  /**
+   * Retrieve all notes attached to a document.
+   * `@param` id - The document ID.
+   * `@returns` The document's notes.
+   */
   async getDocumentNotes(id: number): Promise<Note[]> {
     return this.request<Note[]>(`/documents/${id}/notes/`);
   }

+  /**
+   * Create a note on a document and return the updated notes list.
+   * `@param` id - The document ID.
+   * `@param` note - The note text to add.
+   * `@returns` The document's full notes list after creation.
+   */
   async createDocumentNote(id: number, note: string): Promise<Note[]> {
     return this.request<Note[]>(`/documents/${id}/notes/`, {
       method: "POST",
       body: JSON.stringify({ note }),
     });
   }

+  /**
+   * Delete a note from a document by note ID and return the remaining notes.
+   * `@param` id - The document ID.
+   * `@param` noteId - The ID of the note to delete.
+   * `@returns` The document's remaining notes after deletion.
+   */
   async deleteDocumentNote(id: number, noteId: number): Promise<Note[]> {
     return this.request<Note[]>(`/documents/${id}/notes/?id=${noteId}`, {
       method: "DELETE",
     });
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/PaperlessAPI.ts` around lines 224 - 241, The new note-related methods
in PaperlessAPI lack the required JSDoc documentation. Add concise JSDoc
comments for getDocumentNotes, createDocumentNote, and deleteDocumentNote in
PaperlessAPI.ts, matching the style used by the other API methods and describing
each method’s purpose and parameters so they follow the project’s coding
guidelines.

Source: Coding guidelines

README.md (1)

322-334: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add destructive warning to delete_document_note README section.

If the tool description is updated to include a destructive warning (per coding guidelines), the README should reflect this as well. Consider adding a note that deletion is irreversible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 322 - 334, The README section for
delete_document_note needs the same destructive warning required by the tool
description. Update the delete_document_note documentation to clearly state that
this action is irreversible, keeping the warning aligned with the rest of the
delete-related docs and the delete_document_note example/parameter block.
src/tools/notes.ts (2)

13-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate response construction across all three handlers.

Each handler repeats the same { content: [{ type: "text", text: JSON.stringify(notes) }] } pattern. Extracting a small helper would reduce duplication and make future response format changes easier.

Also applies to: 34-45, 55-66

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/notes.ts` around lines 13 - 24, The three handlers in notes.ts all
build the same JSON text response inline after fetching notes, so extract that
repeated response-shaping logic into a small helper and reuse it from each
withErrorHandling callback. Keep the API fetches in place, but have the helper
return the standard { content: [{ type: "text", text: JSON.stringify(...) }] }
structure so any future format change is centralized.

13-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider using arrayNotEmpty for empty notes handling.

As per coding guidelines, use transformation utilities (arrayNotEmpty, objectNotEmpty) from tools/utils/empty.ts for empty value handling. When a document has no notes, the current response is "[]" — using arrayNotEmpty would provide a clearer user-facing message.

Also applies to: 34-45, 55-66

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/notes.ts` around lines 13 - 24, Update the notes tool handler in
the withErrorHandling block so empty note arrays are handled through the
arrayNotEmpty utility from tools/utils/empty.ts instead of returning
JSON.stringify(notes) as "[]". Locate the logic in the notes tool implementation
and apply the same empty-value transformation pattern to the other affected
branches mentioned in the review, so the user-facing response is clearer when
api.getDocumentNotes(args.id) returns no notes.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tools/notes.test.ts`:
- Around line 153-171: The create_document_note test is asserting the wrong
failure mode: tool validation errors from client.callTool return a
CallToolResult with isError set to true rather than rejecting. Update the test
in notes.test.ts to follow the same pattern as the other tool tests by checking
the returned result from create_document_note for isError instead of using
assert.rejects, while still verifying that calls.createDocumentNote remains
unused when validation fails.

In `@src/tools/notes.ts`:
- Around line 48-56: The delete tool in delete_document_note is missing the
required safety guard for destructive actions. Update the server.tool definition
for delete_document_note to add an explicit confirmation parameter in the schema
(for example a boolean confirm field) and make the tool description clearly warn
that the deletion is irreversible. Then enforce the confirmation check inside
the withErrorHandling callback before any delete logic runs, using the existing
api and args flow.

---

Nitpick comments:
In `@README.md`:
- Around line 322-334: The README section for delete_document_note needs the
same destructive warning required by the tool description. Update the
delete_document_note documentation to clearly state that this action is
irreversible, keeping the warning aligned with the rest of the delete-related
docs and the delete_document_note example/parameter block.

In `@src/api/PaperlessAPI.ts`:
- Around line 224-241: The new note-related methods in PaperlessAPI lack the
required JSDoc documentation. Add concise JSDoc comments for getDocumentNotes,
createDocumentNote, and deleteDocumentNote in PaperlessAPI.ts, matching the
style used by the other API methods and describing each method’s purpose and
parameters so they follow the project’s coding guidelines.

In `@src/tools/notes.ts`:
- Around line 13-24: The three handlers in notes.ts all build the same JSON text
response inline after fetching notes, so extract that repeated response-shaping
logic into a small helper and reuse it from each withErrorHandling callback.
Keep the API fetches in place, but have the helper return the standard {
content: [{ type: "text", text: JSON.stringify(...) }] } structure so any future
format change is centralized.
- Around line 13-24: Update the notes tool handler in the withErrorHandling
block so empty note arrays are handled through the arrayNotEmpty utility from
tools/utils/empty.ts instead of returning JSON.stringify(notes) as "[]". Locate
the logic in the notes tool implementation and apply the same empty-value
transformation pattern to the other affected branches mentioned in the review,
so the user-facing response is clearer when api.getDocumentNotes(args.id)
returns no notes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e7b541be-dce2-4ac6-b89e-6e1e7e4b278b

📥 Commits

Reviewing files that changed from the base of the PR and between 62e5b06 and 8ddbcf0.

📒 Files selected for processing (6)
  • .changeset/document-notes-tools.md
  • README.md
  • src/api/PaperlessAPI.ts
  • src/server.ts
  • src/tools/notes.test.ts
  • src/tools/notes.ts

Comment thread src/tools/notes.test.ts
Comment thread src/tools/notes.ts
@nickponomar

Copy link
Copy Markdown
Author

Hey @baruchiro, thanks for maintaining this project!

Heads-up that the CI workflows likely need your approval to run, since I'm a first-time contributor. Locally everything is green:

  • full unit suite 35/35 pass
  • tsc --noEmit clean
  • npm run build clean
  • verified end-to-end against a live Paperless instance (create/list/delete of a document note)

This closes #124 and follows the existing registerXTools pattern (new src/tools/notes.ts, three PaperlessAPI methods, README + a minor changeset). Happy to address any feedback whenever you get a chance. Thanks!

- delete_document_note now requires confirm: true and warns it is
  irreversible (matches the other destructive tools).
- Add JSDoc to the three new PaperlessAPI note methods.
- Extract a shared notesResult() helper to de-duplicate the tool
  response construction.
- Make the empty-note test accept either a protocol rejection or an
  isError result (the pinned MCP SDK rejects zod violations with -32602;
  newer SDKs return isError), and add a delete-without-confirm test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EoK17h8dBErKg9cwNFoLn
Comment thread src/api/PaperlessAPI.ts Outdated
@nickponomar
nickponomar requested a review from baruchiro July 10, 2026 15:32
@baruchiro
baruchiro enabled auto-merge (squash) July 10, 2026 15:53
@baruchiro
baruchiro merged commit 5032cec into baruchiro:main Jul 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tools for document notes (create/list/delete via /api/documents/{id}/notes/)

2 participants