corpus-mcp
corpus-mcp
에이전트가 문서 디렉토리를 키워드 검색할 수 있게 해주는 MCP 서버입니다. 폴더를 지정하기만 하면 바로 동작합니다 — 모델 다운로드도, API 키도, GPU도, 곁에 실행되는 벡터 데이터베이스도 필요 없습니다. 의존성은 단 하나, MCP SDK뿐입니다.
pip install -e .
corpus-mcp --root ./docs serve흥미로운 부분은 검색 자체가 아니라 도구 설계입니다. 에이전트가 검색 도구로 실제로 무엇을 할 수 있는지, 그리고 무엇이 검색 도구를 컨텍스트 창을 태워버리는 도구가 아니라 유용한 도구로 만드는지에 관한 내용입니다.
10초 만에 사용해 보기
$ make demo
1. reference/glossary.md (score 1.973, f700ededcfdd:0)
# Glossary
**Extraction** — the process of dissolving soluble compounds out of ground
coffee. Under-extraction tastes sour and thin; over-extraction tastes bitter …
2. guides/brewing.md (score 1.774, 71c6f092dbcb:0)
# Pour-over brewing
…그 질의는 *"왜 내 커피는 신맛이 나는가"*였습니다. 문서에는 tastes라고 쓰여 있고 질의는 taste라고 했으며, 실제로 답이 되는 용어 설명 항목이 첫 번째로 순위가 매겨졌습니다. 둘 다 의도적인 것입니다. 아래를 참조하세요.
도구
도구 | 용도 |
| 매치된 부분을 중심으로 한 짧은 스니펫으로 순위가 매겨진 구절 반환, 각각 |
| 한 구절의 전체 텍스트와 이웃 구절 반환 |
| 색인된 항목과 문서별 크기 반환 |
문서는 MCP 리소스로도 corpus://<relative-path>에 노출됩니다.
논쟁할 가치가 있는 설계 결정
검색과 가져오기는 별개의 도구입니다. 전체 청크를 반환하는 search 하나만 두는 것은 작성하기는 더 간단하지만 사용하기에는 훨씬 나쁩니다. 각각 1,200자인 결과 10개는 에이전트가 원하는 것을 고르기도 전에 컨텍스트 창 대부분을 소모합니다. 그래서 search는 선별에 충분한 스니펫을 반환하고, fetch는 선택한 결과를 요청에 따라 확장합니다. 에이전트는 세부 정보가 가치 있다고 판단한 곳에서만 세부 정보에 비용을 지불합니다.
스니펫은 청크의 시작이 아니라 일치 지점을 중심으로 합니다. 처음 N개 문자를 반환하는 방식은 일치하는 문장이 대개 중간에 있기 때문에 끊임없이 실패합니다. 에이전트는 관련 없는 도입부를 보고 좋은 결과를 버리거나 확인하려고 전부 가져옵니다. 스니펫 창은 질의어가 최대한 많이 포함되도록 선택됩니다.
모든 제한은 서버 측에서 강제됩니다. 도구 출력은 컨텍스트 창에 직접 들어가므로, 제한이 없는 도구는 그것을 호출하는 대상에 대한 서비스 거부 공격입니다. 10,000개 결과를 요청하는 호출자가 바로 상한이 존재하는 이유이므로, 제한은 신뢰가 아니라 집행됩니다. 출력이 잘리면 응답이 그 사실을 알려주므로, 에이전트는 모든 것을 봤다고 가정하는 대신 질의를 좁힐 수 있습니다.
빈 결과는 스스로 설명합니다. 빈 목록 하나만 있으면 막다른 길입니다. 응답은 청크 수와 문서 수를 알려주어 "질의가 빗나갔다"와 "아무것도 색인되지 않았다"를 구분합니다 — 다음 행동이 서로 다른 두 상황입니다.
오래된 식별자는 오류가 아니라 예상된 결과입니다. 문서가 편집되면 청크 id가 바뀌므로, 긴 세션의 앞부분에서 얻은 id는 유효하지 않게 될 수 있습니다. fetch는 정확히 그 사실을 말하고 에이전트에게 다시 검색하라고 안내합니다.
청크를 합칠 때 중복은 제거됩니다. 어떤 구절도 경계에서 잘리지 않도록 청크가 겹치지만, 그 중복을 그대로 돌려주면 에이전트가 같은 문장을 두 번 읽고 반복을 강조로 오해할 수 있습니다. 청크는 절대 오프셋을 지니므로 중복은 문자열 일치가 아니라 위치로 제거됩니다.
임베딩이 아니라 BM25. 에이전트가 이미 어느 정도 아는 말뭉치를 탐색하면서 던지는 키워드성 질의에는 어휘 검색이 강력하며, 에이전트 루프에서 가장 중요한 특성을 지닙니다: 빠르고, 조용히 비용이 발생하지 않습니다. 의미 검색은 유용하기 위한 전제 조건이 아니라 가치 있는 추가 기능입니다.
실제 스테머가 아닌 가벼운 어간 처리. 복수형과 흔한 동사 어미를 접어서 tastes가 taste와 일치하게 만듭니다. 완전한 Porter 구현은 백 줄가량에 유지보수 부담이 되며, 그 긴 꼬리(operational → oper)는 짧은 질의에서 도움이 되기보다 해가 될 가능성이 비슷합니다. 색인과 질의는 하나의 토크나이저를 공유합니다. 둘 사이에 조금이라도 차이가 있으면 조용히 재현율을 떨어뜨리기 때문입니다.
보안
서버는 루트 디렉토리를 가리키며 그 밖을 절대 읽지 않습니다. 이는 보기보다 중요합니다: 도구 인자는 모델 출력에서 오므로 문서 식별자는 신뢰할 수 없는 입력이며, ../../.ssh/id_rsa는 혼란스럽거나 적대적인 에이전트가 결국 요청하게 될 것입니다.
경계를 넘는 모든 경로는 비교 전에 심볼릭 링크를 해석하는 단일 격리 검사를 거칩니다. 루트 안의 심볼릭 링크가 루트 밖을 가리키는 경우에는 해석되지 않은 경로에 대한 접두어 검사를 무력화합니다. 절대 경로처럼 보이는 인자는 실제 절대 경로가 아니라 루트를 기준으로 한 상대 경로로 해석됩니다. 리소스 URI도 도구 인자와 동일한 처리를 받습니다.
UTF-8이 아닌 파일, 지나치게 큰 파일, 벤더 디렉토리(.git, node_modules, …)는 잡음으로 색인하지 않고 건너뜁니다.
클라이언트에 연결하기
Claude Desktop 또는 모든 MCP 호스트는 서버를 하위 프로세스로 실행합니다:
{
"mcpServers": {
"my-docs": {
"command": "corpus-mcp",
"args": ["--root", "/absolute/path/to/docs", "serve"]
}
}
}말뭉치는 디스크에서 변경되면 다시 읽히므로, 세션 중에 편집된 파일은 재시작 없이 검색 가능해집니다. 재색인은 매 호출 때마다 전체를 다시 구축하는 대신 수정 시간을 기준으로 증분 방식으로 이루어집니다.
개발
make install # server plus dev tools
make demo # one query against the example corpus
make test # 89 tests, no network required
make smoke # launch the installed server as a subprocess and exercise it
make lint서로 다른 실패를 잡아내는 두 계층의 테스트:
tests/test_server.py는 실제 MCP 클라이언트를 프로세스 내의 실제 서버에 연결합니다. 검증하는 것은 내부의 Python 함수가 아니라 와이어 동작(도구 스키마, 구조화된 결과, 오류 형태)입니다. 함수는 올바르지만 도구 표면이 잘못된 서버도 여전히 고장난 것이며, 이 수준에서만 그 문제를 잡아냅니다.scripts/stdio_smoke.py는 설치된 콘솔 스크립트를 하위 프로세스로 실행하고 호스트가 그렇듯 stdio를 통해 JSON-RPC로 통신합니다. 패키징, 엔트리 포인트, 전송을 포괄합니다 — 무언가가 stdout에 기록하여 프로토콜 스트림을 손상시키는 전형적인 실패를 포함합니다.
제한 사항
어휘 검색만 가능합니다. 문서와 어휘를 전혀 공유하지 않는 질의는 문서를 찾지 못합니다. 동일한 도구 표면 뒤에 임베딩 백엔드를 추가하는 것이 명백한 다음 단계입니다.
텍스트 형식만 지원합니다 —
.md,.txt,.rst,.csv,.json,.yaml등. PDF나 DOCX 추출은 없습니다.전체 인덱스가 메모리에 상주하며 말뭉치가 변경되면 전체를 다시 구축합니다. 이 서버가 대상으로 하는 수천 개 문서 규모에는 적합하지만, 수백만 개 규모의 말뭉치는 파일 단위로 갱신되는 실제 인덱스가 필요합니다.
영어만 지원합니다. 불용어 목록과 접미사 접기가 모두 영어를 전제로 합니다.
루트 외부로의 접근 제어는 없습니다. 루트 아래의 모든 파일은 서버에 연결된 모든 대상에 보입니다.
라이선스
MIT. Aion Innovations 제작.
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 Connectors
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Agentic search over your Dewey document collections from any MCP-compatible client.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
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/mmorrisj/corpus_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server