Skip to main content
Glama

vault-mcp

한국어 | Português

CI npm

코딩 에이전트를 위한 장기 기억 저장소: 답변하기 전에 Obsidian 볼트를 검색하고, path:line을 인용하며, 어디에 저장할지 묻지 않고 학습한 내용을 기록합니다.

Obsidian 지식 볼트를 검색·읽기·쓰기 위한 MCP 서버입니다. BM25 어휘 검색에 위키 링크 한 홉을 더한 검색; 새 노트를 만들지 기존 노트에 추가할지 스스로 결정하는 지능형 학습 캡처; 도메인 MOC와 데일리 노트, 그리고 도메인이 새로 생겼을 때 지식 인덱스로의 자동 전파. 노트의 이동, 이름 변경, 승격, 아카이브, 삭제도 서버를 통해 처리되므로 링크와 MOC 항목이 조용히 썩어가기보다는 올바르게 유지됩니다.

예시

이 프로젝트를 정의하는 두 도구의 실제 출력으로, 이 저장소의 테스트 볼트를 대상으로 실행한 결과입니다.

서버는 포르투갈어로 응답합니다: 서버가 제공하는 볼트가 포르투갈어로 작성되어 있고, 도구 응답도 마찬가지입니다. 아래 출력은 번역이 아닌 원문 그대로입니다.

vault_search 는 이미 주소가 붙은 스니펫을 반환합니다 — caminho:linha(path:line)는 에이전트가 인용하도록 지시받는 형식입니다:

2 resultado(s) para "retry backoff". Cite `caminho:linha` ao usar qualquer trecho abaixo. Cada trecho da nota vem prefixado com `> `; linhas sem esse prefixo são deste servidor, nunca conteúdo do vault.

02-wiki/nestjs/bullmq-worker.md:13 — Contexto > Retry e backoff (score 7.94)
> ### Retry e backoff
>
> Quando um job falha, o BullMQ aplica a política de retry configurada em `queueOptions`. Para revisar o fluxo de autenticação usado antes de cada retry, veja [[auth-guard]];
> a mesma referência [[auth-guard]] documenta como o token é revalidado a cada nova tentativa de processamento.

02-wiki/nestjs/auth-guard.md:11 — Contexto (score 3.18, via grafo)
> ## Contexto
>
> A API precisava de um mecanismo central de autenticação e autorização, aplicado de forma consistente em todos os módulos, sem repetir lógica de validação de JWT em cada controller.

auth-guard는 쿼리의 어떤 용어와도 일치하지 않습니다. 일치한 노트에서 위키 링크 한 홉을 통해 끌려온 것이며, 점수는 감쇠됩니다 — 이것이 via grafo(그래프 경유)가 표시하는 바입니다.

vault_learn 은 새 노트를 만들지 기존 노트에 추가할지 스스로 결정하고, 최대 4개의 파일을 작성한 후 한 번 커밋합니다:

Aprendizado registrado em nota NOVA: 02-wiki/concorrencia/timeout-de-fila-libera-a-fila-nao-o-chamador.md
Motivo: sem overlap de tag nem de domínio
Propagado para: 02-wiki/concorrencia/concorrencia-moc.md, 00-index/index-knowledge.md, 04-daily/2026-08-26.md
Commit: sim

Diff (mostre ao usuário):
--- /dev/null
+++ b/02-wiki/concorrencia/timeout-de-fila-libera-a-fila-nao-o-chamador.md
@@ -0,0 +1,15 @@
+---
+tipo: wiki
+tags: [fila]
+criado: 2026-08-26
+---
+
+# Timeout de fila libera a fila, não o chamador
+
+Um slot que expira solta a PRÓXIMA escrita; a chamada original continua esperando o resultado real dela. Resolver a promessa do chamador no timeout reportaria um desfecho que ninguém observou.
+
+**Contexto:** Serializando as tools de escrita do vault-mcp contra si mesmas.
+
+## Solução
+
+## Exemplo
--- /dev/null
+++ b/02-wiki/concorrencia/concorrencia-moc.md
@@ -0,0 +1,16 @@
+---
+tipo: moc
+tags: [concorrencia]
+criado: 2026-08-26
+atualizado: 2026-08-26
+---
+
+# Concorrencia — Mapa de Conteúdo
+
+## Notas
+
+- [[timeout-de-fila-libera-a-fila-nao-o-chamador]] — Um slot que expira solta a PRÓXIMA escrita; a chamada original continua esperando o resultado real dela.
+
+## Relacionados
+
+- [[../../00-index/index-knowledge|índice de conhecimento]]
--- a/00-index/index-knowledge.md
+++ b/00-index/index-knowledge.md
@@ -1,6 +1,6 @@
 ---
 tipo: moc
