scan_project
Analyze a project's structure to identify gaps and opportunities for Doxygen documentation.
Instructions
Analyze project structure and identify documentation opportunities
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/doxygen_mcp/server.py:343-380 (handler)The main handler function for the 'scan_project' tool. It analyzes a project directory by recursively counting files grouped by extension, then returns a formatted report of the top 15 file types.
@mcp.tool() async def scan_project( project_path: str, ) -> str: """Analyze project structure and identify documentation opportunities""" project_path = Path(project_path) if not project_path.exists(): return f"❌ Project path does not exist: {project_path}" try: # Count files by extension extensions = {} total_files = 0 for file_path in project_path.rglob("*"): if file_path.is_file(): ext = file_path.suffix.lower() if ext: extensions[ext] = extensions.get(ext, 0) + 1 total_files += 1 # Sort by frequency sorted_extensions = sorted(extensions.items(), key=lambda x: x[1], reverse=True) result_text = f"""📁 Project Scan Results for: {project_path} 📊 Total Files Found: {total_files} 📋 Files by Type: """ for ext, count in sorted_extensions[:15]: # Show top 15 extensions result_text += f" 📄 {ext}: {count} files\n" return result_text except Exception as e: return f"❌ Error scanning project: {str(e)}" - src/doxygen_mcp/server.py:343-343 (registration)Registration of scan_project as an MCP tool via the @mcp.tool() decorator on the FastMCP instance 'mcp'.
@mcp.tool() - src/doxygen_mcp/server.py:49-193 (helper)The DoxygenConfig model (lines 49-193) is a supporting class used by other tools (e.g., create_doxygen_project) that pair with scan_project to enable full project setup workflows.
class DoxygenConfig(BaseModel): """ @brief Represents a Doxygen configuration with all major options This class encapsulates all the major configuration options available in Doxygen, providing a structured way to manage documentation generation settings. It supports multiple programming languages, output formats, and advanced features like diagram generation and source browsing. @details The configuration is designed to be language-agnostic while providing specific optimizations for different programming languages. It can generate Doxyfile content that is compatible with Doxygen 1.9.0 and later. @example @code{.py} config = DoxygenConfig( project_name="My API Documentation", output_directory="./docs", file_patterns=["*.cpp", "*.h"], extract_private=False ) doxyfile_content = config.to_doxyfile() @endcode """ # Project settings project_name: str = "My Project" project_number: str = "" project_brief: str = "" project_logo: str = "" output_directory: str = "./docs" # Input settings input_paths: List[str] = ["."] file_patterns: List[str] = ["*.c", "*.cpp", "*.h", "*.hpp", "*.py", "*.php"] recursive: bool = True exclude_patterns: List[str] = [] # Language optimization optimize_output_for_c: bool = False optimize_output_java: bool = False optimize_for_fortran: bool = False optimize_output_vhdl: bool = False # Output formats generate_html: bool = True generate_latex: bool = False generate_rtf: bool = False generate_man: bool = False generate_xml: bool = False generate_docbook: bool = False # Documentation extraction extract_all: bool = True extract_private: bool = False extract_static: bool = True extract_local_classes: bool = True # Diagram generation have_dot: bool = True class_graph: bool = True collaboration_graph: bool = True call_graph: bool = False caller_graph: bool = False include_graph: bool = True included_by_graph: bool = True # Advanced features source_browser: bool = True inline_sources: bool = False strip_code_comments: bool = True referenced_by_relation: bool = True references_relation: bool = True def to_doxyfile(self) -> str: """ @brief Convert configuration to Doxyfile format @return String containing complete Doxyfile configuration @details Generates a complete Doxyfile configuration string that can be written to disk and used with the doxygen command-line tool. The output includes all configured options with appropriate YES/NO values and proper escaping for file paths and patterns. @note The generated Doxyfile is compatible with Doxygen 1.9.0+ """ lines = [ f"# Doxyfile generated by Doxygen MCP Server", f"", f"# Project related configuration options", f"PROJECT_NAME = \"{self.project_name}\"", f"PROJECT_NUMBER = \"{self.project_number}\"", f"PROJECT_BRIEF = \"{self.project_brief}\"", f"PROJECT_LOGO = \"{self.project_logo}\"", f"OUTPUT_DIRECTORY = \"{self.output_directory}\"", f"", f"# Build related configuration options", f"EXTRACT_ALL = {'YES' if self.extract_all else 'NO'}", f"EXTRACT_PRIVATE = {'YES' if self.extract_private else 'NO'}", f"EXTRACT_STATIC = {'YES' if self.extract_static else 'NO'}", f"EXTRACT_LOCAL_CLASSES = {'YES' if self.extract_local_classes else 'NO'}", f"", f"# Input related configuration options", f"INPUT = {' '.join(self.input_paths)}", f"FILE_PATTERNS = {' '.join(self.file_patterns)}", f"RECURSIVE = {'YES' if self.recursive else 'NO'}", ] if self.exclude_patterns: lines.append(f"EXCLUDE_PATTERNS = {' '.join(self.exclude_patterns)}") lines.extend([ f"", f"# Language optimization", f"OPTIMIZE_OUTPUT_FOR_C = {'YES' if self.optimize_output_for_c else 'NO'}", f"OPTIMIZE_OUTPUT_JAVA = {'YES' if self.optimize_output_java else 'NO'}", f"OPTIMIZE_FOR_FORTRAN = {'YES' if self.optimize_for_fortran else 'NO'}", f"OPTIMIZE_OUTPUT_VHDL = {'YES' if self.optimize_output_vhdl else 'NO'}", f"", f"# Output format configuration", f"GENERATE_HTML = {'YES' if self.generate_html else 'NO'}", f"GENERATE_LATEX = {'YES' if self.generate_latex else 'NO'}", f"GENERATE_RTF = {'YES' if self.generate_rtf else 'NO'}", f"GENERATE_MAN = {'YES' if self.generate_man else 'NO'}", f"GENERATE_XML = {'YES' if self.generate_xml else 'NO'}", f"GENERATE_DOCBOOK = {'YES' if self.generate_docbook else 'NO'}", f"", f"# Diagram generation", f"HAVE_DOT = {'YES' if self.have_dot else 'NO'}", f"CLASS_GRAPH = {'YES' if self.class_graph else 'NO'}", f"COLLABORATION_GRAPH = {'YES' if self.collaboration_graph else 'NO'}", f"CALL_GRAPH = {'YES' if self.call_graph else 'NO'}", f"CALLER_GRAPH = {'YES' if self.caller_graph else 'NO'}", f"INCLUDE_GRAPH = {'YES' if self.include_graph else 'NO'}", f"INCLUDED_BY_GRAPH = {'YES' if self.included_by_graph else 'NO'}", f"", f"# Source browsing", f"SOURCE_BROWSER = {'YES' if self.source_browser else 'NO'}", f"INLINE_SOURCES = {'YES' if self.inline_sources else 'NO'}", f"STRIP_CODE_COMMENTS = {'YES' if self.strip_code_comments else 'NO'}", f"REFERENCED_BY_RELATION = {'YES' if self.referenced_by_relation else 'NO'}", f"REFERENCES_RELATION = {'YES' if self.references_relation else 'NO'}", ]) return "\n".join(lines)