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(モデルコンテキストプロトコル)サーバーは、ファイル間のインポート/エクスポート関係に重点を置き、Pythonコード構造を抽出および分析するためのツールを提供します。エージェントシステムを必要としない軽量な実装であるため、あらゆるPythonアプリケーションに簡単に統合できます。

特徴

  • コード関係の検出: Python ファイル間のインポート関係を分析する
  • スマートコード抽出: トークン制限内に収まるように、最も関連性の高いコードセクションのみを抽出します。
  • ディレクトリコンテキスト: より良いコンテキストを提供するために同じディレクトリからのファイルを含める
  • ドキュメントの包含: プロジェクトのドキュメントを提供するために、常に README.md ファイル(またはそのバリエーション)を包含する
  • LLMフレンドリーなフォーマット:言語モデルに適したメタデータでコードをフォーマットする
  • MCPプロトコルサポート: モデルコンテキストプロトコルJSON-RPC標準と完全に互換性があります

get_python_codeツール

サーバーは、次のような強力なコード抽出ツールを公開します。

  • 対象のPythonファイルを分析し、インポートされたすべてのモジュール、クラス、関数を検出します。
  • 対象ファイルの完全なコードを返します
  • 他のファイルから参照されるすべてのオブジェクトのコードが含まれます
  • 同じディレクトリから追加のコンテキストファイルを追加します
  • 言語モデルの過負荷を回避するためにトークン制限を尊重する

インストール

# Clone the repository git clone https://github.com/yourusername/python-mcp-new.git cd python-mcp-new # Create a virtual environment python -m venv venv source venv/bin/activate # On Windows, use: venv\Scripts\activate # Install dependencies pip install -r requirements.txt

環境変数

提供された.env.exampleに基づいて.envファイルを作成します。

# Token limit for extraction TOKEN_LIMIT=8000

使用法

MCP クライアントの設定

この MCP サーバーを MCP 互換クライアント (Codeium Windsurf など) で使用するように構成するには、クライアントの 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 ツール
  • examples/ : MCP サーバーとクライアントの使用方法を示すサンプルスクリプト
  • tests/ : すべての機能に対する包括的なテストケース

応答形式の詳細

get_python_codeツールは、次のフィールドを持つ構造化された JSON オブジェクトを返します。

分野タイプ説明
target_file物体対象のPythonファイルに関する情報
referenced_files配列ターゲットファイルによってインポートされたオブジェクトのリスト
additional_files配列同じディレクトリからの追加のコンテキストファイル
total_files番号応答に含まれるファイルの総数
token_count番号含まれるすべてのコード内のトークンのおおよその数
token_limit番号抽出用に設定された最大トークン制限

ターゲットファイルオブジェクト

分野タイプ説明
file_pathリポジトリルートからのファイルへの相対パス
codeファイルの完全なソースコード
type常に「ターゲット」
docstringモジュールレベルのドキュメント文字列(利用可能な場合)

参照ファイルオブジェクト

分野タイプ説明
file_pathファイルへの相対パス
object_nameインポートされたオブジェクトの名前(クラス、関数など)
object_typeオブジェクトのタイプ(「クラス」、「関数」など)
code特定のオブジェクトのソースコード
docstringオブジェクトのドキュメント文字列(利用可能な場合)
truncatedブール値トークン制限によりコードが切り捨てられたかどうか

追加ファイルオブジェクト

分野タイプ説明
file_pathファイルへの相対パス
codeファイルの完全なソースコード
type関係の種類(例:「related_by_directory」)
docstringモジュールレベルのドキュメント文字列(利用可能な場合)

MCP SDKサーバーの使用

このプロジェクトには、公式Python MCP SDKを使用して構築されたフル機能のモデルコンテキストプロトコル(MCP)サーバーが含まれています。このサーバーは、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

これにより、サーバーのテストとデバッグ用の Web インターフェイスである MCP Inspector が起動します。

クロードデスクトップ統合

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 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) 標準を完全に採用しており、次の 2 つの実装オプションを提供しています。

  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