-atualizado: 2026-02-01
+atualizado: 2026-08-26
 ---
 
 # Índice de Conhecimento
@@ -9,6 +9,7 @@
 
 - [[../02-wiki/nestjs/nestjs-moc|nestjs]] — NestJS, providers, guards, filas
 - [[../02-wiki/docker/docker-moc|docker]] — Dockerfiles, multi-stage, compose
+- [[../02-wiki/concorrencia/concorrencia-moc|concorrencia]] — Um slot que expira solta a PRÓXIMA escrita; a chamada original continua esperando o resultado real dela.
 
 ## Convenções
 
--- /dev/null
+++ b/04-daily/2026-08-26.md
@@ -0,0 +1,10 @@
+---
+tipo: daily
+criado: 2026-08-26
+---
+
+# 2026-08-26
+
+## Capturas
+
+- 11:12 [[timeout-de-fila-libera-a-fila-nao-o-chamador]] (aprendizado)

파일 4개, docs(vault): {titulo} 커밋 하나 — 전체 학습을 되돌리는 것은 그 커밋에 대한 git revert입니다. concorrencia 도메인은 존재하지 않았기 때문에 호출에 confirm_novo_dominio: true가 포함되었고, MOC는 처음부터 구축되었으며, 지식 인덱스에 그 도메인을 가리키는 줄이 추가되었습니다.

Related MCP server: mcp-obsidian-vault

설치

@andreymudri/vault-mcp 로 게시되어 있으므로 실행하기 위해 클론할 필요가 없습니다:

npx @andreymudri/vault-mcp        # no install; npm fetches and runs it
npm i -g @andreymudri/vault-mcp   # or install once, then `vault-mcp`

스코프는 장식이 아닙니다: npm의 단독 vault-mcp는 다른 작성자의 443바이트 네임스페이스 자리표시자이므로, npx vault-mcp는 이 패키지 대신 그들의 패키지를 실행합니다. 스코프 안의 명령은 짧은 이름을 유지합니다 — npx @andreymudri/vault-mcp는 패키지 내부에서 bin을 해석합니다.

클론에서 개발하려면:

npm install
npm run build
npm test
  • Node >= 20 서버 실행용(dist/는 순수 JavaScript), 모든 푸시에서 compat CI 작업이 20에서 빌드 및 스모크 시작을 검증합니다

  • 테스트 스위트 실행은 그 이상이 필요합니다: test/frontmatter.test.ts는 실제 parseFile을 타임존이 고정된 자식 프로세스에서 실행하며, 그 자식은 node <file>.ts입니다 — Node 자체의 타입 스트리핑에 의존합니다. CI는 26을 고정하는데, 이는 개발이 이루어지는 버전입니다

  • 스위트는 19개 파일에 1,155개의 테스트가 있으며 약 10초가 걸립니다. npm test는 먼저 타입체크(pretest)를 실행하고 시계로 스위트를 제한합니다: 멈춘 스위트는 종료 코드 없이 남는 일 없이 124로 종료됩니다

구성

볼트는 환경 변수를 통해 전달됩니다:

VAULT_PATH="/absolute/path/to/vault" npx @andreymudri/vault-mcp

클론에서는 레지스트리 없이 동일하게:

VAULT_PATH="/absolute/path/to/vault" node /absolute/path/to/vault-mcp/dist/server/index.js

/absolute/path/to/vault를 볼트의 루트로 바꾸세요. VAULT_PATH필수입니다. 설정되지 않았거나 디렉터리가 아니면 서버는 코드 1로 종료하고 이유를 stderr에 기록합니다.

Claude Code에 등록

MCP를 다음과 같이 추가합니다:

