Skip to main content
Glama

mcp-project-helper

AI 프로그래밍 어시스턴트 — 특히 Claude Code — 에게 단일 프로젝트 디렉터리 작업을 위한 작고 안전한 도구(tools) 세트(파일 검색, 파일 읽기, 로컬 문서 검색, 사전 승인된 검사(테스트) 실행)를 제공하는 최소 MCP(Model Context Protocol) 서버입니다.

프로젝트는 단계적으로 구현되었습니다(Stage 0 → Stage 3, 프롬프트 히스토리는 PROMPTS.md에 있음). 현재 단계는 Stage 3: 마무리입니다. 네 가지 tool 모두 구현되었고 테스트로 검증되었으며(Stage 1), 서버는 Claude Code에 연결되어 Claude Code CLI를 통한 실제 요청으로 수동 검증되었습니다(Stage 2–3, 증거는 evidence/에 있음).

프로젝트 소개

프로젝트는 어시스턴트에게 shell에 대한 직접 접근이나 무제한 파일 시스템 접근을 제공하는 대신, 네 가지 tool로 구성된 좁고 감사하기 쉬운 표면을 제공합니다:

  • search_project_files — 프로젝트 루트로 제한된 텍스트 검색.

  • read_project_file — 프로젝트 루트로 제한된 단일 파일 읽기.

  • get_docs — 이 저장소의 docs/에 있는 로컬 문서 검색.

  • run_project_check — 화이트리스트에 있는 검사(현재는 tests) 실행. 임의의 shell 명령은 절대 실행하지 않습니다.

이것은 학습용 프로젝트(과제)입니다. 모든 가능한 사용 사례를 다루는 것이 목표가 아니라, MCP 서버의 종단 간, 정직하게 문서화된 예시를 보여주는 것이 목표입니다: 골격과 보안 프리미티브(Stage 0)부터, 실제 tool 구현(Stage 1), IDE 에이전트와의 통합 및 재현 가능한 실제 호출 증거(Stage 2–3)까지.

Related MCP server: GPT Commander

MCP란 무엇이며 에이전트 연결은 어떻게 작동하나요

MCP(Model Context Protocol) — JSON-RPC 기반의 개방형 프로토콜로, AI 어시스턴트(클라이언트/호스트, 예: Claude Code)가 별도 프로세스(MCP 서버)가 제공하는 외부 도구(tools)를 발견하고 호출하는 방법을 설명합니다. 어시스턴트가 호스트의 shell, 네트워크 또는 파일 시스템에 직접 접근할 수 없도록 합니다.

이 프로젝트에서는 stdio 전송을 사용합니다. 이는 로컬 도구에 가장 간단하고 가장 일반적인 방식입니다:

  1. 호스트(Claude Code)는 자체 MCP 구성을 읽고(.mcp.json) 지정된 명령/인수와 환경 변수로 서버를 일반 로컬 하위 프로세스로 시작합니다.

  2. 호스트와 서버는 이 하위 프로세스의 stdin/stdout을 통해 JSON-RPC 메시지를 교환합니다(따라서 stdout은 프로토콜 전용으로 예약되어야 합니다 — "로깅 및 디버깅" 섹션 참조).

  3. 호스트는 initialize()를 호출합니다 — 서버는 자체 이름/버전(mcp-project-helper 0.1.0)과 기능으로 응답합니다.

  4. 호스트는 list_tools()를 호출합니다 — 서버는 등록된 tools 목록을 이름, 설명, MCP SDK가 함수 시그니처에서 생성한 입력 매개변수의 JSON Schema(inputSchema)와 함께 반환합니다.

  5. 사용자(또는 모델 자체)가 tool 중 하나를 호출하기로 결정하면 호스트는 call_tool(name, arguments)를 보냅니다. 서버는 해당 Python 함수를 실행하고 구조화된 결과(아래 "Tool 출력 계약" 참조) 또는 tool 수준 오류를 반환합니다.

  6. 네트워크 포트는 열리지 않습니다. 서버의 수명 주기는 전적으로 호스트가 시작한 하위 프로세스에 바인딩됩니다 — 호스트가 연결을 닫으면 하위 프로세스가 종료됩니다.

