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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。