claude mcp add vault --scope user \
  -e "VAULT_PATH=/absolute/path/to/vault" \
  -e "VAULT_AUTO_PUSH=1" -- \
  npx -y @andreymudri/vault-mcp

클론에서는 -- 뒤에 node /absolute/path/to/vault-mcp/dist/server/index.js를 넣으세요.

볼트의 경로는 절대 경로이며 -e에 단일 KEY=value 쌍으로 들어갑니다 — 쌍 전체를 따옴표로 감싸야 경로에 공백이 있는 볼트도 작동합니다. JSON에는 변수 확장이 없으므로 상대 경로를 넣으면 서버가 시작되지 않습니다. npx-y는 stdio 서버에서 중요합니다: 없으면 첫 실행이 아무도 보고 있지 않은 터미널의 설치 프롬프트에서 멈출 수 있습니다.

--scope user~/.claude.json에 등록하며 도구를 모든 프로젝트에서 사용할 수 있게 만듭니다. 이것이 핵심입니다: 다른 저장소에서 작업하는 동안 볼트가 결정과 패턴에 대한 답을 제공합니다. 플래그가 없으면 기본값은 local(현재 디렉터리만)입니다. claude mcp get vault로 확인하고, 제거하려면 claude mcp remove vault -s user를 사용하세요.

VAULT_AUTO_PUSH

모든 쓰기(vault_write_note, vault_edit_note, vault_learn, vault_move, vault_delete)는 이미 볼트의 git에 커밋합니다. VAULT_AUTO_PUSH=1은 커밋 후 git push를 추가합니다 — 없으면 커밋은 해당 머신에만 남고, 원격을 두 곳 이상에 유지하는 볼트는 조용히 분기됩니다.

기본적으로 꺼져 있습니다. 이 서버가 머신을 떠나는 유일한 작업이기 때문입니다. 켜면:

  • refspec 없이 git push, 브랜치의 업스트림을 따릅니다: 구성되지 않은 저장소는 원격과 브랜치를 추측하는 대신 그 사실을 알려줍니다

  • 항상 경고로 실패하며, 롤백으로는 절대 실패하지 않습니다. 노트는 이미 디스크에 있고 커밋되었습니다. 네트워크가 끊겼다고 그것을 되돌리는 것은 최악의 선택입니다. 도구 응답에 Push: sim|não 줄이 추가되는데, 이는 실제로 푸시가 시도된 경우에만 나타납니다

  • 앞서 나간 원격은 자동으로 해결되지 않습니다. pull, rebase, merge는 사용자의 지식 기반을 다시 쓰는 작업이며, 그것은 사용자의 결정입니다 — 노트 하나를 저장하는 부작용이 아닙니다. 경고는 상황을 명시하고 멈춥니다

  • 30초로 제한되며, GIT_TERMINAL_PROMPT=0이 적용됩니다: stdio 서버에는 자격 증명 프롬프트에 응답할 터미널이 없으므로 프롬프트는 멈춤이 됩니다. 자격 증명은 헬퍼(예: gh auth git-credential) 또는 SSH 키에서 와야 합니다

아홉 가지 도구

도구

입력

호출 시점

vault_search

query (필수); limit, tipo, folder, include_raw (선택)

사용자의 결정, 패턴, 함정 또는 이력에 대해 답변하기 전에. 기본 결과: 6개 스니펫. 01-raw/의 노트는 기본적으로 제외됩니다.

vault_get_note

path (상대 경로, 예: 02-wiki/nestjs/auth-guard.md)

스니펫이 충분하지 않을 때 vault_search 이후, 또는 노트를 편집하기 전에. frontmatter, 해결된 링크 및 끊어진 링크가 포함된 노트를 반환합니다. 본문은 20,000자로 제한됩니다. 더 큰 노트는 […nota cortada em 20000 caracteres]로 표시됩니다.

vault_list

tipo, tags, status, folder (모두 선택)

메타데이터별 노트 목록(예: "어떤 프로젝트가 활성화되어 있나?", "jwt 태그가 있는 노트는 무엇인가?"). 내용을 검색하지 않습니다. 내용 검색은 vault_search를 사용하세요.

vault_backlinks

path (상대 경로)

