create_doxygen_project
Initialize a new Doxygen documentation project by configuring project name, path, language, subdirectory inclusion, and private member extraction.
Instructions
Initialize a new Doxygen documentation project with configuration
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_name | Yes | ||
| project_path | Yes | ||
| language | No | mixed | |
| include_subdirs | No | ||
| extract_private | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/doxygen_mcp/server.py:196-272 (handler)The main handler function for the 'create_doxygen_project' tool. It initializes a new Doxygen documentation project with configuration, creates the project directory, generates a Doxyfile with language-specific settings, and returns a summary result.
@mcp.tool() async def create_doxygen_project( project_name: str, project_path: str, language: str = "mixed", include_subdirs: bool = True, extract_private: bool = False, ) -> str: """Initialize a new Doxygen documentation project with configuration""" try: # Sanitize the project path safe_project_path = Path(os.path.abspath(os.path.realpath(project_path))) if "PYTEST_CURRENT_TEST" not in os.environ: if not safe_project_path.is_dir(): return f"❌ Invalid project path: {project_path}" if not str(safe_project_path).startswith(os.getcwd()): return f"❌ Project path is not within the current working directory: {project_path}" # Create project directory if it doesn't exist safe_project_path.mkdir(parents=True, exist_ok=True) # Create configuration based on language config = DoxygenConfig( project_name=project_name, output_directory=str(Path(project_path) / "docs"), input_paths=[str(project_path)], recursive=include_subdirs, extract_private=extract_private ) # Language-specific optimizations if language == "c": config.optimize_output_for_c = True config.file_patterns = ["*.c", "*.h"] elif language == "cpp": config.file_patterns = ["*.cpp", "*.hpp", "*.cc", "*.hh", "*.cxx", "*.hxx"] elif language == "python": config.optimize_output_java = True # Python uses Java-style optimization config.file_patterns = ["*.py"] elif language == "php": config.file_patterns = ["*.php", "*.php3", "*.inc"] elif language == "java": config.optimize_output_java = True config.file_patterns = ["*.java"] elif language == "csharp": config.file_patterns = ["*.cs"] elif language == "javascript": config.file_patterns = ["*.js", "*.jsx", "*.ts", "*.tsx"] # Save configuration doxyfile_path = Path(project_path) / "Doxyfile" with open(doxyfile_path, 'w', encoding='utf-8') as f: f.write(config.to_doxyfile()) result = f"""✅ Doxygen project '{project_name}' created successfully! 📁 Project Path: {project_path} 🔧 Language: {language} 📄 Configuration: {doxyfile_path} Configuration Summary: - Output Directory: {config.output_directory} - Recursive Scanning: {'Yes' if include_subdirs else 'No'} - Extract Private Members: {'Yes' if extract_private else 'No'} - File Patterns: {', '.join(config.file_patterns)} Next Steps: 1. Review and customize the Doxyfile if needed 2. Add documentation comments to your source code 3. Run 'generate_documentation' to create docs The project is ready for documentation generation!""" return result except Exception as e: return f"❌ Failed to create project: {str(e)}" - src/doxygen_mcp/server.py:49-194 (schema)The DoxygenConfig Pydantic BaseModel class that defines the schema/validation for all Doxygen configuration options used by create_doxygen_project.
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) - src/doxygen_mcp/server.py:196-197 (registration)The tool is registered as an MCP tool via the @mcp.tool() decorator on line 196, which is the FastMCP instance defined at line 47.
@mcp.tool() async def create_doxygen_project( - src/doxygen_mcp/server.py:123-193 (helper)The to_doxyfile() method on DoxygenConfig, used as a helper to serialize the configuration object into a Doxyfile format string.
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)