コードグラフ抽出のための 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 つの実装オプションを提供しています。
- ネイティブ MCP 統合:
agent.py
の元の実装は、MCP と互換性のある直接の JSON-RPC インターフェイスを提供します。 - MCP SDK 統合:
server.py
の新しい実装では、公式の MCP Python SDK を活用して、より堅牢で機能豊富なエクスペリエンスを実現します。
MCP統合のメリット
- 標準化されたインターフェース: MCP 互換クライアントでツールを利用できるようになります
- 強化されたセキュリティ: 組み込みの権限モデルとリソース制御
- より優れたLLM統合:Claude Desktopおよびその他のLLMプラットフォームとのシームレスな統合
- 開発者エクスペリエンスの向上: MCP Inspector などの包括的なツール
MCPプロトコルバージョン
この実装は、MCP プロトコル バージョン 0.7.0 をサポートしています。
MCP の詳細については、公式ドキュメントを参照してください。