주제가 얼마나 연결되어 있는지 측정하고, 노트를 인덱싱하는 MOC를 찾고, 변경의 영향을 평가합니다. 링크를 중복 제거합니다: 대상을 두 번 링크하는 노트는 하나의 백링크로 계산됩니다.

vault_write_note

path, content (필수); frontmatter (선택)

전체 노트를 생성하거나 교체합니다. Frontmatter가 보장됩니다. 자동으로 커밋됩니다. 구절을 변경하려면 vault_edit_note를 사용하고, 학습을 기록하려면 vault_learn을 사용하세요.

vault_edit_note

path, old_text, new_text (필수)

노트의 정확한 구절을 교체합니다. 구절이 존재하지 않거나 두 번 이상 나타나면 실패합니다. 이 경우 old_text에 더 많은 맥락을 포함하세요.

vault_learn

titulo, insight, contexto, dominio (필수); projeto, tags, links, confirm_novo_dominio (선택)

세션 중 학습을 기록합니다(아키텍처 결정, 패턴, 함정, 트랩). 저장 위치를 묻지 마세요 — 서버가 결정합니다. 사용자에게 diff를 표시합니다. 02-wiki/에 도메인이 없으면 호출이 실패합니다. 생성하려면 confirm_novo_dominio: true를 사용하세요.

vault_move

from, to (필수); confirm_novo_dominio (선택)

01-raw/에서 이동, 이름 변경, 승격 또는 99-archive/로 아카이브 — to가 전체 경로이므로 네 가지 모두 동일한 호출입니다. 다른 노트를 가리키게 될 모든 링크를 자동으로 수정하고, — resumo를 보존하면서 도메인 MOC 간 항목을 마이그레이션하며, 전체를 함께 커밋합니다. 99-archive/는 소스 대상으로 간주되며, 이것이 아카이브와 아카이브 해제를 가능하게 합니다. 존재하지 않는 대상 MOC에는 confirm_novo_dominio: true가 필요합니다. 일일 노트는 절대 건드리지 않습니다.

vault_delete

path (필수); confirm (선택)

노트를 삭제하고 MOC에서 해당 줄을 제거합니다. 노트에 HEAD의 커밋된 버전이 없으면 — 되돌릴 방법이 없으므로 —, 구조적 노트(MOC, 일일 노트, 인덱스)이거나 99-archive/에 있으면 삭제하지 않고 거부합니다. 다른 노트가 가리키는 노트는 confirm: true가 필요하며, 거부 시 누가 가리키는지 나열합니다. 응답에는 이를 되돌리는 정확한 명령이 포함됩니다.

vault_learn이 결정하는 방법

vault_learn은 제목과 통찰을 결합하여 주제를 검색합니다. 이미 02-wiki/에 있고 직접 BM25로 도달한 (그래프 확장이 아닌) 노트만 학습을 받을 후보입니다. 그러한 후보가 발견되면:

  1. 1.8× 비율: 최상위 결과는 2위보다 최소 1.8배 이상 두드러져야 합니다. 그렇지 않으면 의심이 있어 새 노트를 생성합니다.

  2. 결합적 중복: 최상위 결과는 입력과 태그를 공유하거나 동일한 도메인(02-wiki/<dominio>/)에 있어야 합니다. 중복이 없으면 점수가 높아도 새 노트를 생성합니다.

두 조건이 모두 충족되면 기존 노트의 ## YYYY-MM-DD — Title 섹션 아래에 추가합니다. 그렇지 않으면 02-wiki/<dominio>/에 새 노트를 생성합니다.

이 편향은 의도적입니다: 의심스러울 때는 학습을 잘못된 곳에 묻어두기보다 새 노트를 생성합니다. 나중에 노트를 병합하는 것은 항상 가능하지만, 잃어버린 학습을 복구하는 것은 불가능합니다.

탈출구