여기에는 LLM/AI API(OpenAI, Anthropic 등) 호출이 없습니다. 이 서버는 클라이언트(Claude Code)가 호출하는 tools를 제공만 합니다. get_docs의 "검색"은 embeddings/벡터 DB 없이 Markdown 섹션에 대한 단순한 결정적 부분 문자열 일치입니다. 서버를 실행하는 데 API 키가 필요하지 않습니다.

이 서버에서 tool로 간주되는 것

Tool@mcp.tool()로 데코레이션된 일반 Python 함수로, JSON 직렬화 가능한 인수를 받고 dict[str, Any]를 반환합니다. MCP SDK는 자동으로:

  • 함수 인수의 시그니처와 타입 어노테이션에서 inputSchema(JSON Schema)를 생성합니다 — 이 스키마를 수동으로 별도로 설명할 필요가 없습니다.

  • 반환 타입 어노테이션 -> dict[str, Any]를 tool의 구조화된 출력(outputSchema/structuredContent)으로 변환합니다 — 아래 "Tool 출력 계약" 참조.

  • tool 함수 내부의 처리되지 않은 Python 예외를 MCP 세션 자체를 중단하지 않고 tool 수준 오류(CallToolResult.is_error = True)가 있는 구조화된 결과로 변환합니다.

