mcp-notas
mcp-server-example — Markdown 메모 데이터베이스용 MCP 서버
기능적이고 테스트된 예제 MCP(Model Context Protocol) 서버로, 어시스턴트에게 세컨드 브레인에 대한 액세스를 제공합니다: 생성, 읽기, 업데이트, 나열, 검색, 측정이 가능한 로컬 Markdown 메모 디렉터리입니다.
여기서 초점은 기능의 양이 아니라 정직한 MCP 서버를 보여주는 것입니다: type hints에서 생성된 스키마, path traversal에 대한 진짜 정화, 그리고 호출을 시뮬레이션하는 대신 실제로 도구를 호출하는 테스트 스위트.
MCP란 무엇인가
Model Context Protocol은 어시스턴트가 외부 시스템과 대화하는 방식을 표준화하는 개방형 프로토콜입니다. 각 애플리케이션이 자체 플러그인 형식을 발명하는 대신, MCP 서버는 세 가지를 선언합니다 — tools(모델이 실행할 수 있는 작업), resources(URI로 주소가 지정된, 읽을 수 있는 데이터), prompts(사용자가 호출할 수 있는 대화 템플릿) — 그리고 호환되는 모든 클라이언트가 이를 자동으로 발견하고 사용합니다. 통신은 JSON-RPC이며, 일반적으로 stdio를 통해 이루어집니다: 클라이언트가 서버를 하위 프로세스로 실행하고 표준 입력/출력으로 메시지를 교환합니다.
Related MCP server: Notes MCP Server
여기에 포함된 것
파일 | 역할 |
|
|
| 모든 디스크 I/O 및 식별자 정화. 경로를 구성하는 유일한 지점. |
| 필드별 순위(제목 > 태그 > 본문)가 있는 텍스트 검색, 악센트 무시. |
|
|
| 실제 서버를 실행하는 45개 테스트, 완전한 MCP 세션 포함. |
| 런타임 및 테스트 의존성. |
|
|
각 메모는 최소한의 front matter가 있는 .md 파일입니다:
---
title: Teste env
tags: []
created: 2026-08-25T00:20:24+00:00
updated: 2026-08-25T00:20:24+00:00
---서버가 노출하는 것
Tools
Tool | 인수 | 반환 |
|
| 날짜가 채워진 생성된 메모. |
|
| 전체 메모(본문, 태그, 날짜). |
|
| 이미 업데이트된 메모. |
|
| 텍스트로 된 확인 메시지. |
|
| 각 메모의 총계 및 요약, 본문 제외. |
|
| 관련성 순으로 정렬된 결과, 발췌문 포함. |
| — | 개수, 가장 많이 사용된 태그, 가장 긴 메모. |
Resources
URI | 유형 | 내용 |
|
| 전체 데이터베이스의 인덱스: 각 메모의 slug, 제목, 태그 및 URI. |
|
| front matter가 포함된 메모의 전체 Markdown. |
Prompts
Prompt | 인수 | 구성 내용 |
|
| 메모 내용이 이미 포함된 요약 요청. |
|
| 네 개의 메시지: 지침, 시작 메모, 다른 메모들의 카탈로그, 어시스턴트의 시작. |
설치
git clone <url-do-repositorio> mcp-server-example
cd mcp-server-example
pip install -r requirements.txtPython 3.11+ 및 mcp >= 1.27.0 필요.
실행 방법
기본 전송은 stdio입니다 — MCP 클라이언트가 서버를 실행하는 방식입니다:
cd mcp-server-example
python3 -m mcp_notas프로세스는 표준 입력에서 JSON-RPC 메시지를 기다리며 조용히 대기합니다; 이것은 정상적인 동작이지 멈춤이 아닙니다.
데이터베이스 디렉터리는 환경 변수 MCP_NOTAS_DIR로 구성할 수 있습니다(기본값: ./notas, 자동 생성):
MCP_NOTAS_DIR=~/meu-second-brain python3 -m mcp_notas클라이언트 구성
MCP 클라이언트 구성에 붙여넣을 준비가 된 블록:
{
"mcpServers": {
"notas": {
"command": "python3",
"args": ["-m", "mcp_notas"],
"cwd": "/caminho/absoluto/para/mcp-server-example",
"env": {
"MCP_NOTAS_DIR": "/caminho/absoluto/para/suas-notas"
}
}
}
}⚠️ 이 블록은 이 환경에서 실제 MCP 클라이언트에 대해 테스트되지 않았습니다. 여기서 검증된 것은 프로그래밍 방식의 동등물입니다: 서버가
python3 -m mcp_notas로 하위 프로세스로 실행되었고 SDK의ClientSession이 stdio를 통해 handshake를 완료하고, tools를 나열하고, 호출을 실행했습니다("검증 상태" 참조). 이 handshake를 특정 클라이언트의 구성 형식으로 변환하는 것은 실행되지 않았습니다.
사용 예시
실제 출력, 서버를 in-process로 실행하여 캡처(criar_servidor() + call_tool). diretorio 필드는 일반 경로로 대체되었습니다; 나머지는 그대로입니다.
>>> criar_nota
{
"slug": "protocolo-mcp",
"titulo": "Protocolo MCP",
"tags": [
"mcp",
"protocolo"
],
"corpo": "O Model Context Protocol padroniza como um assistente acessa ferramentas e dados externos.",
"criada_em": "2026-08-25T00:20:03+00:00",
"atualizada_em": "2026-08-25T00:20:03+00:00"
}
>>> listar_notas(tag='mcp')
{
"total": 1,
"filtro_tag": "mcp",
"notas": [
{
"slug": "protocolo-mcp",
"titulo": "Protocolo MCP",
"tags": [
"mcp",
"protocolo"
],
"atualizada_em": "2026-08-25T00:20:03+00:00",
"resumo": "O Model Context Protocol padroniza como um assistente acessa ferramentas e dados externos.",
"tamanho": 90
}
]
}
>>> buscar_notas(consulta='protocolo')
{
"consulta": "protocolo",
"total": 2,
"resultados": [
{
"slug": "protocolo-mcp",
"titulo": "Protocolo MCP",
"tags": [
"mcp",
"protocolo"
],
"pontuacao": 8.0,
"trecho": "O Model Context Protocol padroniza como um assistente acessa ferramentas e dados externos."
},
{
"slug": "memoria-de-longo-prazo",
"titulo": "Memória de longo prazo",
"tags": [
"produtividade"
],
"pontuacao": 1.0,
"trecho": "Anotações sobre second brain. Cita o protocolo de revisão semanal."
}
]
}순위에 주목하세요: "protocolo"라는 단어는 첫 번째 메모의 제목과 태그에 있습니다(점수 8.0), 두 번째 메모의 본문에만 있습니다(점수 1.0).
>>> estatisticas_base()
{
"total_de_notas": 2,
"total_de_caracteres": 156,
"total_de_palavras": 23,
"media_de_caracteres": 78.0,
"total_de_tags": 3,
"tags_mais_usadas": {
"mcp": 1,
"produtividade": 1,
"protocolo": 1
},
"nota_mais_longa": "protocolo-mcp",
"ultima_atualizacao": "2026-08-25T00:20:03+00:00",
"diretorio": "/caminho/para/notas"
}
>>> read_resource('notas://index')
{
"diretorio": "/caminho/para/notas",
"total": 2,
"notas": [
{
"slug": "memoria-de-longo-prazo",
"titulo": "Memória de longo prazo",
"tags": [
"produtividade"
],
"uri": "notas://memoria-de-longo-prazo"
},
{
"slug": "protocolo-mcp",
"titulo": "Protocolo MCP",
"tags": [
"mcp",
"protocolo"
],
"uri": "notas://protocolo-mcp"
}
]
}
>>> get_prompt('resumir_nota', {'slug': 'protocolo-mcp'})
Resuma em no máximo 3 bullets.
Não invente informação que não esteja na nota.
# Protocolo MCP
Tags: mcp, protocolo
O Model Context Protocol padroniza como um assistente acessa ferramentas e dados externos.그리고 실제 stdio handshake, 서버가 하위 프로세스로 실행되고 SDK의 ClientSession이 반대편에 있는 경우(리터럴 출력, 서버의 INFO 로그 제외):
serverInfo: mcp-notas 1.27.0
instructions[:60]: Servidor de uma base local de notas em Markdown. Use 'listar
tools: ['apagar_nota', 'atualizar_nota', 'buscar_notas', 'criar_nota', 'estatisticas_base', 'ler_nota', 'listar_notas']
criar_nota isError: False slug: handshake-stdio
estatisticas: 1 nota(s)
traversal isError: True
traversal msg: Error executing tool ler_nota: Identificador inválido '../../etc/passwd': separadores de caminho não são permitidos. Use보안
파일을 다루는 MCP 서버의 전형적인 버그는 모델에서 온 식별자를 받아 경로에 직접 연결하는 것입니다: Path(base) / slug. slug = "../../etc/passwd"를 사용하면 프롬프트를 제어하는 사람에게 전체 디스크가 노출됩니다.
여기서 방어는 mcp_notas/storage.py에 있으며 두 계층이 있습니다.
1. sanitizar_slug() — 허용 목록 검증. 식별자는 경로 구분자(/, \), null 바이트, Windows 드라이브 문자(C:) 및 ..의 모든 발생을 명시적으로 거부한 후 ^[a-z0-9][a-z0-9._-]{0,79}$와 일치해야만 통과합니다. 문자나 숫자로 시작해야 한다는 요구 사항은 .ssh와 같은 숨김 이름도 차단합니다.
2. BaseDeNotas.caminho() — 확인된 경로 검증. 정화 후 경로는 Path.resolve()로 확인되고 코드는 그 부모가 정확히 데이터베이스 디렉터리인지 확인합니다. 이 검사는 구조상 중복됩니다 — 그리고 그것이 요점입니다: 첫 번째 계층에 구멍이 생기더라도 누출은 발생하지 않습니다.
도구에 대해 실제로 실행된 표준 공격:
>>> call_tool('ler_nota', {'slug': '../../etc/passwd'})
ToolError: Error executing tool ler_nota: Identificador inválido '../../etc/passwd': separadores de caminho não são permitidos. Use apenas o slug da nota, sem diretórios.notas://{slug} 리소스도 동일한 보호를 가지며, 두 가지 다른 경로로: 원시 URI notas://../../etc/passwd는 템플릿과 일치하지도 않습니다(Unknown resource), 반면 percent-encoded 형식 notas://..%2F..%2Fetc%2Fpasswd는 일치하고 정화에 도달하여 거부됩니다 — 위험한 두 번째 경우가 테스트가 다루는 것입니다.
테스트는 또한 파일 시스템에서 공격 대상이 생성되지 않음을 증명합니다: slug="../vazamento"로 criar_nota를 시도한 후 데이터베이스 디렉터리는 계속 비어 있고 외부 파일은 존재하지 않습니다.
또한: API 키 없음, 네트워크 액세스 없음, 서버는 구성된 디렉터리 밖에서 읽거나 쓰지 않습니다.
테스트
$ python3 -m pytest tests/ -q
............................................. [100%]
45 passed in 1.48spath traversal 테스트만:
$ python3 -m pytest tests/ -q -k traversal
................. [100%]
17 passed, 28 deselected in 0.67s스위트는 순서대로 다음을 다룹니다:
정화 — 13개의 매개변수화된 악성 입력(
../../etc/passwd,/etc/passwd,..\\..\\windows\\system32\\config\\sam,C:\Windows\win.ini,nota\x00.md, 빈 문자열…), 데이터베이스 밖에 아무것도 생성되지 않는다는 디스크 증명 포함.MCP 표면 —
list_tools가 정확히 일곱 개의 tools를 반환하고, 스키마(required,type,default,outputSchema)는 type hints와 docstrings에서 생성된 것입니다.각 tool의 실제 호출 — 디스크에서 확인된 지속성을 가진 생성, 중복, 읽기, 존재하지 않는 항목 읽기, 업데이트,
anexar로 업데이트, 태그 필터 유무에 따른 나열, 순위 및 제한이 있는 검색, 통계 및 삭제.Resources —
list_resources,list_resource_templates, JSON 인덱스 읽기, 개별 메모 읽기 및 두 가지 traversal 형식.Prompts —
list_prompts, 두 프롬프트의get_prompt, 메모 내용이 실제로 포함되고 시작 메모가 다른 메모들의 카탈로그에 나타나지 않는지 확인.종단 간 세션 —
create_connected_server_and_client_session이 메모리에서 연결된 MCP 클라이언트와 서버를 실행합니다; 테스트는 tools를 나열하고, 메모를 생성하고, 나열하고, resource를 읽고, prompt를 가져오고 traversal 시도에서isError: True를 확인합니다.격리된 저장소 — front matter의 round-trip 및 메모가 아닌 파일이 나열에서 무시되는지.
검증 상태
아래의 모든 것은 이 환경에서 mcp 1.27.0, pytest 9.1.1 및 pytest-asyncio 1.4.0, Python 3.11에서 실행되었습니다.
✅ 검증됨
python3 -m pytest tests/ -q→ 45 passed.일곱 개의 tools가
FastMCP.call_tool을 통해 실제로 호출되고 결과가 확인됨.두 개의 resources가
FastMCP.read_resource로 읽힘; 두 개의 prompts가FastMCP.get_prompt로 읽힘.mcp.shared.memory.create_connected_server_and_client_session으로 메모리에서 완전한 MCP 클라이언트↔서버 세션.실제 stdio handshake: 서버가 하위 프로세스로 실행되고(
python3 -m mcp_notas) SDK의ClientSession이 이를 통해initialize,list_tools및call_tool을 실행.Path traversal이
sanitizar_slug, tool, resource 및 파일 시스템에서 거부됨.MCP_NOTAS_DIR존중됨: 생성된 메모가 변수가 가리키는 디렉터리에 나타남.이 README에 표시된 모든 출력은 실제 실행에서 복사됨.
⚠️ 테스트되지 않음
mcpServers블록은 실제 MCP 클라이언트(Claude Desktop, 편집기 등)에 대해 테스트되지 않았습니다. 이 환경에는 설치된 클라이언트가 없습니다; 이 검증을 대체하는 것은 위에서 설명한 프로그래밍 방식의 stdio handshake입니다.sse및streamable-http전송은FastMCP.run에 존재하지만 이 프로젝트는stdio만 실행합니다.동시성 테스트 없음: 동일한 메모에 대한 동시 쓰기는 lock으로 조정되지 않습니다.
Windows 또는 macOS 테스트 없음 — Linux만.
라이선스
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceManages markdown notes in a specified directory, allowing users to create, read, update, and list notes through the Model Context Protocol.1
- AlicenseAqualityDmaintenanceEnables creating, managing, and searching Markdown notes with support for tags, timestamps, and full-text search. Includes AI prompts for analyzing and summarizing notes.61MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to search, read, create, update, and remove personal markdown notes stored locally, providing persistent memory across sessions.132MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to interact with a local folder of Markdown notes, supporting listing, reading, searching, creating, and appending to notes with strict security boundaries.5MIT
Related MCP Connectors
AI access to your aNotepad online notes: read, search, write, and organize via 22 tools.
Read and write your Fresh Jots notes from Claude, Cursor, and any MCP client.
Create, validate, edit, export (markdown/svg/png/mermaid), and search JSON Canvas files.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/herickbrandao483-jpg/mcp-server-example'
If you have feedback or need assistance with the MCP directory API, please join our Discord server