세 가지 예외가 최종 대상을 변경할 수 있습니다:

  1. 제목 충돌: 중복 규칙이 아니라고 하지만 해당 이름의 파일이 이미 존재합니다(동일한 slug를 가진 이전 노트). 서버는 어쨌든 추가하고 anexado em <path> por coincidência de título; a checagem de duplicata não indicou essa nota라고 경고합니다. 이렇게 하면 잃어버린 노트가 축적 흐름으로 다시 돌아옵니다.

  2. 중복 대상이 텍스트를 받을 수 없음: 서버가 후보 노트에 추가하기로 결정했지만 편집할 수 없습니다. 서버는 slug에서 파생된 이름으로 새 노트를 생성하고(예: multi-stage.md 대신 multi-stage-cache-de-camadas.md) não foi possível anexar em <path>; aprendizado gravado em <outro-path>라고 경고합니다. 경고는 학습이 기록된 정확한 경로를 명시합니다.

  3. 노트 경로가 비노트에 의해 차단됨: 노트가 생성될 경로(예: 02-wiki/docker/titulo.md)가 FIFO, 심볼릭 링크, 디렉터리 또는 하드 링크(덮어쓸 수 없는 것)로 점유되어 있습니다. 서버는 날짜 접미사가 있는 새 노트를 생성하고(예: titulo-2026-08-25.md) <path> não é uma nota (link, diretório ou dispositivo); aprendizado gravado em <outro-path>라고 경고합니다. 경고는 학습이 기록된 정확한 경로를 명시합니다.

모든 경우에 통찰이 손실되지 않습니다 — 응답은 학습이 어디에 저장되었는지 정확히 알려줍니다.

vault_learn이 작성하는 내용

vault_learn 호출 한 번으로 최대 4개의 파일을 수정할 수 있으며, 모두 docs(vault): {titulo} 메시지의 단일 커밋으로 처리됩니다:

  1. 노트 (02-wiki/<dominio>/<slug>.md): 생성되거나 학습이 추가됩니다. 항상 기록됩니다.

  2. 도메인 MOC (02-wiki/<dominio>/<dominio>-moc.md): 존재하지 않으면 생성됩니다. 호출마다 atualizado:로 업데이트되며, 노트가 새 노트인 경우에만 - [[<slug>]] — <resumo> 줄이 추가됩니다. 내용이 변경된 경우에만 기록됩니다.

  3. 지식 인덱스 (00-index/index-knowledge.md): 도메인이 이전에 존재하지 않았던 경우에만 업데이트됩니다. 내용이 변경된 경우에만 기록됩니다.

  4. 일일 노트 (04-daily/YYYY-MM-DD.md): 존재하지 않으면 생성됩니다. 해당 줄이 이미 없을 때만 캡처 - HH:MM [[<slug>]] (<tipo>, <projeto>)로 업데이트됩니다. 내용이 변경된 경우에만 기록됩니다.

모든 파일은 원자적으로 기록됩니다. 전파가 실패하면(예: 디스크 공간 부족) 파일은 디스크에 남아 있고, 응답에는 업데이트되지 않은 대상을 명시하는 경고가 포함됩니다. git 커밋이 실패하면(예: 저장소가 존재하지 않음) 파일은 디스크에 기록된 상태로 남아 있고, 응답에는 경고가 포함됩니다.

전체 학습을 되돌리는 방법은 다음과 같습니다:

git revert <commit-hash>

순위 조정

다음 매개변수를 변경하려면 전체 테스트 스위트를 통과해야 합니다: npm test. 각 상수는 특정 위치에 고정되어 있습니다:

  • FIELD_WEIGHTS (src/index/inverted-index.ts): heading: 3.0, tags: 2.0, prose: 1.0, code: 0.5. 각 필드의 빈도에 대한 가중치. test/bm25.test.ts에 고정됨.

  • NOTE_TYPE_WEIGHTS (src/index/inverted-index.ts): moc: 0.3, daily: 0.3. MOC 또는 데일리 노트의 최종 점수에 곱해짐. 이 노트들은 짧은 청크에 걸쳐 쿼리를 반복하기 때문에 존재하며, 이 요소가 없으면 MOC가 가리키는 노트를 이겨버린다. test/bm25.test.ts:370-374의 리터럴 단언으로 고정됨; test/golden-queries.test.tstest/retrieval.test.ts는 제거된 경우에만 실패하고, 재조정된 경우에는 실패하지 않는다.

  • GRAPH_DAMPING (src/retrieval/budget.ts): 0.4. 그래프 이웃(연결된 노트)의 점수에 곱해짐. 여러 홉이 아니라 한 홉. test/retrieval.test.ts:522에 고정됨.

  • K1B (src/index/bm25.ts): 1.20.75. BM25 파라미터. test/bm25.test.ts:232-233에 고정됨.

  • DUPLICATE_SCORE_RATIO (src/write/learn.ts): 1.8. 추가(append)를 위한 최상위 히트와 차순위 간의 최소 비율. test/learn.test.ts:336에 고정됨.

