Skip to main content
Glama
nadimhoss

mcp-notes-server

by nadimhoss

mcp-notes-server

An MCP server that gives an AI agent a searchable markdown notes vault: six tools over a flat directory of .md files with YAML-style frontmatter.

Notes stay plain markdown on disk. Nothing is locked in a database, so the same files work with your editor, grep, and git.

~/notes/
├── pad-thai.md
├── sourdough-starter.md
└── weekly-review.md

Tools

Tool

Description

create_note

Create a note. Returns the generated slug.

read_note

Read one note in full, by slug.

list_notes

Summaries (no bodies), newest first, optionally filtered by tag.

search_notes

Ranked full-text search with snippets.

update_note

Patch title / body / tags. The slug never changes.

delete_note

Delete a note by slug.

Install

npm install
npm run build

Use it with an MCP client

Add it to your client's server config — for Claude Desktop, claude_desktop_config.json:

{
  "mcpServers": {
    "notes": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-notes-server/dist/src/index.js", "--vault", "/absolute/path/to/notes"]
    }
  }
}

The vault directory is resolved in this order: --vault <dir>, then $NOTES_VAULT, then ~/notes. It is created on startup if it does not exist.

Design notes

Slugs are the identity, and they are validated. A note lives at <vault>/<slug>.md, and every slug is checked against /^[a-z0-9]+(?:-[a-z0-9]+)*$/ before it reaches the filesystem. That is what makes read_note({slug: "../../.ssh/id_rsa"}) impossible rather than merely unlikely — an allowlist, not an escaping pass. Slugs are also stable across updates: renaming the file when the title changes would invalidate any slug the model is still holding from an earlier tool call.

Tool errors are data, not exceptions. "No note with slug X" comes back as a normal tool result with isError: true, so the model reads it and corrects itself. If it were thrown, the client would see a protocol error, which the model cannot recover from. Genuine bugs (anything that is not a VaultError) are still thrown, so they stay loud.

Search is weighted term frequency. A term in the title counts triple and a term in a tag counts double, so searching sourdough ranks a note about sourdough above one that mentions it in passing. It is deliberately simple — no index to keep in sync, and a vault of a few thousand notes scans in milliseconds.

The vault knows nothing about MCP. src/vault.ts is plain filesystem code, src/server.ts is the MCP binding, and src/index.ts is the stdio entry point. That split is why the vault can be tested directly and the server can be tested through a real MCP client over an in-memory transport, with no subprocess and no mocks.

Development

npm test          # 46 tests, vitest
npm run typecheck # tsc --noEmit
npm run build     # emit to dist/

Tests cover the vault directly (test/vault.test.ts) and the server end to end through a real MCP Client over InMemoryTransport (test/server.test.ts), so tool schemas, argument validation, and result shapes are all exercised — not just the logic behind them.

License

MIT

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.

  • AI access to your aNotepad online notes: read, search, write, and organize via 22 tools.

  • Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nadimhoss/mcp-notes-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server