Python MCP Server

local-only server

The server can only run on the client’s local machine because it depends on local resources.

Integrations

  • Provides configuration for use with Codeium Windsurf as an MCP-compatible client

코드 그래프 추출을 위한 Python MCP 서버

이 MCP(Model Context Protocol) 서버는 파일 간 가져오기/내보내기 관계에 중점을 두고 Python 코드 구조를 추출하고 분석하는 도구를 제공합니다. 에이전트 시스템이 필요 없는 가벼운 구현 방식으로 모든 Python 애플리케이션에 쉽게 통합할 수 있습니다.

특징

  • 코드 관계 검색 : Python 파일 간의 가져오기 관계 분석
  • 스마트 코드 추출 : 토큰 한도 내에 있도록 가장 관련성 있는 코드 섹션만 추출합니다.
  • 디렉토리 컨텍스트 : 더 나은 컨텍스트를 제공하기 위해 동일한 디렉토리의 파일을 포함합니다.
  • 문서 포함 : 프로젝트 문서를 제공하기 위해 항상 README.md 파일(또는 변형)을 포함합니다.
  • LLM 친화적 포맷팅 : 언어 모델에 대한 적절한 메타데이터로 코드 포맷팅
  • MCP 프로토콜 지원 : Model Context Protocol JSON-RPC 표준과 완벽하게 호환됩니다.

get_python_code 도구

이 서버는 다음과 같은 강력한 코드 추출 도구를 제공합니다.

  • 대상 Python 파일을 분석하고 가져온 모든 모듈, 클래스 및 함수를 검색합니다.
  • 대상 파일의 전체 코드를 반환합니다.
  • 다른 파일의 모든 참조된 개체에 대한 코드를 포함합니다.
  • 동일한 디렉토리에서 추가 컨텍스트 파일을 추가합니다.
  • 과도한 언어 모델을 방지하기 위해 토큰 제한을 존중합니다.

설치

지엑스피1

환경 변수

제공된 .env.example 을 기반으로 .env 파일을 만듭니다.

# Token limit for extraction TOKEN_LIMIT=8000

용법

MCP 클라이언트 구성

Codeium Windsurf와 같은 MCP 호환 클라이언트에서 이 MCP 서버를 사용하도록 구성하려면 클라이언트의 MCP 구성 파일에 다음 구성을 추가하세요.

{ "mcpServers": { "python-code-explorer": { "command": "python", "args": [ "/path/to/python-mcp-new/server.py" ], "env": { "TOKEN_LIMIT": "8000" } } } }

/path/to/python-mcp-new/server.py 시스템의 server.py 파일에 대한 절대 경로로 바꾸세요.

환경 변수를 사용자 정의할 수도 있습니다.

  • TOKEN_LIMIT : 코드 추출을 위한 최대 토큰 한도(기본값: 8000)

사용 예

직접 함수 호출

from agent import get_python_code # Get Python code structure for a specific file result = get_python_code( target_file="/home/user/project/main.py", root_repo_path="/home/user/project" # Optional, defaults to target file directory ) # Process the result target_file = result["target_file"] print(f"Main file: {target_file['file_path']}") print(f"Docstring: {target_file['docstring']}") # Display related files for ref_file in result["referenced_files"]: print(f"Related file: {ref_file['file_path']}") print(f"Object: {ref_file['object_name']}") print(f"Type: {ref_file['object_type']}") # See if we're close to the token limit print(f"Token usage: {result['token_count']}/{result['token_limit']}")

예제 응답(직접 함수 호출)

{ "target_file": { "file_path": "main.py", "code": "import os\nimport sys\nfrom utils.helpers import format_output\n\ndef main():\n args = sys.argv[1:]\n if not args:\n print('No arguments provided')\n return\n \n result = format_output(args[0])\n print(result)\n\nif __name__ == '__main__':\n main()", "type": "target", "docstring": "" }, "referenced_files": [ { "file_path": "utils/helpers.py", "object_name": "format_output", "object_type": "function", "code": "def format_output(text):\n \"\"\"Format the input text for display.\"\"\"\n if not text:\n return ''\n return f'Output: {text.upper()}'\n", "docstring": "Format the input text for display.", "truncated": false } ], "additional_files": [ { "file_path": "config.py", "code": "# Configuration settings\n\nDEBUG = True\nVERSION = '1.0.0'\nMAX_RETRIES = 3\n", "type": "related_by_directory", "docstring": "Configuration settings for the application." } ], "total_files": 3, "token_count": 450, "token_limit": 8000 }

MCP 프로토콜 사용

사용 가능한 도구 목록