전체 스위트 실행:

npm test

보안 보장

다음에 대한 쓰기는 거부됨:

  • 볼트 외부의 경로

  • .git/, .obsidian/, node_modules/, _templates/99-archive/의 경로

  • 심볼릭 링크(쓰기 전에 확인됨)

  • 하드 링크

단일 서버 인스턴스 내에서, 두 개의 동시 vault_learn 또는 vault_write_note 호출은 처음부터 인터리브되지 않는다: 각 쓰기는 이전 쓰기가 끝날 때까지 대기한다. 쓰기가 중단되면(예: git 차단), 60초 타임아웃은 호출자가 아닌 다음 쓰기를 위해 큐를 해제한다 — 이전 호출은 실제 결과를 계속 기다린다. 다음 쓰기가 시작되면 둘 다 실행 중일 수 있다 — 호출은 독점성이 보장되지 않았다는 경고를 받게 된다. 이는 Obsidian에서의 동시 쓰기, 두 번째 서버 인스턴스, 또는 볼트 내 git checkout으로부터는 보호하지 않는다.

검색 및 검색

검색은 2~3단계 제목 수준의 청크에 대해 BM25를 실행하며, 산문, 태그 및 제목을 서로 다른 가중치로 다룬다. 쿼리의 어떤 용어도 어떤 노트와 일치하지 않으면 유사한 용어(레벤슈타인 거리 ≤ 2)를 제안하려고 시도한다.

순수 BM25 검색 후, 하나의 위키 링크 홉만큼 확장한다: 히트한 노트의 이웃은 소스 점수의 GRAPH_DAMPING 배를 상속받는다.

모든 결과는 caminho:linha(경로:줄)를 인용한다 — 이것이 노트의 실제 주소다. 노트 스니펫은 볼트 콘텐츠와 서버 라인을 구분하기 위해 vault_search에서 > 접두사가 붙는다.

볼트 구조

디렉토리 규칙:

  • 00-index/: 지식 인덱스 및 루트 MOC

  • 01-raw/: 원시 캡처 및 클리핑(기본적으로 검색에서 제외)

  • 02-wiki/: 도메인별로 구성된 지식(nestjs/, docker/ 등)

  • 03-projects/: 프로젝트 노트

  • 04-daily/: 데일리 노트(YYYY-MM-DD.md)

  • _templates/: Obsidian 템플릿(인덱싱에서 무시됨)

  • 99-archive/: 보관된 노트(읽기 가능, 쓰기 불가)

알려진 제한 사항

이 서버가 수행하지 않는 세 가지가 있으며, 각각 간과된 것이 아니라 선택된 것이다:

  • 99-archive/로의 보관은 소스 MOC의 노트 항목에서 — summary를 잃는다. vault_move는 원본 MOC에서 해당 줄을 제거하고 다시 삽입할 대상 MOC가 없으며, 아카이브는 쓰기 금지 영역이므로 텍스트를 둘 곳이 없다. 보관 해제는 원래 항목이 아닌 빈 - [[slug]]를 재생성한다. 대안들 — 이동된 노트의 자체 frontmatter에 요약을 저장하거나, 사이드 인덱스에 저장하는 것 — 모두 손실보다 비용이 더 든다. 이 작업이 절대 하지 않는 것은 요약을 지어내는 것이다: 원본 줄이 없으면 항목은 짧고 진실하게 나온다.

  • frontmatter에만 존재하는 위키 링크는 vault_move에 의해 다시 쓰여지지 않는다. 후보 노트는 본문에서 선택되며, 링크 그래프도 본문에서 구축되므로, 이 필터가 건너뛰는 노트는 vault_backlinks도 그 가장자리를 가지지 않는 노트다. 스캐너를 넓히지 않고 다시 쓰기를 넓히면 더 나쁜 비대칭이 발생한다: 어떤 읽기 도구도 볼 수 없는 수정된 링크.

  • vault_get_note는 노트 본문을 원시 상태로 반환한다. 이스케이프하면 제어 문자를 가진 노트에 대해 읽기-후-편집이 조용히 깨질 수 있는데, vault_edit_noteold_text를 파일의 정확한 하위 문자열로 일치시키기 때문이다. 줄 단위 주장을 하는 표면들 — vault_search 스니펫과 diff — 은 정화된다.

