Skip to content

Repository files navigation

test-mcp — Local Docs MCP Sample

키워드 기반으로 로컬 docs/ 폴더의 마크다운 문서를 검색해 LLM 에이전트(Claude Code / Codex / Cursor 등)에게 반환하는 로컬 MCP 서버 샘플.

동작 개요

  1. 에이전트가 get_design_docs, get_react_design_guide, get_api_docs, get_test_docs 중 하나를 호출하면서 topic 키워드를 넘긴다.
  2. 서버는 DOCS_PATH 아래의 해당 도메인 폴더(design/, react-design/, api/, testing/)에서 .md 파일을 수집한다.
  3. 키워드 + 동의어 + 우선순위 패턴으로 파일을 랭킹해 상위 8개(curated) 또는 매칭된 전체(full)를 본문과 함께 텍스트로 반환한다.

랭킹 점수 구성:

  • priority pattern: 도메인별로 미리 정의한 핵심 파일 경로일수록 가산점
  • filename match: 파일명에 키워드가 들어가면 큰 가산점
  • path match: 폴더 경로에 키워드가 들어가면 중간 가산점
  • content occurrences: 본문 키워드 등장 횟수 (최대 10회까지)
  • exact phrase: topic 전체 문장이 본문에 그대로 등장하면 추가 가산점

디렉토리 구조

tools/test-mcp/
├── package.json
├── tsconfig.json
├── install.sh / install.cmd          # pnpm install + tsc build
├── register-codex.sh / register-codex.cmd  # Codex CLI에 MCP 등록
├── src/
│   ├── index.ts                      # MCP 서버 진입점 (StdioServerTransport)
│   ├── search.ts                     # 마크다운 수집·랭킹·포맷팅
│   └── scripts/
│       └── query-regression.ts       # 랭킹 회귀 테스트
└── README.md

빌드

cd tools/test-mcp
./install.sh         # pnpm install + pnpm build
# Windows: install.cmd

빌드 결과는 dist/에 생성된다.

직접 실행 (디버깅용)

DOCS_PATH=/absolute/path/to/docs node dist/index.js

stdio로 MCP 요청을 받는다. 단독 실행은 LLM 호스트가 stdin/stdout으로 JSON-RPC를 주고받을 때만 의미가 있다.

LLM 에이전트에 등록

Claude Code (사용자 또는 프로젝트 settings.json)

{
  "mcpServers": {
    "local-docs-guide": {
      "command": "node",
      "args": ["/absolute/path/to/tools/test-mcp/dist/index.js"],
      "env": {
        "DOCS_PATH": "/absolute/path/to/docs"
      }
    }
  }
}

Codex CLI

./register-codex.sh
# 등록 확인
codex mcp get local-docs-guide

DOCS_PATH 환경변수가 미리 설정돼 있지 않으면 <repo>/docs를 기본값으로 사용한다.

Cursor / 기타 MCP 호스트

command = node, args = ["dist/index.js"], env.DOCS_PATH = ... 형태로 등록하면 동작한다.

docs 폴더 레이아웃 (예시)

docs/
├── design/
│   ├── foundation/invariants.md
│   ├── architecture/overview.md
│   ├── architecture/source-structure.md
│   └── architecture/state-management.md
├── react-design/
│   ├── foundation/invariants.md
│   ├── architecture/overview.md
│   ├── architecture/source-structure.md
│   ├── architecture/state-management.md
│   └── components/overview.md
├── api/
│   ├── foundation/invariants.md
│   ├── architecture/overview.md
│   ├── endpoints/overview.md
│   └── auth/overview.md
└── testing/
    ├── overview.md
    ├── unit-testing.md
    ├── integration-testing.md
    └── e2e-testing.md

위 경로들은 src/search.tscreateDomainConfigs()에서 도메인별 priorityPatterns / defaultEntryPaths로 정의돼 있다. 본인 프로젝트의 폴더 구조에 맞게 자유롭게 수정하면 된다.

새 도메인 추가하기

  1. src/search.tscreateDomainConfigs() 에 새 키를 추가한다.

    get_runtime_docs: {
        folderPath: path.join(docsPath, 'runtime'),
        priorityPatterns: ['overview.md', 'lifecycle.md'],
        defaultEntryPaths: ['overview.md']
    }
  2. src/index.tstools 배열에 동일한 이름으로 tool 정의를 추가한다 (name, description, inputSchema).

  3. pnpm build 후 MCP 호스트를 재시작한다.

동의어 / 정렬 튜닝

src/search.ts 상단:

  • QUERY_STOP_WORDS — 검색 시 무시할 흔한 단어
  • TOKEN_SYNONYMS — 키워드 → 유사어 매핑 (예: hooksubscription)

도메인 용어가 많은 프로젝트라면 여기 동의어를 추가하면 검색 정확도가 크게 올라간다.

랭킹 회귀 테스트

DOCS_PATH=/absolute/path/to/docs pnpm test:queries

src/scripts/query-regression.tscases 배열에 (tool, topic, expected[]) 쌍을 추가하면, 향후 동의어/우선순위를 바꿔도 기대 문서가 상위에 잡히는지 자동 검증할 수 있다.

라이선스 / 출처

이 샘플은 사내 프로젝트에서 사용 중이던 docs 검색 MCP 서버를 도메인 종속 명칭을 제거하고 공개용으로 정리한 것이다. 자유롭게 fork/수정하여 사용하면 된다.

About

Local MCP server sample that serves markdown docs to LLM agents (Claude Code / Codex / Cursor) via keyword ranking

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages