notes-mcp
A simple MCP server for chatbot/human collaborative management of text content stored as markdown files with YAML frontmatter.
README
Notes MCP server
A simple MCP server for chatbot/human collaborative management of text content.
Content files, notes, are stored as markdown files with YAML frontmatter, a format commonly used to organize blog posts. Having metadata associated with the notes is useful for various things, such as timestamping and searchability.
I use the server as
- a means to improve my own own productivity, through management of blog content, general notes and other things.
- a demo project, for showing and reasoning about the capabilities of LLM tool usage.
Tool usage and model context protocol (MCP)
Tool usage is the concept of having an LLM invoke software functions when they receive input that warrants it. The model context protocol is a standard whose main purpose is to define conventions for how tool usage should be implemented. Here is an example of the present MCP server in action, in conjunction with an official Gmail tool server:
<img src="images/meetup-attendance-update.png" width="85%">
Try out the server
-
Get Claude desktop and the uv Python package manager.
-
Put this in the
claude_desktop_config.jsonfile of your Claude installation (with an updated path to an existing folder called "my-notes"):
{
"mcpServers": {
"my-notes": {
"command": "uvx",
"args": ["notes-mcp", "C:\\Users\\me\\path\\to\\my-notes"]
}
}
}
-
(Re-) Start Claude desktop and check in the chat input toolbar that "my-notes" and "Web search" are activated.
-
Tell Claude "github.com/edvardlindelof/notes-mcp seems like an awesome package, check it out and save a small TODO about sharing it with others in my notes".
-
Did your LLM hallucinate? Then open the note in your favorite editor and correct it. Work collaboratively!
Implementation
The server is built with FastMCP and implements the operations read, write, glob, mkdir, rm, rmdir and search. Most of them are very simple, here is mkdir:
@mcp.tool()
def mkdir(path: str) -> str:
"""Create a directory."""
(root_dir / path).mkdir(parents=True, exist_ok=True)
return f"Directory created: {path}"
Some cool aspects of LLM tool usage implementation
Here are some things about LLM tool usage implementation that I find particularly powerful or fascinating!
Activating multiple tool servers is a means of instant integration
By activating multiple tool servers, you make your chatbot an integration interface between them. Above, you saw one example involving Gmail inbox parsing and another involving web fetch. Some wild possibilities emerge if you consider the range of available MCP servers out there. Try out what can be done with the Playwright MCP for automating web browsing, for example. Have it parse some web pages you're interested in and save the results with Notes MCP :).
The flexibility provided by the LLM lets you implement less
With the LLM responsible for figuring out the details of which tools to invoke and how, the chatbot becomes a very flexible UI. This often lets us be minimalistic about the set of tools that we implement. There is an example above: you may have noticed that while operations for reading, writing and deletion were listed, there is none for moving or renaming. This is deliberately omitted from the server because the LLM can figure out the workaround (read -> write -> delete) easily enough:
<img src="images/move-attendance-list.png" width="85%">
Don't jump straight to implementing every conceivable tool, but think about which ones are necessary to achieve value!
Tools can reverse delegate work to the LLM through their documentation
While the standard principle is that the LLM invokes tools to have work done, tools can also "fool" the LLM to do work upfront, using documentation. Example: if you study notes_mcp.py, you will find that there is no code in there for converting text to YAML (or markdown). This is instead delegated to the LLM by prompting it for already formatted YAML and markdown - all that is needed are the words "YAML" and "markdown" in the argument names:
@mcp.tool()
def write(path: str, yaml_frontmatter: str, markdown_content: str) ...
Delegating text formatting work to the LLM is appropriate because LLMs, while unreliable for many things, excel at syntax and formatting. This particular case of reverse delegation is a small example of something that can be much more elaborate. Typical chat LLMs will, for example, effectively and correctly populate large JSON strings as long as a template is included in the docstring.
Experiment with the server locally
-
Clone this repo.
-
Modify your
claude_desktop_config.jsonto include this:
{
"mcpServers": {
// ... other mcp servers go here ...
"my-notes-local": {
"command": "uv",
"args": [
"run",
"--directory",
"C:\\Users\\me\\path\\to\\notes-mcp",
"notes-mcp",
"C:\\Users\\me\\path\\to\\my-notes"
]
}
}
}
- Modify something in the code, then restart Claude desktop to try out the changes.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.