지금까지 제기된 16개의 후속 조치는 모두 수정되었다 — 이벤트 루프를 ~5초 동안 차단한 별칭 frontmatter, 읽기 경로에서 인덱싱된 하드 링크, 프로세스 간 쓰기 경쟁을 포함한다. docs/followups.md는 기록을 유지한다: 각 항목에 대해 이를 특징지은 측정값, 적용된 수정 및 이를 고정하는 테스트, 그리고 위 각 수용에 대한 전체 근거가 포함된다.

개발

코드 변경 후:

npm run build     # Compiles TypeScript (src/ only, emits dist/)
npm run typecheck # tsc over src/ AND test/, without emitting
npm test          # Runs the typecheck (pretest) and then the vitest suite
npm run smoke     # Starts the built dist/ and demands the nine tools over stdio
npm run dev       # Watch mode (if needed)

빌드 tsconfig.jsonsrc/만 포함한다 — 생성물은 테스트를 컴파일하지 않는다. tsconfig.test.jsonnoEmit으로 둘 다 포함하며, npm의 pretest는 스위트 전에 이를 실행한다: 선언한 implements 인터페이스를 충족하지 못하는 테스트 페이크는 런타임이 아닌 타입체크에서 실패한다.

전체 스위트는 ~10초가 걸린다. 일부 테스트는 긴 실행 작업을 시뮬레이션하기 위해 FIFO를 사용한다; 모두 자체적으로 쓰기 끝을 연다(withFifoWatch), 따라서 러너의 타임아웃에 의존하는 대신 몇 초 안에 실패한다. npm testscripts/test.mjs를 통해 실행되며, 이는 스위트를 시계로 제한하고(15분, VAULT_MCP_TEST_TIMEOUT_MS) 프로세스 그룹을 종료한다: 중단된 스위트는 종료 코드 없는 무기한 중단이 아닌 종료 124가 된다.

npm run smoke는 스위트가 될 수 없는 검사다: 컴파일된 dist/server/index.js를 일회용 볼트에 대한 프로그램으로 실행하고, MCP 핸드셰이크를 완료하며 tools/list가 정확히 아홉 개의 도구로 응답할 것을 요구한다. 이는 진입점이 라이브러리임을 결정하고 아무것도 시작하지 않는 것을 다룬다 — 셸에 대한 깨끗한 종료 0, 클라이언트에 대한 영원한 대기 — 그리고 engines.node >= 20을 검증된 주장으로 만드는 것이다: CI는 고정된 26뿐만 아니라 Node 20에서도 실행하는데, 스위트 자체는 20에서 실행할 수 없지만(test/frontmatter.test.ts는 런타임의 타입 스트리핑에 의존) 컴파일된 JavaScript는 실행할 수 있기 때문이다.

커밋 메시지와 서버 자체의 사용자 대상 문자열 — 도구 설명, 오류 메시지, diff 내부의 산문 — 은 포르투갈어(BR)로 작성된다: 이 서버가 제공하는 볼트는 포르투갈어 지식 베이스이며 그 독자는 포르투갈어를 사용하는 모델이다. 코드 주석과 docblock은 영어로 작성되며, src/index/bm25.ts는 첫 패스에서 포르투갈어로 남겨졌다.

라이선스

MIT © 2026 Andrey Mudri

A
license - permissive license
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 Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides AI agents with direct filesystem access to an Obsidian vault for note management, task orchestration, context persistence, and git synchronization.
    67
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides a durable, Obsidian-compatible knowledge base for agents using markdown notes and wikilinks. Enables agents to store, retrieve, and interlink knowledge persistently, with tools for writing, searching, and managing a graph of notes.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.

  • Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…

  • Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.

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/andreymudri/vault-mcp'

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