用于代码图提取的 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 服务器
该项目现在包含一个功能齐全的模型上下文协议 (MCP) 服务器,该服务器使用官方Python MCP SDK构建。该服务器以标准化的方式公开我们的代码提取功能,可与任何 MCP 客户端(包括 Claude Desktop)一起使用。
启动服务器
# 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,一个用于测试和调试服务器的 Web 界面。
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)标准,提供两种实现选项:
- 原生 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 的更多信息,请参阅官方文档。