Skip to main content
Glama
dev.py6.57 kB
#!/usr/bin/env python3 """Development utilities for AutoDocs MCP Server.""" import asyncio import json from pathlib import Path import click from autodoc_mcp.config import get_config from autodoc_mcp.core.cache_manager import FileCacheManager from autodoc_mcp.core.dependency_parser import PyProjectParser from autodoc_mcp.core.doc_fetcher import PyPIDocumentationFetcher from autodoc_mcp.core.version_resolver import VersionResolver @click.group() def cli(): """Development tools for AutoDocs MCP.""" pass @cli.command() @click.option("--project-path", type=click.Path(exists=True), default=".") def test_scan(project_path): """Test dependency scanning locally.""" async def run_test(): parser = PyProjectParser() project_dir = Path(project_path) try: result = await parser.parse_project(project_dir) # Convert to MCP tool response format mcp_result = { "success": True, "partial_success": result.partial_success, "project_path": str(result.project_path), "project_name": result.project_name, "dependencies": [ { "name": dep.name, "version_constraint": dep.version_constraint, "extras": dep.extras, "source": dep.source, } for dep in result.dependencies ], "scan_timestamp": result.scan_timestamp.isoformat(), "successful_deps": result.successful_deps, "total_dependencies": len(result.dependencies), "failed_deps": result.failed_deps, "warnings": result.warnings, "errors": result.errors, } click.echo(json.dumps(mcp_result, indent=2, default=str)) except Exception as e: error_result = { "success": False, "error": {"type": type(e).__name__, "message": str(e)}, } click.echo(json.dumps(error_result, indent=2, default=str)) asyncio.run(run_test()) @cli.command() @click.option("--project-path", type=click.Path(exists=True), default=".") def validate_project(project_path): """Validate that a project can be scanned.""" from autodoc_mcp.core.dependency_parser import PyProjectParser parser = PyProjectParser() project_dir = Path(project_path) pyproject_file = project_dir / "pyproject.toml" if not pyproject_file.exists(): click.echo(f"❌ No pyproject.toml found in {project_dir}") return is_valid = parser.validate_file(pyproject_file) if is_valid: click.echo(f"✅ Valid pyproject.toml found in {project_dir}") else: click.echo(f"⚠️ pyproject.toml exists but appears invalid in {project_dir}") @cli.command() @click.argument("package_name") @click.option("--version-constraint", help='Version constraint like ">=2.0.0"') @click.option("--query", help="Filter query for documentation") def test_docs(package_name, version_constraint, query): """Test documentation fetching locally.""" async def run_test(): config = get_config() cache_manager = FileCacheManager(config.cache_dir) version_resolver = VersionResolver() await cache_manager.initialize() try: click.echo(f"🔍 Resolving version for {package_name}...") resolved_version = await version_resolver.resolve_version( package_name, version_constraint ) cache_key = version_resolver.generate_cache_key( package_name, resolved_version ) click.echo(f"📦 Resolved: {package_name} -> v{resolved_version}") click.echo(f"🔑 Cache key: {cache_key}") # Check cache first cached_entry = await cache_manager.get(cache_key) if cached_entry: click.echo("✅ Found in cache!") package_info = cached_entry.data from_cache = True else: click.echo("🌐 Fetching from PyPI...") async with PyPIDocumentationFetcher() as fetcher: package_info = await fetcher.fetch_package_info(package_name) await cache_manager.set(cache_key, package_info) from_cache = False # Format documentation async with PyPIDocumentationFetcher() as fetcher: docs = fetcher.format_documentation(package_info, query) result = { "success": True, "package_name": package_info.name, "version": package_info.version, "resolved_version": resolved_version, "version_constraint": version_constraint, "from_cache": from_cache, "cache_key": cache_key, "documentation": docs, } click.echo(json.dumps(result, indent=2, default=str)) except Exception as e: error_result = { "success": False, "error": {"type": type(e).__name__, "message": str(e)}, } click.echo(json.dumps(error_result, indent=2, default=str)) asyncio.run(run_test()) @cli.command() def cache_stats(): """Show cache statistics.""" async def run_test(): config = get_config() cache_manager = FileCacheManager(config.cache_dir) await cache_manager.initialize() stats = await cache_manager.get_cache_stats() packages = await cache_manager.list_cached_packages() result = { "cache_stats": stats, "cached_packages": packages, "total_packages": len(packages), } click.echo(json.dumps(result, indent=2, default=str)) asyncio.run(run_test()) @cli.command() def clear_cache(): """Clear the documentation cache.""" async def run_test(): config = get_config() cache_manager = FileCacheManager(config.cache_dir) await cache_manager.initialize() initial_stats = await cache_manager.get_cache_stats() await cache_manager.invalidate() click.echo(f"✅ Cleared {initial_stats.get('total_entries', 0)} cache entries") click.echo(f"💾 Freed {initial_stats.get('total_size_bytes', 0)} bytes") asyncio.run(run_test()) if __name__ == "__main__": cli()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bradleyfay/autodoc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server