from agent import handle_mcp_request import json # List available tools list_request = { "jsonrpc": "2.0", "id": 1, "method": "tools/list" } response = handle_mcp_request(list_request) print(json.dumps(response, indent=2))

예시 응답(도구/목록)

{ "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "get_python_code", "description": "Return the code of a target Python file and related files based on import/export proximity.", "inputSchema": { "type": "object", "properties": { "target_file": { "type": "string", "description": "Path to the Python file to analyze." }, "root_repo_path": { "type": "string", "description": "Root directory of the repository. If not provided, the directory of the target file will be used." } }, "required": ["target_file"] } } ] } }

get_python_code 도구 호출

from agent import handle_mcp_request import json # Call the get_python_code tool tool_request = { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_python_code", "arguments": { "target_file": "/home/user/project/main.py", "root_repo_path": "/home/user/project" # Optional } } } response = handle_mcp_request(tool_request) print(json.dumps(response, indent=2))

예시 응답(도구/통화)

{ "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "Python code analysis for /home/user/project/main.py" }, { "type": "resource", "resource": { "uri": "resource://python-code/main.py", "mimeType": "application/json", "data": { "target_file": { "file_path": "main.py", "code": "import os\nimport sys\nfrom utils.helpers import format_output\n\ndef main():\n args = sys.argv[1:]\n if not args:\n print('No arguments provided')\n return\n \n result = format_output(args[0])\n print(result)\n\nif __name__ == '__main__':\n main()", "type": "target", "docstring": "" }, "referenced_files": [ { "file_path": "utils/helpers.py", "object_name": "format_output", "object_type": "function", "code": "def format_output(text):\n \"\"\"Format the input text for display.\"\"\"\n if not text:\n return ''\n return f'Output: {text.upper()}'\n", "docstring": "Format the input text for display.", "truncated": false } ], "additional_files": [ { "file_path": "config.py", "code": "# Configuration settings\n\nDEBUG = True\nVERSION = '1.0.0'\nMAX_RETRIES = 3\n", "type": "related_by_directory", "docstring": "Configuration settings for the application." } ], "total_files": 3, "token_count": 450, "token_limit": 8000 } } } ], "isError": false } }

오류 처리

from agent import handle_mcp_request # Call with invalid file path faulty_request = { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "get_python_code", "arguments": { "target_file": "/path/to/nonexistent.py" } } } response = handle_mcp_request(faulty_request) print(json.dumps(response, indent=2))

오류 응답 예시

{ "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "Error processing Python code: No such file or directory: '/path/to/nonexistent.py'" } ], "isError": true } }

테스트

기능을 확인하기 위해 테스트를 실행하세요.

python -m unittest discover tests

주요 구성 요소

  • agent.py : get_python_code 함수와 사용자 정의 MCP 프로토콜 핸들러를 포함합니다.
  • code_grapher.py : Python 코드 분석을 위한 CodeGrapher 클래스를 구현합니다.
  • server.py : MCP Python SDK를 사용한 전체 MCP 서버 구현
  • run_server.py : MCP 서버를 실행하기 위한 CLI 도구
  • 예제/ : MCP 서버와 클라이언트를 사용하는 방법을 보여주는 예제 스크립트
  • tests/ : 모든 기능에 대한 포괄적인 테스트 케이스

응답 형식 세부 정보

get_python_code 도구는 다음 필드가 포함된 구조화된 JSON 객체를 반환합니다.

필드유형설명
target_file물체대상 Python 파일에 대한 정보
referenced_files정렬대상 파일에 의해 가져온 객체 목록
additional_files정렬동일한 디렉토리의 추가 컨텍스트 파일
total_files숫자응답에 포함된 총 파일 수
token_count숫자포함된 모든 코드의 토큰의 대략적인 개수
token_limit숫자추출을 위해 구성된 최대 토큰 한도

대상 파일 객체

필드유형설명
file_path저장소 루트에서 파일에 대한 상대 경로
code파일의 전체 소스 코드
type항상 "타겟"
docstring사용 가능한 경우 모듈 수준 docstring

참조된 파일 객체

필드유형설명
file_path파일에 대한 상대 경로
object_name가져온 객체의 이름(클래스, 함수 등)
object_type객체의 유형("클래스", "함수" 등)
code특정 객체의 소스 코드
docstring사용 가능한 경우 객체의 Docstring
truncated부울토큰 제한으로 인해 코드가 잘렸는지 여부

추가 파일 객체

필드유형설명
file_path파일에 대한 상대 경로
code파일의 전체 소스 코드
type관계 유형(예: "related_by_directory")
docstring사용 가능한 경우 모듈 수준 docstring

MCP SDK 서버 사용

이 프로젝트에는 공식 Python MCP SDK를 기반으로 구축된 모든 기능을 갖춘 MCP(Model Context Protocol) 서버가 포함됩니다. 이 서버는 Claude Desktop을 포함한 모든 MCP 클라이언트에서 사용할 수 있는 표준화된 방식으로 코드 추출 기능을 제공합니다.

서버 시작

# Start the server with default settings python run_server.py # Specify a custom name python run_server.py --name "My Code Explorer" # Use a specific .env file python run_server.py --env-file .env.production

MCP 개발 모드 사용

MCP SDK가 설치되면 MCP CLI를 사용하여 개발 모드에서 서버를 실행할 수 있습니다.

# Install the MCP CLI pip install "mcp[cli]" # Start the server in development mode with the Inspector UI mcp dev server.py

이렇게 하면 서버를 테스트하고 디버깅하는 웹 인터페이스인 MCP Inspector가 시작됩니다.

Claude 데스크톱 통합

Claude Desktop에 서버를 설치하면 Claude에서 직접 코드 탐색 도구에 액세스할 수 있습니다.

# Install the server in Claude Desktop mcp install server.py # With custom configuration mcp install server.py --name "Python Code Explorer" -f .env

사용자 정의 서버 배포

사용자 정의 배포의 경우 MCP 서버를 직접 사용할 수 있습니다.

from server import mcp # Configure the server mcp.name = "Custom Code Explorer" # Run the server mcp.run()

MCP 클라이언트 사용

MCP Python SDK를 사용하여 서버에 프로그래밍 방식으로 연결할 수 있습니다. examples/mcp_client_example.py 에서 제공된 예제를 참조하세요.

from mcp.client import Client, Transport # Connect to the server client = Client(Transport.subprocess(["python", "server.py"])) client.initialize() # List available tools for tool in client.tools: print(f"Tool: {tool.name}") # Use the get_code tool result = client.tools.get_code(target_file="path/to/your/file.py") print(f"Found {len(result['referenced_files'])} referenced files") # Clean up client.shutdown()

예제를 실행해보세요:

python examples/mcp_client_example.py [optional_target_file.py]

추가 도구 추가

server.py 에서 @mcp.tool() 데코레이터로 함수를 데코레이션하여 MCP 서버에 추가 도구를 추가할 수 있습니다.

@mcp.tool() def analyze_imports(target_file: str) -> Dict[str, Any]: """Analyze all imports in a Python file.""" # Implementation code here return { "file": target_file, "imports": [], # List of imports found "analysis": "" # Analysis of the imports } @mcp.tool() def find_python_files(directory: str, pattern: str = "*.py") -> list[str]: """Find Python files matching a pattern in a directory.""" from pathlib import Path return [str(p) for p in Path(directory).glob(pattern) if p.is_file()]

리소스 엔드포인트를 추가하여 데이터를 직접 제공할 수도 있습니다.

@mcp.resource("python_stats://{directory}") def get_stats(directory: str) -> Dict[str, Any]: """Get statistics about Python files in a directory.""" from pathlib import Path stats = { "directory": directory, "file_count": 0, "total_lines": 0, "average_lines": 0 } files = list(Path(directory).glob("**/*.py")) stats["file_count"] = len(files) if files: total_lines = 0 for file in files: with open(file, "r") as f: total_lines += len(f.readlines()) stats["total_lines"] = total_lines stats["average_lines"] = total_lines / len(files) return stats

모델 컨텍스트 프로토콜 통합

이 프로젝트는 MCP(Model Context Protocol) 표준을 완전히 수용하여 두 가지 구현 옵션을 제공합니다.

  1. 기본 MCP 통합 : agent.py 의 원래 구현은 MCP와 호환되는 직접적인 JSON-RPC 인터페이스를 제공합니다.
  2. MCP SDK 통합 : server.py 의 새로운 구현은 보다 강력하고 기능이 풍부한 환경을 위해 공식 MCP Python SDK를 활용합니다.

MCP 통합의 이점

  • 표준화된 인터페이스 : 모든 MCP 호환 클라이언트에서 도구를 사용할 수 있습니다.
  • 강화된 보안 : 내장된 권한 모델 및 리소스 제어
  • 더 나은 LLM 통합 : Claude Desktop 및 기타 LLM 플랫폼과의 원활한 통합
  • 향상된 개발자 경험 : MCP Inspector와 같은 포괄적인 툴링

MCP 프로토콜 버전

이 구현은 MCP 프로토콜 버전 0.7.0을 지원합니다.

MCP에 대한 자세한 내용은 공식 문서를 참조하세요.

ID: 4zt7hpbt5k