<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Saurabh Pathak</title>
    <description>The latest articles on DEV Community by Saurabh Pathak (@saurabh_pathak394).</description>
    <link>https://dev.to/saurabh_pathak394</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4207685%2F527127c1-9f88-4cb1-bfc9-c923b41a218b.png</url>
      <title>DEV Community: Saurabh Pathak</title>
      <link>https://dev.to/saurabh_pathak394</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saurabh_pathak394"/>
    <language>en</language>
    <item>
      <title>mcp-notes-server: giving Claude a notes memory that lives in one JSON file</title>
      <dc:creator>Saurabh Pathak</dc:creator>
      <pubDate>Mon, 26 Oct 2026 10:29:17 +0000</pubDate>
      <link>https://dev.to/saurabh_pathak394/mcp-notes-server-giving-claude-a-notes-memory-that-lives-in-one-json-file-7l3</link>
      <guid>https://dev.to/saurabh_pathak394/mcp-notes-server-giving-claude-a-notes-memory-that-lives-in-one-json-file-7l3</guid>
      <description>&lt;p&gt;Every chat with an AI assistant starts from zero. I wanted Claude to be able to remember things between conversations, with the notes on my own disk and no cloud service involved.&lt;/p&gt;

&lt;p&gt;mcp-notes-server is a Model Context Protocol (MCP) server in TypeScript. Connect it to Claude Desktop, Claude Code or any MCP client and the assistant can save, search, edit, export and delete notes that survive between chats. Everything sits in one local JSON file, and the server makes no network calls.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/techsaurabh-394/mcp-notes-server" rel="noopener noreferrer"&gt;https://github.com/techsaurabh-394/mcp-notes-server&lt;/a&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/mcp-notes-server" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/mcp-notes-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try it in one line with Claude Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;claude mcp add notes -- npx -y mcp-notes-server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then ask: "Save a note titled RAG chunking: use 800-character chunks. Tag it rag." and later "Search my notes for chunking."&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The AI app starts the server as a child process and talks to it over stdio using JSON-RPC. The model reads the tool list and picks a tool. The server validates the input and sends the result back as text.&lt;/p&gt;

&lt;h3&gt;
  
  
  There are 7 tools:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;add_note, get_note, list_notes, search_notes, update_note, delete_note&lt;/code&gt; and &lt;code&gt;export_notes&lt;/code&gt;. There are also two resources (notes://all and notes://{id}) and a review_notes prompt. Every tool has a typed zod schema and MCP annotations (readOnlyHint, destructiveHint and so on), so clients can show the right confirmation UI. Bad input returns a clear error and stores nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search
&lt;/h2&gt;

&lt;p&gt;Search is deliberately simple keyword scoring: +3 if a word is in the title, +2 if it matches a tag exactly, +1 if it is in the body. Scores add up, highest first. It is not semantic search, and I say so in the README. Embeddings are on the roadmap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safe writes
&lt;/h2&gt;

&lt;p&gt;The part I spent the most time on was making the file safe to write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writers take a lock file, write a temp file, then rename it over notes.json, so a crash never leaves half a file.&lt;/li&gt;
&lt;li&gt;A lock older than 30 seconds is treated as left behind by a crash and removed.&lt;/li&gt;
&lt;li&gt;A notes file with malformed entries is refused, not overwritten.&lt;/li&gt;
&lt;li&gt;A test starts four separate OS processes that add 15 notes each and checks that all 60 surviv
e.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security choices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No shell, no SQL, no network calls.&lt;/li&gt;
&lt;li&gt;The file path comes from the operator (NOTES_FILE), never from tool input. Ids are 8 hex characters and are never used as paths.&lt;/li&gt;
&lt;li&gt;stdout is the protocol channel, so all logging goes to stderr, and a test checks that every stdout line is a JSON-RPC message.&lt;/li&gt;
&lt;li&gt;Optional human approval for delete_note through a companion package, mcp-safe-actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;stdout belongs to the protocol. One stray console.log breaks an MCP server. Sending logs to stderr and testing for it saved me from a confusing class of bugs.&lt;/li&gt;
&lt;li&gt;End-to-end tests beat unit tests for MCP. The most useful tests spawn the built server over stdio with the MCP SDK client and call every tool with valid input, invalid input, empty results and unknown ids.&lt;/li&gt;
&lt;li&gt;Say what it does not do. Notes are plain text with no encryption, and the model sees whatever it reads. Putting that in the README is better than letting people assume otherwise.&lt;/li&gt;
&lt;li&gt;Publishing is its own task. Getting the package onto npm, with CI on Node 18, 20 and 22, took as long as some of the features.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mlhacks</category>
      <category>devchallenge</category>
      <category>hackathon</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
