mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
a4fd71c10b
Add new MCP tool 'diagnostics' that provides: - Basic Memory version and API version information - System details (Python, OS, architecture) - Configuration summary (projects, database, sync settings) - Tool availability with categorization - Project context and status - Robust error handling with troubleshooting guidance The tool helps users troubleshoot installations, verify features, and gather system information for support requests. Files added: - src/basic_memory/mcp/tools/diagnostics.py: Main diagnostic tool implementation - tests/mcp/test_tool_diagnostics.py: Comprehensive test suite with 11 test functions Files modified: - src/basic_memory/mcp/tools/__init__.py: Added diagnostics tool to exports Resolves #187 Co-authored-by: Drew Cain <groksrc@users.noreply.github.com>
236 lines
8.4 KiB
Python
236 lines
8.4 KiB
Python
"""Diagnostic tool for Basic Memory MCP server."""
|
|
|
|
import platform
|
|
import sys
|
|
from typing import Optional
|
|
from pathlib import Path
|
|
|
|
from loguru import logger
|
|
|
|
from basic_memory.mcp.server import mcp
|
|
from basic_memory.mcp.project_session import get_active_project
|
|
import basic_memory
|
|
|
|
|
|
def _get_system_info() -> list[str]:
|
|
"""Get system information for diagnostic output."""
|
|
info_lines = []
|
|
|
|
try:
|
|
info_lines.extend([
|
|
f"**Python Version**: {sys.version.split()[0]}",
|
|
f"**Platform**: {platform.system()} {platform.release()}",
|
|
f"**Architecture**: {platform.machine()}",
|
|
f"**Python Implementation**: {platform.python_implementation()}",
|
|
])
|
|
|
|
# Add Python executable path
|
|
info_lines.append(f"**Python Executable**: {sys.executable}")
|
|
|
|
# Add current working directory
|
|
info_lines.append(f"**Working Directory**: {Path.cwd()}")
|
|
|
|
except Exception as e:
|
|
logger.debug(f"Could not get some system info: {e}")
|
|
info_lines.append(f"**System Info Error**: {str(e)}")
|
|
|
|
return info_lines
|
|
|
|
|
|
def _get_configuration_summary() -> list[str]:
|
|
"""Get configuration summary for diagnostic output."""
|
|
config_lines = []
|
|
|
|
try:
|
|
from basic_memory.config import app_config, config_manager
|
|
|
|
config_lines.extend([
|
|
f"**Environment**: {app_config.env}",
|
|
f"**Log Level**: {app_config.log_level}",
|
|
f"**Default Project**: {app_config.default_project}",
|
|
f"**Total Projects**: {len(app_config.projects)}",
|
|
f"**Sync Delay**: {app_config.sync_delay}ms",
|
|
f"**Update Permalinks on Move**: {app_config.update_permalinks_on_move}",
|
|
f"**Sync Changes**: {app_config.sync_changes}",
|
|
])
|
|
|
|
# Add database info
|
|
config_lines.append(f"**Database Path**: {app_config.app_database_path}")
|
|
config_lines.append(f"**Config Directory**: {config_manager.config_dir}")
|
|
|
|
# Add project list
|
|
if app_config.projects:
|
|
config_lines.extend(["", "**Configured Projects**:"])
|
|
for name, path in app_config.projects.items():
|
|
is_default = " (default)" if name == app_config.default_project else ""
|
|
config_lines.append(f"- {name}: {path}{is_default}")
|
|
|
|
except Exception as e:
|
|
logger.debug(f"Could not get configuration info: {e}")
|
|
config_lines.append(f"**Configuration Error**: {str(e)}")
|
|
|
|
return config_lines
|
|
|
|
|
|
def _get_tool_availability() -> list[str]:
|
|
"""Get available MCP tools for diagnostic output."""
|
|
tool_lines = []
|
|
|
|
try:
|
|
# List of expected tools based on the __init__.py file
|
|
expected_tools = [
|
|
"build_context", "canvas", "create_project", "delete_note",
|
|
"delete_project", "edit_note", "get_current_project", "list_directory",
|
|
"list_projects", "move_note", "read_content", "read_note",
|
|
"recent_activity", "search_notes", "set_default_project",
|
|
"switch_project", "sync_status", "view_note", "write_note",
|
|
"diagnostics" # Include this tool itself
|
|
]
|
|
|
|
tool_lines.extend([
|
|
f"**Available Tools**: {len(expected_tools)}",
|
|
"",
|
|
"**Tool List**:"
|
|
])
|
|
|
|
# Group tools by category for better readability
|
|
categories = {
|
|
"Content Management": [
|
|
"write_note", "read_note", "edit_note", "delete_note",
|
|
"move_note", "view_note", "read_content"
|
|
],
|
|
"Project Management": [
|
|
"list_projects", "switch_project", "get_current_project",
|
|
"create_project", "delete_project", "set_default_project"
|
|
],
|
|
"Navigation & Discovery": [
|
|
"build_context", "list_directory", "search_notes", "recent_activity"
|
|
],
|
|
"Visualization": ["canvas"],
|
|
"System": ["sync_status", "diagnostics"]
|
|
}
|
|
|
|
for category, tools in categories.items():
|
|
tool_lines.append(f"- **{category}**: {', '.join(tools)}")
|
|
|
|
except Exception as e:
|
|
logger.debug(f"Could not get tool availability: {e}")
|
|
tool_lines.append(f"**Tool Availability Error**: {str(e)}")
|
|
|
|
return tool_lines
|
|
|
|
|
|
@mcp.tool(
|
|
description="""Get comprehensive diagnostic information for Basic Memory installation.
|
|
|
|
This tool provides:
|
|
- Basic Memory version and build information
|
|
- System environment details (Python, OS, architecture)
|
|
- Configuration summary and project status
|
|
- Available MCP tools and their categories
|
|
- Current project context
|
|
|
|
Use this tool to:
|
|
- Troubleshoot installation issues
|
|
- Verify feature availability
|
|
- Confirm system compatibility
|
|
- Support debugging and issue reporting
|
|
- Check configuration status
|
|
""",
|
|
)
|
|
async def diagnostics(project: Optional[str] = None) -> str:
|
|
"""Get comprehensive diagnostic information for Basic Memory.
|
|
|
|
This tool provides detailed information about the Basic Memory installation,
|
|
system environment, configuration, and available functionality.
|
|
|
|
Args:
|
|
project: Optional project name to include project-specific context
|
|
|
|
Returns:
|
|
Comprehensive diagnostic report with version, system, and status information
|
|
"""
|
|
logger.info("MCP tool call tool=diagnostics")
|
|
|
|
diagnostic_lines = []
|
|
|
|
try:
|
|
# Header
|
|
diagnostic_lines.extend([
|
|
"# Basic Memory Diagnostics",
|
|
"",
|
|
f"**Version**: {basic_memory.__version__}",
|
|
f"**API Version**: {basic_memory.__api_version__}",
|
|
"",
|
|
])
|
|
|
|
# System Information
|
|
diagnostic_lines.extend(["## System Information", ""])
|
|
diagnostic_lines.extend(_get_system_info())
|
|
diagnostic_lines.extend(["", ""])
|
|
|
|
# Configuration Summary
|
|
diagnostic_lines.extend(["## Configuration", ""])
|
|
diagnostic_lines.extend(_get_configuration_summary())
|
|
diagnostic_lines.extend(["", ""])
|
|
|
|
# Tool Availability
|
|
diagnostic_lines.extend(["## Tool Availability", ""])
|
|
diagnostic_lines.extend(_get_tool_availability())
|
|
diagnostic_lines.extend(["", ""])
|
|
|
|
# Project Context
|
|
diagnostic_lines.extend(["## Project Context", ""])
|
|
if project:
|
|
try:
|
|
active_project = get_active_project(project)
|
|
diagnostic_lines.extend([
|
|
f"**Requested Project**: {project}",
|
|
f"**Active Project Name**: {active_project.name}",
|
|
f"**Project Path**: {active_project.home}",
|
|
])
|
|
except Exception as e:
|
|
diagnostic_lines.extend([
|
|
f"**Requested Project**: {project}",
|
|
f"**Project Error**: {str(e)}",
|
|
])
|
|
else:
|
|
try:
|
|
from basic_memory.config import app_config
|
|
diagnostic_lines.extend([
|
|
f"**Default Project**: {app_config.default_project}",
|
|
"**Note**: Use the 'project' parameter to get specific project context",
|
|
])
|
|
except Exception as e:
|
|
diagnostic_lines.append(f"**Project Context Error**: {str(e)}")
|
|
|
|
diagnostic_lines.extend(["", ""])
|
|
|
|
# Footer with usage info
|
|
diagnostic_lines.extend([
|
|
"## Usage Notes",
|
|
"",
|
|
"- This diagnostic tool helps troubleshoot Basic Memory installations",
|
|
"- Share this output when reporting issues for faster support",
|
|
"- All sensitive paths and personal information should be reviewed before sharing",
|
|
"- For more detailed logging, check the Basic Memory log files in ~/.basic-memory/",
|
|
])
|
|
|
|
return "\n".join(diagnostic_lines)
|
|
|
|
except Exception as e:
|
|
return f"""# Basic Memory Diagnostics - Error
|
|
|
|
❌ **Unable to generate diagnostic information**: {str(e)}
|
|
|
|
**Troubleshooting:**
|
|
- The system may still be starting up
|
|
- Try waiting a few seconds and checking again
|
|
- Check logs for detailed error information
|
|
- Consider restarting if the issue persists
|
|
|
|
**Basic Information:**
|
|
- Basic Memory Version: {getattr(basic_memory, '__version__', 'Unknown')}
|
|
- Python Version: {sys.version.split()[0]}
|
|
- Platform: {platform.system()} {platform.release()}
|
|
""" |