네 가지 등록은 모두 server.py:37-58에 함께 있습니다. 각각은 MCP에 노출되는 얇은 래퍼(docstring이 모델에 보이는 tool 설명이 됨)로, 호출을 tools/*.py의 실제 구현에 위임하여 프로토콜 수준 시그니처를 로직과 분리합니다.

스택

  • Python 3.14 (pyproject.tomlrequires-python = ">=3.10" — 이는 사용된 MCP SDK의 실제 하한선이며 3.14에서만 작동한다는 주장이 아닙니다).

  • 공식 MCP Python SDK(mcp 패키지, 설치 버전 2.0.0) — 서버 프레임워크(mcp.server.MCPServer), tool 등록(@mcp.tool()), stdio 전송(mcp.run(transport="stdio"))을 제공합니다.

  • pytest — 테스트 스위트를 위한 유일한 dev 의존성.

  • LLM/AI API 통합이 없고 네트워크 전송이 없습니다(HTTP/SSE 미구성) — 이전 섹션 참조.

아키텍처

src/mcp_project_helper/
  server.py        точка входа: создаёт MCPServer, регистрирует tools, запускает stdio
  config.py        корень проекта / корень docs / настройки логирования / whitelist проверок / лимиты
  security.py      resolve_within_root() — единый шлюз ограничения путей
  logging_setup.py логирование в stderr (+ опционально файл), не затрагивая stdout
  tools/
    search_project_files.py   поиск текста в пределах корня проекта
    read_project_file.py      чтение одного файла в пределах корня проекта
    get_docs.py                поиск по секциям markdown в docs/
    run_project_check.py       запуск подпроцесса из белого списка

파일로 작업하는 각 tool은 경로를 열기 전에 security.resolve_within_root(root, relative_path)를 통과합니다. config.py는 환경 변수 MCP_PROJECT_HELPER_ROOT(기본값 ./demo_project)에서 프로젝트 루트를 정의하므로 코드 변경 없이 서버를 모든 프로젝트로 지정할 수 있습니다.

구현된 MCP tools

search_project_files(query, path=".", max_results=50)

path 아래의 텍스트 파일(프로젝트 루트 기준, 기본값은 전체 루트)에서 query 부분 문자열의 정확한 일치를 재귀적으로 검색합니다. config.IGNORED_DIR_NAMES(.git, .venv, __pycache__, node_modules, ...)의 디렉터리와 모든 *.egg-info 디렉터리를 건너뜁니다. 파일은 바이너리 콘텐츠(처음 4KB의 NUL 바이트 또는 잘못된 UTF-8)를 확인하고 오류를 발생시키는 대신 조용히 건너니다. 루트 외부의 디렉터리나 파일에 대한 심볼릭 링크를 절대 따라가지 않습니다 — 각 후보 경로는 디렉터리 심볼릭 링크를 따르지 않는 표준 os.walk 동작에 추가로 resolve_within_root를 통해 확인됩니다.

max_resultsconfig.SEARCH_RESULTS_CAP(200) 값으로 상한이 제한됩니다. config.SEARCH_MAX_LINE_CHARS(300)보다 긴 일치 줄은 잘립니다. config.SEARCH_MAX_FILE_BYTES(2MB)보다 큰 파일은 스캔되지 않고 건너니다.

구현: tools/search_project_files.py:41-130.

read_project_file(path)

path(프로젝트 루트 기준)의 단일 텍스트 파일을 읽습니다. 디렉터리, 존재하지 않는 파일, 바이너리 콘텐츠(NUL 바이트 또는 잘못된 UTF-8)를 거부합니다. 콘텐츠는 config.READ_MAX_FILE_BYTES(200KB) 값으로 제한됩니다 — 더 큰 파일은 거부되지 않고 잘려서 반환됩니다.

구현: tools/read_project_file.py:25-69.

get_docs(query=None, max_results=10)

Markdown 헤딩으로 섹션으로 분할된 docs/*.md(재귀적)를 검색합니다. query가 있으면 헤딩 또는 본문에 검색어(대소문자 구분 없음)가 포함된 섹션을 각각 원본 파일과 헤딩과 함께 반환합니다. query가 없으면 파일당 하나의 섹션 목록 — 어떤 문서가 존재하는지에 대한 목록을 반환합니다. config.get_docs_root()로만 제한됩니다 — 프로젝트 루트로는 절대 제한되지 않습니다.

max_resultsconfig.DOCS_RESULTS_CAP(50) 값으로 상한이 제한됩니다. 스니펫은 config.DOCS_MAX_SNIPPET_CHARS(800자) 값으로 제한됩니다.

구현: tools/get_docs.py:58-114.

run_project_check(check_name)

화이트리스트의 검사를 실행합니다. check_name은 아무것도 실행되기 전에 config.ALLOWED_CHECKS에서 검색됩니다 — 알 수 없는 이름은 즉시 오류를 발생시키고 하위 프로세스는 절대 시작되지 않습니다. 화이트리스트의 argv는 subprocess.run(argv, shell=False, cwd=<프로젝트 루트>, timeout=...)를 통해 실행됩니다: shell 없이, 고정된 작업 디렉터리로, 호출 측에서 명령줄에 아무것도 추가되지 않습니다.

구현: tools/run_project_check.py:32-90.

화이트리스트

ALLOWED_CHECKS = {
    "tests": [sys.executable, "-m", "pytest", "-q"],
}

config.py:55-57에 정의되어 있습니다. sys.executable(단순 문자열 "pytest"가 아님)은 PATH에 무엇이 먼저 있든 검사가 항상 서버와 동일한 인터프리터/환경으로 실행되도록 사용됩니다. 여기에는 의도적으로 lint 항목이 없습니다. 이 저장소에는 ruff 의존성이나 구성이 없으므로 "lint" 검사를 연결하는 것은 허구이거나 속임수일 것입니다. 나중에 추가할 수 있습니다 (config.ALLOWED_CHECKS["lint"] = [sys.executable, "-m", "ruff", "check", "."]), ruff가 실제 구성과 함께 프로젝트의 실제 의존성이 될 때 — 화이트리스트 메커니즘은 다른 코드 변경 없이 이미 이를 지원합니다.

타임아웃(config.CHECK_TIMEOUT_SECONDS, 기본 60초)과 출력 볼륨 제한(config.CHECK_MAX_OUTPUT_CHARS, 기본 스트림당 20,000자)이 각 검사 실행에 적용됩니다.

Tool 출력 계약

각 tool은 -> dict[str, Any] 어노테이션이 있는 함수에서 일반 Python dict를 반환합니다. MCP SDK는 이를 자동으로 tool의 구조화된 출력으로 인식합니다(CallToolResult.structured_content를 채우고 outputSchema를 출력합니다) — 결과를 JSON 문자열로 수동 직렬화하는 곳은 없습니다. 오류 상황(잘못된 입력, 경로 이탈, 알 수 없는 검사, 파일 없음, 바이너리 콘텐츠 등)은 dict를 반환하는 대신 Python 예외를 발생시킵니다. SDK는 이를 자동으로 tool 수준 오류(CallToolResult.is_error = True)가 있는 결과로 변환합니다. 유일한 예외는 검사 타임아웃입니다. 이는 성공적으로 시작된 검사 실행의 합법적인 결과이지 입력 오류가 아니므로 예외를 발생시키는 대신 구조화된 dict {"status": "error", ...}로 반환됩니다.

search_project_files

{
  "status": "success",
  "query": "apply_discount",
  "path": ".",
  "matches": [
    {"file": "demo_app/services.py", "line": 12, "text": "def apply_discount(order: Order, percent: float) -> float:"}
  ],
  "count": 4,
  "truncated": false
}

read_project_file

{
  "status": "success",
  "file": "demo_app/models.py",
  "content": "...",
  "size": 397,
  "truncated": false
}

get_docs

{
  "status": "success",
  "query": "whitelist",
  "results": [
    {"file": "architecture.md", "heading": "Whitelist", "snippet": "..."}
  ],
  "count": 1,
  "truncated": false
}

run_project_check

{
  "status": "success",
  "check_name": "tests",
  "exit_code": 0,
  "stdout": "...",
  "stderr": "",
  "truncated": false
}

타임아웃 시: {"status": "error", "check_name": ..., "error": "check timed out after 60s", "exit_code": null, "stdout": "...", "stderr": "...", "truncated": ...}.

위의 필드 이름과 status/count/truncated 규칙은 구현 세부 사항이 아니라 향후 안정적인 계약으로 간주됩니다.

보안 제한 사항

  • 경로 제한: security.resolve_within_root (security.py:19-50)은 절대 경로, ..를 통한 우회(어느 깊이든), NUL 바이트, 그리고 설정된 루트 밖으로 이어지는 심볼릭 링크를 거부합니다. read_project_filesearch_project_files에서 프로젝트 루트를 기준으로 사용되며, search_project_files에서는 탐색 중 각 후보 파일에 대해 다시 적용됩니다. tests/test_security.py의 unit 테스트로 커버되며, Claude Code를 통한 실제 네거티브 테스트로 수동 확인되었습니다(아래 "검증 결과" 참조, 테스트 6).

  • 탐색 시 심볼릭 링크를 통한 이탈 없음: search_project_filesget_docs는 디렉토리 심볼릭 링크를 절대 따라가지 않으며(os.walk 기본 동작), 파일 심볼릭 링크는 완전히 건너뜁니다.

  • 임의의 shell 명령 없음: run_project_check는 요청된 검사 이름을 config.ALLOWED_CHECKS(config.py:55-57)와 대조하여 실행 전에 검증합니다. 알 수 없는 이름은 즉시 거부되며, 검사 자체는 subprocess.run(argv, shell=False, ...)를 통해 고정된 cwd로 실행되고 호출 측에서 추가된 인수는 없습니다.

  • 모든 곳에서 출력 제한: 각 tool은 반환 데이터의 양을 제한합니다 — 검색 및 docs의 경우 max_results + 하드 한도, 파일 읽기의 경우 바이트 제한, 검사 출력의 경우 문자 제한 + 타임아웃 — 따라서 어떤 호출도 무제한의 데이터를 반환하거나 무한히 실행될 수 없습니다.

  • stdout은 깨끗하게 유지됨: 모든 로깅은 logging_setup.py를 통해 stderr로(그리고 선택적으로 로그 파일로) 이루어집니다. 서버의 어떤 것도 MCP 프로토콜의 JSON-RPC 프레이밍을 위해 예약된 stdout에 쓰지 않습니다.

  • 로그에 비밀 없음: 서버는 API 키나 자격 증명을 전혀 받지 않습니다. 각 실제 tool 호출은 tool 이름, 안전한 입력 매개변수(쿼리 문자열, 경로, 검사 이름, 결과 수/크기 — 그러나 파일 내용은 절대 아님) 및 최종 status=success/status=error를 로깅합니다.

로깅 및 디버깅

각 실제 tool 호출은 공통 로거 mcp_project_helper(stderr, 추가로 MCP_PROJECT_HELPER_LOG_FILE을 통한 선택적 파일)를 통해 한 줄을 로깅합니다. 예: evidence/tool-calls.log의 실제 줄:

INFO mcp_project_helper: tool=search_project_files query='apply_discount' path='.' max_results=50 matches=4 truncated=False status=success
INFO mcp_project_helper: tool=read_project_file path='demo_app/models.py' size=397 truncated=False status=success
INFO mcp_project_helper: tool=run_project_check check_name='tests' exit_code=0 status=success
INFO mcp_project_helper: tool=read_project_file path='../../../../etc/passwd' status=error

파일 내용은 절대 로깅되지 않습니다 — 호출에 대한 메타데이터(경로, 쿼리 문자열, 크기, 개수, 종료 코드)만 로깅됩니다. 로깅 설정 — logging_setup.py:20-42.

디버깅을 위해:

  • 로깅 수준은 MCP_PROJECT_HELPER_LOG_LEVEL(DEBUG, INFO, WARNING, ERROR, CRITICAL; 기본값 INFO)로 조정합니다.

  • 로그 파일은 MCP_PROJECT_HELPER_LOG_FILE로 지정합니다. 기본값(이 변수 없이)은 stderr에만 씁니다. Claude Code(.mcp.json)에서 실행할 때는 evidence/tool-calls.log를 가리킵니다.

  • 서버 코드에서 print()를 절대 사용하지 마세요 — stdout은 JSON-RPC 프로토콜용으로 예약되어 있습니다. stdout에 대한 추가 출력은 stdio 전송을 깨뜨립니다.

  • 현재 Claude Code 세션에서 실제로 발생한 호출을 보려면 MCP_PROJECT_HELPER_LOG_FILE(evidence/tool-calls.log)이 가리키는 파일을 열거나, 서버를 수동으로 실행하고(python -m mcp_project_helper.server) stderr를 확인하세요.

설치

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

유일한 런타임 의존성은 mcp 패키지입니다. pytest는 개발/테스트 전용 의존성입니다(둘 다 pyproject.toml에 고정되어 있음).

환경 설정

구성은 환경 변수를 통해 지정됩니다 — .env.example.env로 복사하고 필요에 따라 값을 변경하세요:

변수

용도

기본값

MCP_PROJECT_HELPER_ROOT

파일 tools(search_project_files, read_project_file, get_docs — 해당 docs/에만 접근, get_docsMCP_PROJECT_HELPER_ROOT가 아닌 리포지토리 루트에서 작동)이 접근할 수 있는 유일한 디렉토리.

./demo_project

MCP_PROJECT_HELPER_LOG_FILE

로그 파일 경로("로깅 및 디버깅" 참조). 로그는 항상 stderr에도 기록됩니다.

미설정(stderr만)

MCP_PROJECT_HELPER_LOG_LEVEL

DEBUG/INFO/WARNING/ERROR/CRITICAL 중 하나.

INFO

서버에는 비밀(API 키, 토큰)이 필요하지 않습니다 — .env.example에는 안전한 경로 및 로깅 수준 예시만 포함되어 있고, .env는 git에서 무시됩니다(아래 "프로젝트 구조" 참조).

MCP 서버 실행

서버를 직접 실행합니다(stdin에서 클라이언트를 기다립니다 — stdio 전송을 사용하는 MCP 서버에서는 정상입니다. Ctrl+C로 종료):

python -m mcp_project_helper.server

테스트 세트 실행:

pytest -q

demo 프로젝트의 자체 테스트를 직접 실행(MCP_PROJECT_HELPER_ROOT가 기본적으로 demo_project를 가리키므로 run_project_check("tests")가 기본적으로 실행하는 것):

cd demo_project && pytest -q

Claude Code 통합

이 리포지토리에는 리포지토리 루트에 project-scoped 파일 .mcp.json이 포함되어 있습니다 — Claude Code 전용 구성입니다 (.vscode/mcp.json — native MCP host VS Code의 별도 구성과는 다릅니다. 자세한 비교는 아래 참조).

Claude Code는 프로젝트 폴더를 열 때 .mcp.json을 감지하고, 서버를 자식 프로세스로 시작한 후 stdio를 통해 JSON-RPC로 통신합니다 — 이 프로젝트의 모든 자동화된 테스트에서 사용되는 것과 동일한 전송 방식으로, 테스트 harness가 아닌 Claude Code 자체가 실행한다는 점만 다릅니다.

확인된 end-to-end 시나리오: Claude Code CLI → MCP server → custom tools. 6개의 모든 검증 요청(아래 "검증 결과" 참조)은 .mcp.json으로 연결된 이 서버로 Claude Code CLI를 통해 실제로 실행되었습니다 — 단지 구성만 된 것이 아니라 실제로 호출되었으며, 실제 스크린샷과 server-side 로그 기록이 있습니다.

Claude Code 구성

.mcp.json:

{
  "mcpServers": {
    "mcp-project-helper": {
      "command": "${CLAUDE_PROJECT_DIR:-.}/.venv/bin/python",
      "args": ["-m", "mcp_project_helper.server"],
      "env": {
        "MCP_PROJECT_HELPER_ROOT": "${CLAUDE_PROJECT_DIR:-.}/demo_project",
        "MCP_PROJECT_HELPER_LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/evidence/tool-calls.log"
      }
    }
  }
}

${CLAUDE_PROJECT_DIR}은 Claude Code 자체가 리포지토리가 클론된 디렉토리의 절대 경로로 확장하므로, 파일에는 특정 머신에 특화된 경로가 포함되지 않으며 git clone 후 수정이 필요 없습니다. fallback 값이 있는 ${CLAUDE_PROJECT_DIR:-.} 형식이 사용되며, 순수한 ${CLAUDE_PROJECT_DIR}이 아닙니다. :-.가 없으면 변수가 확장되지 않아 Claude Code가 ${CLAUDE_PROJECT_DIR}/.venv/bin/python을 실행 파일 경로로 그대로 실행하려고 했습니다(이 오류는 Stage 2 구성의 첫 버전에서 실제로 발견되었습니다. REPORT.md 참조). MCP_PROJECT_HELPER_ROOT${CLAUDE_PROJECT_DIR:-.}/demo_project로 명시적으로 설정되어, 서버에 전달되는 프로젝트 루트가 config.py의 자체 기본값과 무관하게 명확하도록 합니다.

플랫폼 참고 사항: .venv/bin/python은 이 프로젝트 전체에서 사용되는 Unix(macOS/Linux)용 venv 구조입니다. Windows에서 해당 경로는 .venv\Scripts\python.exe입니다. 해당 플랫폼도 지원하려면 .mcp.json에 Windows 전용 두 번째 항목(또는 래퍼 스크립트)이 필요합니다 — 프로젝트가 macOS에서만 개발 및 검증되었으므로 이 작업은 수행되지 않았습니다.

VS Code 구성

이 리포지토리에는 .vscode/mcp.json도 포함되어 있습니다 — VS Code 내장 MCP 호스트(GitHub Copilot Chat의 에이전트 모드에서 사용)를 위한 별도의 워크스페이스 구성입니다:

{
  "servers": {
    "mcp-project-helper": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/bin/python",
      "args": ["-m", "mcp_project_helper.server"],
      "env": {
        "MCP_PROJECT_HELPER_ROOT": "${workspaceFolder}/demo_project",
        "MCP_PROJECT_HELPER_LOG_FILE": "${workspaceFolder}/evidence/tool-calls.log"
      }
    }
  }
}

동일한 stdio 서버 mcp-project-helper이며, MCP_PROJECT_HELPER_ROOT${workspaceFolder}/demo_project로, MCP_PROJECT_HELPER_LOG_FILE${workspaceFolder}/evidence/tool-calls.log로 설정되어 있습니다.

파일이 하나가 아닌 두 개인 이유: .mcp.json.vscode/mcp.json은 서로 다른 호환되지 않는 스키마를 따르며, 경로 대체 변수는 호스트 간에 상호 교환할 수 없습니다:

  • .mcp.json(Claude Code 구성)은 최상위 키 mcpServers를 사용하고 ${CLAUDE_PROJECT_DIR:-.}을 리포지토리 루트로 확장합니다.

  • .vscode/mcp.json(native MCP host VS Code 구성)은 최상위 키 servers, 명시적 필드 "type": "stdio"를 사용하고 대신 ${workspaceFolder}를 열린 폴더의 경로로 확장합니다. VS Code MCP 호스트는 ${CLAUDE_PROJECT_DIR}이해하지 못합니다 — VS Code에서 .mcp.json을 직접 열려고 하면 변수가 그대로 전달되어 서버가 시작할 수 없습니다(spawn ${CLAUDE_PROJECT_DIR}/.venv/bin/python ENOENT) — 이는 실제로 관찰된 오류이며, 별도의 .vscode/mcp.json이 만들어진 이유입니다. 각 호스트의 구성을 자체 파일에, 자체 변수로 저장하면 이 오류를 피할 수 있고, 한 구성이 다른 구성의 구문을 손상시키지 않으면서 두 도구를 동일한 클론과 함께 사용할 수 있습니다.

.vscode/mcp.json.gitignore에서 .vscode/*를 무시하는 일반 규칙의 유일한 예외입니다. 나머지 로컬 VS Code 상태(settings.local.json 등)는 추적되지 않습니다.

VS Code 검증 상태: .vscode/mcp.json은 구문 및 의미적으로 올바르며(동일한 서버, 동일한 명령/환경 변수 — 작동하는 Claude Code 구성과 동일) JSON으로 검증되었습니다. 또한 evidence/vscode_mcp_server_connected.png 실제 스크린샷으로 VS Code 내장 native MCP host가 이 구성으로 서버를 실제로 시작한다는 사실이 확인되었습니다: Starting server mcp-project-helperConnection state: RunningDiscovered 4 tools, 같은 출력에서 mcp_project_helper 프로세스의 자체 stderr 로그의 확인 줄이 함께 있습니다. 이것은 VS Code 인터페이스를 통한 custom tools 호출 확인과는 다릅니다 — 이 인터페이스를 통해 사용자 시나리오 (search_project_files 등)는 실행되지 않았으며 검증된 것으로 주장되지 않습니다. 사용자가 실제로 tools를 호출하는 것까지 확인된 유일한 IDE 통합(6개 시나리오 모두에 대한 스크린샷 + server-side 로그)은 Claude Code CLI입니다. 아래 "검증 결과" 참조. 둘 다와 별개로: Claude Code Desktop / VS Code 내 Claude Code 확장을 통한 통합은 이 세션에서 전혀 검증되지 않았습니다 — native MCP host VS Code(이 섹션)나 Claude Code CLI와 혼동하지 마세요.

MCP 활성화 방법

요약(자세한 내용은 위 하위 섹션 참조):

Claude Code:

  1. venv를 만들고 의존성을 설치합니다("설치" 섹션).

  2. Claude Code에서 리포지토리 루트를 엽니다(리포지토리 루트에서 claude).

  3. Claude Code가 .mcp.json을 감지하고 mcp-project-helper 서버에 대한 워크스페이스 신뢰 확인을 한 번 요청합니다 — 확인합니다.

  4. /mcp(또는 터미널에서 claude mcp list)를 실행하고 mcp-project-helper가 4개의 tools로 연결되었는지 확인합니다.

VS Code(native MCP host, Copilot Chat 에이전트 모드):

  1. Claude Code와 동일하게 venv를 만듭니다 — .vscode/mcp.json은 동일한 .venv/bin/python을 기대합니다.

  2. VS Code에서 리포지토리 루트를 폴더로 엽니다.

  3. VS Code가 .vscode/mcp.json을 감지하고 서버 시작을 제안합니다 — 시작/신뢰를 확인합니다.

  4. MCP: List Servers로 상태를 확인합니다.

Оба варианта предполагают Unix-структуру venv (.venv/bin/python); в
Windows — .venv\Scripts\python.exe (не настроено, см. выше).

Проверочные запросы

Шесть сценариев, реально выполненных через Claude Code CLI для подтверждения
интеграции (полная таблица с результатами — в
evidence/README.md):

  1. Найди через MCP все места использования функции apply_discount в
    demo_project → ожидается search_project_files.

  2. Прочитай через MCP файл demo_app/models.py и кратко объясни, какие
    модели там определены → ожидается read_project_file.

  3. Используя MCP-документацию проекта, расскажи, какие ограничения
    безопасности есть у MCP-сервера → ожидается get_docs.

  4. Проверь через MCP-инструмент, проходят ли тесты demo_project
    ожидается run_project_check.

  5. Используя только MCP-инструменты, найди в demo_project реализацию
    apply_discount, затем прочитай файл, где она определена, и объясни её
    параметры/возврат/расчёт скидки → ожидается цепочка из двух tools:
    search_project_files, затем read_project_file.

  6. (негативный / security-тест) Попробуй через MCP прочитать файл
    ../../../../etc/passwd → ожидается отказ read_project_file со
    структурированной ошибкой (путь выходит за пределы разрешённого корня).

Результаты проверки

Все 6 из 6 запросов выполнены успешно (в тесте 5 — оба ожидаемых tool, в
правильном порядке; в тесте 6 успехом является ожидаемый отказ). Каждая
строка подтверждена и реальным скриншотом, и независимой строкой в
evidence/tool-calls.log. Полная таблица —
evidence/README.md; подробный разбор с ссылками на
код и логи — REPORT.md.

Tool

Итог

1

search_project_files

Успех, 4 совпадений

2

read_project_file

Успех, size=397

3

get_docs

Успех, найден раздел «Безопасность»

4

run_project_check

Успех, exit_code=0, 2/2 тестов пройдено

5

search_project_filesread_project_file

Успех, цепочка из двух tools

6

read_project_file

Успешный отказ (path traversal заблокирован)

Автоматизированные проверки (не заменяют, а дополняют ручное IDE-тестирование
выше):

  • pytest -q из корня репозитория — 44 passed.

  • pytest -q внутри demo_project/2 passed.

  • Программный stdio-хендшейк (initialize() + list_tools()) — сервер
    сообщает mcp-project-helper 0.1.0 и ровно 4 tools:
    get_docs, read_project_file, run_project_check,
    search_project_files.

Структура проекта

mcp-project-helper/
  .mcp.json                конфигурация MCP для Claude Code (project-scoped)
  .vscode/mcp.json          конфигурация MCP для native MCP host VS Code
  .env.example              безопасные примеры переменных окружения (без секретов)
  pyproject.toml            зависимости, entry point, конфигурация pytest
  README.md                 этот файл
  REPORT.md                 итоговый отчёт по всем стадиям, со ссылками файл:строки
  PROMPTS.md                история фактически использованных промптов (Этапы 0-3)
  docs/
    architecture.md          документация, которую обслуживает get_docs
  src/mcp_project_helper/
    server.py                 точка входа: MCPServer, регистрация tools, stdio
    config.py                  корень проекта/docs, лимиты, whitelist проверок
    security.py                resolve_within_root() — ограничение путей
    logging_setup.py           логирование в stderr (+ опционально файл)
    tools/
      search_project_files.py
      read_project_file.py
      get_docs.py
      run_project_check.py
  tests/                     unit- и интеграционные тесты mcp_project_helper (44 теста)
  demo_project/              демонстрационный проект — цель для файловых tools
    demo_app/
      models.py                Product, Order
      services.py               apply_discount, OrderBuilder
      tests/test_services.py    2 теста, запускаемые run_project_check("tests")
  evidence/                  реальные доказательства ручного тестирования через Claude Code и VS Code
    README.md                  реестр всех 6 тестов с результатами + доп. evidence по VS Code
    tool-calls.log              реальный server-side лог всех 6 тестов (закоммичен)
    tool-calls.log.example      формат строки лога (шаблон)
    test1_search_project_files.png … test6_path_traversal.png   скриншоты 6 тестов Claude Code CLI (закоммичены)
    vscode_mcp_server_connected.png   доп. скриншот: native MCP host VS Code подключился, 4 tools (закоммичен)
F
license - not found
Not graded
quality - not tested
C
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
    B
    maintenance
    Agent-safe code retrieval MCP server that indexes repositories and provides semantic search, file navigation, call graph analysis, and bounded file reading tools for coding agents.
    3,977,962
    3
    AGPL 3.0
  • A
    license
    A
    quality
    C
    maintenance
    Zero-config MCP server that connects local codebases to AI assistants, providing secure project tree, regex search, file reading, and tech stack tools locally.
    4
    33
    MIT

View all related MCP servers

Related MCP Connectors

  • Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • An MCP server that gives your AI access to the source code and docs of all public github repos

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/pw5rhn4tnn-dotcom/mcp-project-helper'

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