About Cmc Inspect
Cmc Inspect is an MCP server published by sillydog5254 in the Other category.
Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.
Install
git clone https://github.com/sillydog5254/cmc-inspectThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Cmc Inspect
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
CMC软件包分析工具
用于 CI/CD 质量门禁的自动化软件包分析代理
📋 目录
🎯 项目概述
CMC软件包分析工具是一个用于CI/CD质量门禁的自动化代理程序,专门设计用于在B版本被提升为C版本之前进行质量检查。该工具能够自动分析软件包的目录结构和软件包大小变化,及早发现打包错误并阻止有问题的构建继续进行。
核心价值
- 🔍 自动化质量检查: 无需人工干预的软件包质量分析
- 🚨 早期问题发现: 在CI/CD流水线早期发现打包问题
- 📊 结构化报告: 输出标准JSON格式报告,易于集成
- 🔧 灵活配置: 支持自定义阈值和检查规则
- 🚀 多种接口: CLI工具、MCP服务器、Python API
应用场景
- CI/CD质量门禁: 作为自动化质量检查步骤
- 版本发布验证: 确保发布包符合质量标准
- 打包错误检测: 及早发现文件缺失或冗余
- 合规性检查: 确保发布包不包含敏感文件
🚀 核心功能
1. 软件包大小分析
- ✅ 计算软件包总大小
- ✅ 与前一版本比较大小变化
- ✅ 支持可配置阈值检查(默认±15%)
- ✅ 提供详细的大小变化描述
2. 目录结构分析
- ✅ 对比当前版本与前一版本的文件/目录树
- ✅ 识别新增的文件和目录
- ✅ 识别删除的文件和目录
- ✅ 检测禁止文件模式(*.log, *.tmp, .idea/等)
3. 多种输出格式
- ✅ 结构化JSON报告(符合CI/CD集成要求)
- ✅ 人类可读的文本摘要
- ✅ 详细的分析日志
4. 多种接口支持
- 🖥️ 命令行工具(CLI): 直接命令行使用
- 🌐 MCP服务器: 为AI代理提供分析能力
- 🔧 Python API: 编程接口支持
🏗️ 项目架构
整体架构图
┌─────────────────────────────────────────────────────────────┐
│ CMC软件包分析工具 │
├─────────────────────────────────────────────────────────────┤
│ 用户接口层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ CLI工具 │ │ MCP服务器 │ │ Python API │ │
│ │ │ │ │ │ │ │
│ │ cmc-inspect │ │FastMCP-based│ │ 编程接口 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 业务逻辑层 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 分析器模块 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │ │
│ │ │ SizeAnalyzer│ │StructAnalyz.│ │ BaseAnalyzer │ │ │
│ │ │ 大小分析 │ │ 结构分析 │ │ 分析器基类 │ │ │
│ │ └─────────────┘ └─────────────┘ └───────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 数据模型层 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Pydantic模型 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │ │
│ │ │PackageInfo │ │AnalysisResult│ │ 配置模型 │ │ │
│ │ │ 包信息 │ │ 分析结果 │ │ │ │ │
│ │ └─────────────┘ └─────────────┘ └───────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 工具支持层 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 工具模块 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │ │
│ │ │PackageExtr. │ │ FileUtils │ │ FormatUtils │ │ │
│ │ │ 包解压 │ │ 文件工具 │ │ 格式化工具 │ │ │
│ │ └─────────────┘ └─────────────┘ └───────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
目录结构
cmc-inspect/
├── src/cmc_inspect/ # 主要源码目录
│ ├── __init__.py # 包初始化,导出核心组件
│ ├── config.py # 配置管理模块
│ ├── cli.py # 命令行接口
│ ├── server.py # MCP服务器入口
│ │
│ ├── models/ # 数据模型
│ │ ├── __init__.py
│ │ ├── package_info.py # 软件包信息模型
│ │ └── analysis_result.py # 分析结果模型
│ │
│ ├── analyzers/ # 分析器模块
│ │ ├── __init__.py
│ │ ├── base.py # 分析器基类
│ │ ├── size.py # 大小分析器
│ │ └── structure.py # 结构分析器
│ │
│ ├── tools/ # 工具模块
│ │ ├── __init__.py
│ │ ├── package_extractor.py # 软件包解压工具
│ │ ├── file_utils.py # 文件操作工具
│ │ └── format_utils.py # 格式化工具
│ │
│ └── mcp_tools/ # MCP工具定义
│ ├── __init__.py
│ ├── analyze_package.py # 分析工具
│ └── compare_packages.py # 比较工具
│
├── tests/ # 测试目录
│ ├── __init__.py
│ ├── test_basic.py # 基础功能测试
│ ├── test_analyzers/ # 分析器测试
│ ├── test_tools/ # 工具测试
│ └── test_mcp_tools/ # MCP工具测试
│
├── examples/ # 示例和文档
│ ├── config.json # 示例配置文件
│ ├── usage_examples.md # 使用示例文档
│ ├── demo.py # 功能演示脚本
│ └── sample_packages/ # 示例软件包
│ ├── create_samples.py # 创建示例包脚本
│ ├── example-package-v1.0.zip
│ ├── example-package-v2.0.zip
│ └── example-package-v2.1.zip
│
├── pyproject.toml # 项目配置
├── README.md # 项目文档
├── PROJECT_SUMMARY.md # 项目总结
└── .gitignore # Git忽略文件
🛠️ 模块功能详解
1. 数据模型层 (models/)
PackageInfo - 软件包信息模型
class PackageInfo(BaseModel):
name: str # 软件包名称
version: str # 版本号
file_path: Path # 文件路径
size_bytes: int # 文件大小(字节)
extracted_path: Optional[Path] # 解压路径
created_at: datetime # 创建时间
AnalysisResult - 分析结果模型
class AnalysisResult(BaseModel):
analysis_info: AnalysisInfo # 分析元信息
overall_status: StatusType # 总体状态
size_check: SizeCheckResult # 大小检查结果
structure_check: StructureCheckResult # 结构检查结果
summary: str # 人类可读摘要
状态类型定义
StatusType = Literal["PASSED", "WARNING", "FAILED"]
2. 分析器层 (analyzers/)
BaseAnalyzer - 分析器基类
- 提供通用的分析器接口
- 定义抽象方法:
analyze()和compare() - 包含配置管理和验证功能
SizeAnalyzer - 大小分析器
核心功能:
- 计算软件包大小
- 比较版本间大小变化
- 根据阈值确定状态
- 格式化大小显示
关键方法:
async def analyze(package_info: PackageInfo) -> Dict[str, Any]
async def compare(current: PackageInfo, previous: PackageInfo) -> Dict[str, Any]
StructureAnalyzer - 结构分析器
核心功能:
- 分析目录结构
- 比较文件变化
- 检测禁止文件
- 生成变化报告
关键方法:
async def analyze(package_info: PackageInfo) -> DirectoryStructure
async def compare(current: PackageInfo, previous: PackageInfo) -> Dict[str, Any]
3. 工具支持层 (tools/)
PackageExtractor - 软件包解压工具
支持格式:
.zip- ZIP压缩包.tar,.tar.gz,.tgz- TAR压缩包.tar.bz2,.tar.xz- 其他TAR变种.7z- 7-Zip压缩包(需要py7zr)
核心功能:
- 安全解压(防止路径遍历攻击)
- 异步操作支持
- 错误处理和清理
- 格式自动检测
file_utils.py - 文件操作工具
提供功能:
- 目录大小计算
- 文件列表获取
- 模式匹配查找
- 安全目录操作
format_utils.py - 格式化工具
提供功能:
- 文件大小格式化(B, KB, MB, GB, TB)
- 百分比变化格式化
- 时间戳格式化
- 状态信息格式化
4. MCP工具层 (mcp_tools/)
分析工具 (analyze_package.py)
analyze_package- 完整软件包分析extract_package- 软件包解压get_package_info- 获取包基本信息
比较工具 (compare_packages.py)
compare_packages- 主要比较工具(输出标准JSON)compare_packages_detailed- 详细比较分析quick_size_compare- 快速大小比较
5. 接口层
CLI接口 (cli.py)
子命令:
analyze- 分析单个软件包compare- 比较两个软件包版本server- 启动MCP服务器
MCP服务器 (server.py)
- FastMCP服务器实现
- 工具注册和管理
- 健康检查功能
- 配置管理
🚀 快速开始
前提条件
- Python 3.13+
- uv包管理器
1. 克隆项目
git clone <your-repo-url>
cd cmc-inspect
2. 安装依赖
# 安装基础依赖
uv sync
# 安装开发依赖
uv sync --extra dev
3. 运行测试
uv run pytest tests/ -v
4. 创建示例包
python examples/sample_packages/create_samples.py
5. 快速体验
# 分析单个软件包
uv run cmc-inspect analyze examples/sample_packages/example-package-v1.0.zip
# 比较两个版本
uv run cmc-inspect compare \
examples/sample_packages/example-package-v2.0.zip \
examples/sample_packages/example-package-v1.0.zip \
--current-version "B-103" \
--previous-version "B-102"
📦 安装指南
方式1: 使用uv(推荐)
# 开发模式安装
uv pip install -e .
# 生产模式安装
uv pip install .
方式2: 使用pip
# 从源码安装
pip install -e .
# 或者直接安装
pip install .
依赖说明
核心依赖:
fastmcp>=2.11.1- MCP服务器框架pydantic>=2.11.7- 数据验证和序列化typing-extensions>=4.14.1- 类型支持pathlib2>=2.3.7- 路径操作增强
开发依赖:
pytest>=7.4.0- 测试框架pytest-asyncio>=0.21.0- 异步测试支持black>=23.0.0- 代码格式化ruff>=0.1.0- 代码检查mypy>=1.7.0- 类型检查
🖥️ 使用方法
CLI命令行工具
分析单个软件包
# 基本用法
cmc-inspect analyze package.zip
# 指定版本和参数
cmc-inspect analyze package.zip \
--version "B-103" \
--package-name "my-app" \
--temp-dir "./temp" \
--size-threshold 20.0
比较两个软件包
# 基本比较
cmc-inspect compare current.zip previous.zip
# 完整参数
cmc-inspect compare current.zip previous.zip \
--current-version "B-103" \
--previous-version "B-102" \
--size-threshold 15.0 \
--temp-dir "./temp"
启动MCP服务器
# 使用默认配置
cmc-inspect-server
# 使用自定义配置
cmc-inspect-server --config config.json --verbose
MCP服务器使用
1. 启动服务器
uv run cmc-inspect-server
2. 连接到服务器
服务器将提供以下MCP工具:
analyze_package- 分析软件包compare_packages- 比较软件包(主要工具)extract_package- 解压软件包get_package_info- 获取包信息compare_packages_detailed- 详细比较quick_size_compare- 快速大小比较
Python API使用
基本分析示例
import asyncio
from pathlib import Path
from cmc_inspect import SizeAnalyzer, StructureAnalyzer, PackageInfo
from cmc_inspect.tools import PackageExtractor
async def analyze_package_example():
# 创建软件包信息
package_file = Path("example.zip")
package_info = PackageInfo(
name="example",
version="1.0.0",
file_path=package_file,
size_bytes=package_file.stat().st_size
)
# 解压软件包
extractor = PackageExtractor()
extracted_path = await extractor.extract(str(package_file))
package_info.extracted_path = Path(extracted_path)
# 执行分析
size_analyzer = SizeAnalyzer()
structure_analyzer = StructureAnalyzer()
size_result = await size_analyzer.analyze(package_info)
structure_result = await structure_analyzer.analyze(package_info)
print(f"软件包大小: {size_result['formatted_size']}")
print(f"文件数量: {structure_result.total_files}")
# 运行示例
asyncio.run(analyze_package_example())
比较分析示例
import asyncio
from cmc_inspect import SizeAnalyzer, StructureAnalyzer
from cmc_inspect.models import AnalysisResult, AnalysisInfo, SizeCheckResult, StructureCheckResult
async def compare_packages_example():
# 准备包信息(省略创建代码)
current_info = create_package_info("current.zip", "2.0.0")
previous_info = create_package_info("previous.zip", "1.0.0")
# 执行比较
size_analyzer = SizeAnalyzer()
structure_analyzer = StructureAnalyzer()
size_comparison = await size_analyzer.compare(current_info, previous_info)
structure_comparison = await structure_analyzer.compare(current_info, previous_info)
# 构建完整结果
result = AnalysisResult(
analysis_info=AnalysisInfo(
current_version="2.0.0",
previous_version="1.0.0"
),
overall_status="PASSED", # 根据检查结果确定
size_check=SizeCheckResult(**size_comparison),
structure_check=StructureCheckResult(**structure_comparison),
summary="" # 自动生成
)
# 输出JSON报告
print(result.to_json_output())
asyncio.run(compare_packages_example())
📋 API文档
核心类和方法
PackageInfo
class PackageInfo(BaseModel):
"""软件包信息模型"""
name: str # 软件包名称
version: str # 版本号
file_path: Path # 软件包文件路径
size_bytes: int # 文件大小(字节)
extracted_path: Optional[Path] # 解压后目录路径
created_at: datetime # 创建时间
AnalysisResult
class AnalysisResult(BaseModel):
"""分析结果模型"""
analysis_info: AnalysisInfo # 分析信息
overall_status: StatusType # 总体状态
size_check: SizeCheckResult # 大小检查结果
structure_check: StructureCheckResult # 结构检查结果
summary: str # 人类可读摘要
def to_json_output(self) -> str:
"""转换为JSON输出格式"""
@classmethod
def create_failed_result(cls, error_message: str) -> "AnalysisResult":
"""创建失败结果"""
SizeAnalyzer
class SizeAnalyzer(BaseAnalyzer):
"""软件包大小分析器"""
async def analyze(self, package_info: PackageInfo) -> Dict[str, Any]:
"""分析单个软件包的大小"""
async def compare(self, current: PackageInfo, previous: PackageInfo) -> Dict[str, Any]:
"""比较两个版本的软件包大小"""
StructureAnalyzer
class StructureAnalyzer(BaseAnalyzer):
"""目录结构分析器"""
async def analyze(self, package_info: PackageInfo) -> DirectoryStructure:
"""分析软件包的目录结构"""
async def compare(self, current: PackageInfo, previous: PackageInfo) -> Dict[str, Any]:
"""比较两个版本的目录结构"""
PackageExtractor
class PackageExtractor:
"""软件包解压器"""
async def extract(self, package_path: str, extract_dir: Optional[str] = None) -> str:
"""解压软件包到指定目录"""
@staticmethod
def get_supported_formats() -> List[str]:
"""获取支持的文件格式列表"""
@staticmethod
def is_supported_format(file_path: str) -> bool:
"""检查文件格式是否受支持"""
JSON输出格式
标准分析报告
{
"analysis_info": {
"current_version": "B-103",
"previous_version": "B-102",
"timestamp_utc": "2025-01-27T12:00:00Z"
},
"overall_status": "FAILED",
"size_check": {
"status": "FAILED",
"current_size_bytes": 15000000,
"previous_size_bytes": 10000000,
"change_percentage": 50.0,
"threshold_percentage": 15.0
},
"structure_check": {
"status": "WARNING",
"added_files": ["/config/new_feature.xml", "/lib/extra_lib.jar"],
"deleted_files": ["/config/old_setting.properties"],
"forbidden_files": []
},
"summary": "检查失败。软件包大小增加50%(超出15%阈值)。目录结构变更:新增2个文件,删除1个文件。"
}
状态说明
PASSED: 所有检查通过WARNING: 有变化但在可接受范围内FAILED: 检查失败,不建议继续
⚙️ 配置说明
配置文件格式 (JSON)
{
"analysis": {
"size_threshold_percentage": 15.0,
"size_warning_threshold_percentage": 12.0,
"forbidden_patterns": [
"*.log", "*.tmp", "*.temp",
".idea/", ".vscode/", ".git/",
"__pycache__/", "*.pyc", "*.pyo",
".DS_Store", "Thumbs.db",
"*.swp", "*.swo", "*~"
],
"temp_dir": "./temp/cmc_extract",
"cleanup_temp_files": true,
"verbose": false,
"max_listed_files": 50
},
"mcp": {
"server_name": "CMC软件包分析代理",
"server_version": "1.0.0",
"enable_analyze_tool": true,
"enable_compare_tool": true,
"enable_extract_tool": true
}
}
配置项说明
分析配置 (analysis)
size_threshold_percentage: 大小变化失败阈值(默认15%)size_warning_threshold_percentage: 大小变化警告阈值(默认12%)forbidden_patterns: 禁止的文件模式列表temp_dir: 临时解压目录cleanup_temp_files: 是否清理临时文件verbose: 是否详细输出max_listed_files: 最多列出的文件数量
MCP配置 (mcp)
server_name: MCP服务器名称server_version: 服务器版本enable_analyze_tool: 是否启用分析工具enable_compare_tool: 是否启用比较工具enable_extract_tool: 是否启用解压工具
环境变量支持
# 设置临时目录
export CMC_TEMP_DIR="/custom/temp/dir"
# 设置大小阈值
export CMC_SIZE_THRESHOLD="20.0"
# 启用详细输出
export CMC_VERBOSE="true"
🔧 开发指南
开发环境设置
1. 克隆和安装
git clone <repo-url>
cd cmc-inspect
uv sync --extra dev
2. 开发工具配置
# 代码格式化
uv run black src/ tests/
# 代码检查
uv run ruff check src/ tests/
# 类型检查
uv run mypy src/
3. 运行测试
# 运行所有测试
uv run pytest tests/ -v
# 运行特定测试
uv run pytest tests/test_basic.py -v
# 测试覆盖率
uv run pytest tests/ --cov=cmc_inspect
添加新的分析器
1. 创建分析器类
# src/cmc_inspect/analyzers/my_analyzer.py
from .base import BaseAnalyzer
from ..models.package_info import PackageInfo
class MyAnalyzer(BaseAnalyzer):
"""自定义分析器"""
async def analyze(self, package_info: PackageInfo) -> Dict[str, Any]:
"""实现分析逻辑"""
# 你的分析代码
return {"status": "PASSED", "details": "..."}
async def compare(self, current: PackageInfo, previous: PackageInfo) -> Dict[str, Any]:
"""实现比较逻辑"""
# 你的比较代码
return {"status": "PASSED", "changes": "..."}
2. 注册分析器
# src/cmc_inspect/analyzers/__init__.py
from .my_analyzer import MyAnalyzer
__all__ = [..., "MyAnalyzer"]
3. 添加MCP工具
# src/cmc_inspect/mcp_tools/my_tools.py
from fastmcp import FastMCP
from ..analyzers.my_analyzer import MyAnalyzer
def setup_my_tools(mcp: FastMCP, config: AnalysisConfig):
@mcp.tool()
async def my_analysis_tool(package_path: str) -> Dict[str, Any]:
"""自定义分析工具"""
analyzer = MyAnalyzer(config)
# 实现工具逻辑
return result
添加新的数据模型
1. 定义模型
# src/cmc_inspect/models/my_model.py
from pydantic import BaseModel, Field
from typing import List, Optional
class MyModel(BaseModel):
"""自定义数据模型"""
name: str = Field(..., description="名称")
items: List[str] = Field(default_factory=list, description="项目列表")
optional_field: Optional[str] = Field(None, description="可选字段")
def custom_method(self) -> str:
"""自定义方法"""
return f"Model: {self.name}"
2. 导出模型
# src/cmc_inspect/models/__init__.py
from .my_model import MyModel
__all__ = [..., "MyModel"]
测试编写
1. 单元测试
# tests/test_my_analyzer.py
import pytest
from cmc_inspect.analyzers.my_analyzer import MyAnalyzer
from cmc_inspect.models.package_info import PackageInfo
class TestMyAnalyzer:
def test_analyzer_creation(self):
"""测试分析器创建"""
analyzer = MyAnalyzer()
assert analyzer is not None
@pytest.mark.asyncio
async def test_analyze_function(self):
"""测试分析功能"""
analyzer = MyAnalyzer()
# 创建测试数据
package_info = create_test_package_info()
result = await analyzer.analyze(package_info)
assert result["status"] in ["PASSED", "WARNING", "FAILED"]
2. 集成测试
# tests/test_integration.py
import pytest
from cmc_inspect import create_mcp_server
@pytest.mark.asyncio
async def test_mcp_server_integration():
"""测试MCP服务器集成"""
server = create_mcp_server()
tools = server.list_tools()
assert "analyze_package" in tools
assert "compare_packages" in tools
性能优化
1. 异步操作
# 使用异步操作处理I/O密集任务
async def process_large_package(package_path: str):
async with aiofiles.open(package_path, 'rb') as f:
content = await f.read()
# 处理内容
2. 内存管理
# 分块处理大文件
def process_large_file_in_chunks(file_path: Path, chunk_size: int = 8192):
with open(file_path, 'rb') as f:
while chunk := f.read(chunk_size):
yield chunk
3. 缓存优化
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_calculation(package_hash: str) -> Dict[str, Any]:
"""缓存昂贵的计算结果"""
# 执行计算
return result
💡 示例代码
完整分析流程示例
#!/usr/bin/env python3
"""完整的软件包分析流程示例"""
import asyncio
import json
from pathlib import Path
from cmc_inspect import (
PackageInfo, AnalysisResult, AnalysisInfo,
SizeAnalyzer, StructureAnalyzer, PackageExtractor,
SizeCheckResult, StructureCheckResult
)
async def full_analysis_example():
"""完整分析流程示例"""
# 1. 准备软件包信息
current_path = Path("current-package.zip")
previous_path = Path("previous-package.zip")
current_info = PackageInfo(
name="my-app",
version="B-103",
file_path=current_path,
size_bytes=current_path.stat().st_size
)
previous_info = PackageInfo(
name="my-app",
version="B-102",
file_path=previous_path,
size_bytes=previous_path.stat().st_size
)
# 2. 解压软件包
extractor = PackageExtractor()
current_extracted = await extractor.extract(str(current_path))
previous_extracted = await extractor.extract(str(previous_path))
current_info.extracted_path = Path(current_extracted)
previous_info.extracted_path = Path(previous_extracted)
# 3. 执行分析
size_analyzer = SizeAnalyzer()
structure_analyzer = StructureAnalyzer()
# 大小比较
size_comparison = await size_analyzer.compare(current_info, previous_info)
print("大小比较结果:", size_comparison)
# 结构比较
structure_comparison = await structure_analyzer.compare(current_info, previous_info)
print("结构比较结果:", structure_comparison)
# 4. 构建完整结果
from datetime import datetime
result = AnalysisResult(
analysis_info=AnalysisInfo(
current_version=current_info.version,
previous_version=previous_info.version,
timestamp_utc=datetime.utcnow()
),
overall_status="PASSED", # 临时值
size_check=SizeCheckResult(**size_comparison),
structure_check=StructureCheckResult(**structure_comparison),
summary="" # 临时值
)
# 自动确定状态和摘要
result.overall_status = result.determine_overall_status()
result.summary = result.generate_summary()
# 5. 输出结果
print("\n=== 完整分析报告 ===")
print(result.to_json_output())
# 6. 清理临时文件
PackageExtractor.cleanup_directory(current_extracted)
PackageExtractor.cleanup_directory(previous_extracted)
return result
# 运行示例
if __name__ == "__main__":
asyncio.run(full_analysis_example())
MCP客户端使用示例
#!/usr/bin/env python3
"""MCP客户端使用示例"""
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def mcp_client_example():
"""MCP客户端使用示例"""
# 启动MCP服务器
server_params = StdioServerParameters(
command="uv",
args=["run", "cmc-inspect-server"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# 初始化
await session.initialize()
# 获取可用工具
tools = await session.list_tools()
print("可用工具:", [tool.name for tool in tools.tools])
# 调用分析工具
result = await session.call_tool(
"analyze_package",
arguments={
"package_path": "examples/sample_packages/example-package-v1.0.zip",
"package_version": "B-102"
}
)
print("分析结果:", result.content)
# 调用比较工具
comparison = await session.call_tool(
"compare_packages",
arguments={
"current_package_path": "examples/sample_packages/example-package-v2.0.zip",
"previous_package_path": "examples/sample_packages/example-package-v1.0.zip",
"current_version": "B-103",
"previous_version": "B-102"
}
)
print("比较结果:", comparison.content)
# 运行示例
if __name__ == "__main__":
asyncio.run(mcp_client_example())
自定义配置示例
#!/usr/bin/env python3
"""自定义配置使用示例"""
from cmc_inspect import AnalysisConfig, MCPServerConfig, SizeAnalyzer
# 创建自定义分析配置
custom_config = AnalysisConfig(
size_threshold_percentage=20.0, # 更宽松的大小阈值
size_warning_threshold_percentage=15.0,
forbidden_patterns=[
"*.log", "*.tmp", "*.cache",
"node_modules/", ".git/",
"*.secret", "*.key"
],
temp_dir="./custom_temp",
cleanup_temp_files=True,
verbose=True,
max_listed_files=100
)
# 创建自定义MCP配置
mcp_config = MCPServerConfig(
server_name="自定义CMC分析器",
server_version="2.0.0",
enable_analyze_tool=True,
enable_compare_tool=True,
enable_extract_tool=False # 禁用解压工具
)
# 使用自定义配置
async def custom_config_example():
"""自定义配置使用示例"""
# 使用自定义配置创建分析器
analyzer = SizeAnalyzer(custom_config)
# 创建自定义MCP服务器
from cmc_inspect import create_mcp_server
server = create_mcp_server(custom_config, mcp_config)
print("自定义服务器已创建")
print(f"服务器名称: {mcp_config.server_name}")
print(f"配置的大小阈值: {custom_config.size_threshold_percentage}%")
# 从文件加载配置
def load_config_from_file(config_path: str):
"""从文件加载配置"""
import json
from pathlib import Path
config_file = Path(config_path)
if not config_file.exists():
raise FileNotFoundError(f"配置文件不存在: {config_path}")
with open(config_file, 'r', encoding='utf-8') as f:
config_data = json.load(f)
analysis_config = AnalysisConfig(**config_data.get("analysis", {}))
mcp_config = MCPServerConfig(**config_data.get("mcp", {}))
return analysis_config, mcp_config
# 使用示例
if __name__ == "__main__":
# 使用自定义配置
asyncio.run(custom_config_example())
# 从文件加载配置
try:
analysis_cfg, mcp_cfg = load_config_from_file("examples/config.json")
print(f"从文件加载的配置: {analysis_cfg.size_threshold_percentage}%")
except FileNotFoundError as e:
print(f"配置文件加载失败: {e}")
🔍 故障排除
常见问题
1. 导入错误
问题: ModuleNotFoundError: No module named 'cmc_inspect'
解决方案:
# 确保正确安装项目
uv pip install -e .
# 或者使用uv运行
uv run python your_script.py
2. 解压失败
问题: ValueError: 不支持的文件格式
解决方案:
# 检查支持的格式
from cmc_inspect.tools import PackageExtractor
supported = PackageExtractor.get_supported_formats()
print("支持的格式:", supported)
# 对于7z文件,安装额外依赖
# pip install py7zr
3. 权限错误
问题: PermissionError: [WinError 5] 拒绝访问
解决方案:
# 确保临时目录有写权限
import os
temp_dir = "./temp"
os.makedirs(temp_dir, exist_ok=True)
os.access(temp_dir, os.W_OK) # 检查写权限
# 或者使用不同的临时目录
config = AnalysisConfig(temp_dir="/tmp/cmc_extract")
4. 大文件处理
问题: 处理大文件时内存不足 解决方案:
# 增加内存限制
import resource
resource.setrlimit(resource.RLIMIT_AS, (2**30, 2**30)) # 1GB限制
# 或者分块处理
def process_large_archive(archive_path, chunk_size=1024*1024):
# 分块处理逻辑
pass
调试技巧
1. 启用详细日志
import logging
logging.basicConfig(level=logging.DEBUG)
# 或者使用配置
config = AnalysisConfig(verbose=True)
2. 保留临时文件
config = AnalysisConfig(cleanup_temp_files=False)
# 分析完成后检查临时目录内容
3. 使用调试模式
# 使用调试模式运行
uv run python -m pdb your_script.py
# 或者在代码中添加断点
import pdb; pdb.set_trace()
性能优化建议
1. 大型软件包处理
- 使用异步操作
- 分块读取大文件
- 设置合理的内存限制
2. 网络环境
- 配置代理设置
- 使用本地缓存
- 并行处理多个包
3. CI/CD集成
- 使用Docker容器隔离
- 配置适当的超时时间
- 实现重试机制
获取帮助
如果遇到其他问题,可以:
- 查看日志: 启用详细模式获取更多信息
- 检查配置: 确认配置文件格式正确
- 运行测试: 验证基本功能是否正常
- 查看示例: 参考examples目录中的示例代码
- 提交问题: 在项目仓库中提交Issue
📄 许可证
MIT License - 详见 LICENSE 文件
🤝 贡献
欢迎提交Pull Request和Issue!
📞 联系方式
- 作者: SillyDog5254
- 邮箱: ruyileng26@gmail.com
祝您使用愉快!🎉
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.