UNPKG

dhis2-mcp-server

Version:

A Model Context Protocol server providing 108 tools for DHIS2 development, including code generators, debugging helpers, and documentation access for web and Android app development.

1,174 lines (1,161 loc) • 65.3 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, CompleteRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { DHIS2Client } from './dhis2-client.js'; import { createDevelopmentTools, createAPITools } from './tools/index.js'; import { auditLogger } from './audit-logger.js'; import { ConfirmationSystem } from './confirmation-system.js'; import { PermissionSystem } from './permission-system.js'; import { ParameterCompletion } from './parameter-completion.js'; import { MultiServerComposition } from './multi-server-composition.js'; import { generateWebAppInitInstructions, generateManifestContent, generateBuildSystemConfig, generateDevEnvironmentConfig, generateAppRuntimeConfig, generateAuthenticationPatterns, generateUIComponents, generateUIFormPatterns, generateUIDataDisplayPatterns, generateUINavigationLayout, generateDesignSystemConfig, generateAndroidMaterialForm, generateAndroidListAdapter, generateAndroidNavigationDrawer, generateAndroidBottomSheet, generateTestSetup } from './webapp-generators.js'; import { diagnoseCORSIssues, generateCORSConfiguration, debugAuthentication, generateProxyConfiguration, resolveBuildIssues, generatePerformanceOptimizations, validateEnvironment, generateMigrationGuide } from './debugging-helpers.js'; import { generateAndroidProjectInit, generateGradleBuildConfig, generateSyncConfiguration, generateLocationServicesConfig, generateStorageConfiguration, generateCameraConfiguration, generateAndroidAuthenticationConfig, generateDataModelsConfiguration, generateAndroidTestingConfiguration, generateAndroidUIConfiguration, generateOfflineAnalyticsConfiguration, generateNotificationsConfiguration, generatePerformanceOptimizationConfiguration } from './android-generators.js'; function filterUndefinedValues(obj) { const filtered = {}; for (const [key, value] of Object.entries(obj)) { if (value !== undefined) { filtered[key] = value; } } return filtered; } // Helper function to add audit logging to successful operations function logSuccessfulOperation(toolName, params, result, startTime, resourcesAffected) { auditLogger.log({ toolName, parameters: params, outcome: 'success', dhis2Instance: dhis2Client?.baseURL, userId: currentUser?.username, executionTime: Date.now() - startTime, ...(resourcesAffected && { resourcesAffected }) }); } const server = new Server({ name: 'dhis2-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, }); let dhis2Client = null; let tools = createDevelopmentTools(); // Initialize with development tools immediately let userPermissions = PermissionSystem.createDefaultPermissions(); let currentUser = null; let parameterCompletion = new ParameterCompletion(null); let multiServerComposition = new MultiServerComposition(); server.setRequestHandler(ListToolsRequestSchema, async () => { // Filter tools based on user permissions const filteredTools = PermissionSystem.filterToolsByPermissions(tools, userPermissions); return { tools: filteredTools, }; }); server.setRequestHandler(CompleteRequestSchema, async (request) => { const { ref, argument } = request.params; try { // Extract current argument values from context for tool-specific completions const context = argument?.name ? { [argument.name]: argument.value } : {}; const toolName = typeof ref === 'object' && 'name' in ref ? ref.name : ''; const argumentName = argument?.name || ''; const partialValue = typeof argument?.value === 'string' ? argument.value : undefined; const completion = await parameterCompletion.getCompletion(toolName, argumentName, partialValue); // Also try tool-specific completions if (toolName && argumentName) { const toolSpecific = await parameterCompletion.getToolSpecificCompletion(toolName, argumentName, context); if (toolSpecific.values.length > 0) { completion.values = [...toolSpecific.values, ...completion.values]; } } return { completion: { values: completion.values.slice(0, 50), // Limit to 50 suggestions hasMore: completion.values.length > 50 } }; } catch (error) { console.error('Error in completion handler:', error); return { completion: { values: [], hasMore: false } }; } }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const startTime = Date.now(); // Check if tool requires confirmation and isn't already confirmed const argsWithConfirmation = args; if (ConfirmationSystem.requiresConfirmation(name) && !argsWithConfirmation.confirmed) { const confirmationRequest = ConfirmationSystem.getConfirmationRequest(name, argsWithConfirmation); if (confirmationRequest) { const confirmationMessage = ConfirmationSystem.generateConfirmationMessage(confirmationRequest); // Log the confirmation request auditLogger.log({ toolName: name, parameters: args, outcome: 'error', error: 'Confirmation required', dhis2Instance: dhis2Client?.baseURL }); return { content: [{ type: 'text', text: confirmationMessage }], isError: true }; } } try { switch (name) { case 'dhis2_configure': const { baseUrl, username, password } = args; dhis2Client = new DHIS2Client(baseUrl, username, password); await dhis2Client.testConnection(); // Update parameter completion with the new client parameterCompletion = new ParameterCompletion(dhis2Client); // Fetch user information and permissions try { currentUser = await dhis2Client.getCurrentUser(); userPermissions = PermissionSystem.extractPermissionsFromDHIS2User(currentUser); } catch (error) { console.warn('Could not fetch user permissions, using defaults:', error); userPermissions = PermissionSystem.createDefaultPermissions(); } tools = [...createDevelopmentTools(), ...createAPITools()]; // Log successful connection auditLogger.log({ toolName: name, parameters: { baseUrl, username: '***REDACTED***' }, outcome: 'success', dhis2Instance: baseUrl, userId: currentUser?.username || username, executionTime: Date.now() - startTime }); const permissionSummary = PermissionSystem.getPermissionSummary(userPermissions); return { content: [ { type: 'text', text: `āœ… Successfully connected to DHIS2 instance at ${baseUrl} šŸ‘¤ User: ${currentUser?.displayName || username} šŸ” Permission Level: ${permissionSummary.level} šŸ“ ${permissionSummary.description} šŸ› ļø Available Tools: ${PermissionSystem.filterToolsByPermissions(tools, userPermissions).length} of ${tools.length} total tools • Development tools: Available without connection āœ… • API tools: Now available with connection āœ… āœ… Allowed Operations: ${permissionSummary.allowedOperations.map(op => ` • ${op}`).join('\n')} ${permissionSummary.restrictedOperations.length > 0 ? `ā›” Restricted Operations: ${permissionSummary.restrictedOperations.map(op => ` • ${op}`).join('\n')}` : ''} šŸ” All tools starting with 'dhis2_' are now available for development and API access.`, }, ], }; default: // Check if this tool requires DHIS2 connection const apiTools = createAPITools().map(t => t.name); if (apiTools.includes(name) && !dhis2Client) { return { content: [ { type: 'text', text: `āŒ **Connection Required** The tool \`${name}\` requires a DHIS2 instance connection to function. šŸš€ **Quick Setup - Choose Your Option:** **Option 1: Public Demo (Fastest)** Use the \`dhis2_configure\` tool with these demo credentials: \`\`\`json { "baseUrl": "https://play.dhis2.org/2.40.4", "username": "admin", "password": "district" } \`\`\` **Option 2: Local Docker Instance** \`\`\`bash # Run DHIS2 locally docker run -d --name dhis2 -p 8080:8080 dhis2/core:2.40.4 # Then configure with: { "baseUrl": "http://localhost:8080", "username": "admin", "password": "district" } \`\`\` **Option 3: Organization Instance** Contact your DHIS2 administrator for: - Instance URL (e.g., https://yourorg.dhis2.org) - Username and password - Required authorities for your workflow šŸ’” **Meanwhile, try these tools without connection:** • \`dhis2_init_webapp\` - Create new DHIS2 apps • \`dhis2_configure_build_system\` - Setup build tools • \`dhis2_generate_test_setup\` - Testing configuration • \`dhis2_create_ui_components\` - UI code generation šŸ”„ **After connecting, you'll have access to ${name} and all API tools!**`, }, ], isError: true, }; } break; } // At this point, if we reach here for API tools, dhis2Client must be initialized // because the earlier check would have returned an error switch (name) { case 'dhis2_get_system_info': const systemInfo = await dhis2Client.getSystemInfo(); logSuccessfulOperation(name, {}, systemInfo, startTime); return { content: [ { type: 'text', text: JSON.stringify(systemInfo, null, 2), }, ], }; case 'dhis2_list_data_elements': const { filter: deFilter, pageSize: dePageSize } = args; const dataElements = await dhis2Client.getDataElements(filterUndefinedValues({ filter: deFilter, pageSize: dePageSize })); logSuccessfulOperation(name, { filter: deFilter, pageSize: dePageSize }, dataElements, startTime); return { content: [ { type: 'text', text: JSON.stringify(dataElements, null, 2), }, ], }; case 'dhis2_create_data_element': const newDataElement = args; const createdDE = await dhis2Client.createDataElement(newDataElement); logSuccessfulOperation(name, newDataElement, createdDE, startTime, [createdDE.response?.uid || 'unknown']); return { content: [ { type: 'text', text: JSON.stringify(createdDE, null, 2), }, ], }; case 'dhis2_update_data_element': const { id: deId, ...deUpdateData } = args; const updatedDE = await dhis2Client.updateDataElement(deId, deUpdateData); return { content: [ { type: 'text', text: JSON.stringify(updatedDE, null, 2), }, ], }; case 'dhis2_delete_data_element': const { id: deDeleteId } = args; const deletedDE = await dhis2Client.deleteDataElement(deDeleteId); return { content: [ { type: 'text', text: JSON.stringify(deletedDE, null, 2), }, ], }; case 'dhis2_list_data_sets': const { filter: dsFilter, pageSize: dsPageSize } = args; const dataSets = await dhis2Client.getDataSets(filterUndefinedValues({ filter: dsFilter, pageSize: dsPageSize })); return { content: [ { type: 'text', text: JSON.stringify(dataSets, null, 2), }, ], }; case 'dhis2_create_data_set': const newDataSet = args; const createdDS = await dhis2Client.createDataSet(newDataSet); return { content: [ { type: 'text', text: JSON.stringify(createdDS, null, 2), }, ], }; case 'dhis2_list_categories': const { filter: catFilter, pageSize: catPageSize } = args; const categories = await dhis2Client.getCategories(filterUndefinedValues({ filter: catFilter, pageSize: catPageSize })); return { content: [ { type: 'text', text: JSON.stringify(categories, null, 2), }, ], }; case 'dhis2_create_category': const newCategory = args; const createdCat = await dhis2Client.createCategory(newCategory); return { content: [ { type: 'text', text: JSON.stringify(createdCat, null, 2), }, ], }; case 'dhis2_list_category_options': const { filter: coFilter, pageSize: coPageSize } = args; const categoryOptions = await dhis2Client.getCategoryOptions(filterUndefinedValues({ filter: coFilter, pageSize: coPageSize })); return { content: [ { type: 'text', text: JSON.stringify(categoryOptions, null, 2), }, ], }; case 'dhis2_create_category_option': const newCategoryOption = args; const createdCO = await dhis2Client.createCategoryOption(newCategoryOption); return { content: [ { type: 'text', text: JSON.stringify(createdCO, null, 2), }, ], }; case 'dhis2_list_category_combos': const { filter: ccFilter, pageSize: ccPageSize } = args; const categoryCombos = await dhis2Client.getCategoryCombos(filterUndefinedValues({ filter: ccFilter, pageSize: ccPageSize })); return { content: [ { type: 'text', text: JSON.stringify(categoryCombos, null, 2), }, ], }; case 'dhis2_create_category_combo': const newCategoryCombo = args; const createdCC = await dhis2Client.createCategoryCombo(newCategoryCombo); return { content: [ { type: 'text', text: JSON.stringify(createdCC, null, 2), }, ], }; case 'dhis2_list_category_option_combos': const { filter: cocFilter, pageSize: cocPageSize } = args; const categoryOptionCombos = await dhis2Client.getCategoryOptionCombos(filterUndefinedValues({ filter: cocFilter, pageSize: cocPageSize })); return { content: [ { type: 'text', text: JSON.stringify(categoryOptionCombos, null, 2), }, ], }; case 'dhis2_list_org_units': const { filter: ouFilter, pageSize: ouPageSize } = args; const orgUnits = await dhis2Client.getOrganisationUnits(filterUndefinedValues({ filter: ouFilter, pageSize: ouPageSize })); return { content: [ { type: 'text', text: JSON.stringify(orgUnits, null, 2), }, ], }; case 'dhis2_list_org_unit_groups': const { filter: ougFilter, pageSize: ougPageSize } = args; const orgUnitGroups = await dhis2Client.getOrganisationUnitGroups(filterUndefinedValues({ filter: ougFilter, pageSize: ougPageSize })); return { content: [ { type: 'text', text: JSON.stringify(orgUnitGroups, null, 2), }, ], }; case 'dhis2_create_org_unit_group': const newOrgUnitGroup = args; const createdOUG = await dhis2Client.createOrganisationUnitGroup(newOrgUnitGroup); return { content: [ { type: 'text', text: JSON.stringify(createdOUG, null, 2), }, ], }; case 'dhis2_list_validation_rules': const { filter: vrFilter, pageSize: vrPageSize } = args; const validationRules = await dhis2Client.getValidationRules(filterUndefinedValues({ filter: vrFilter, pageSize: vrPageSize })); return { content: [ { type: 'text', text: JSON.stringify(validationRules, null, 2), }, ], }; case 'dhis2_create_validation_rule': const { leftSideExpression, rightSideExpression, ...vrData } = args; const validationRule = { ...vrData, leftSide: { expression: leftSideExpression, missingValueStrategy: 'SKIP_IF_ANY_VALUE_MISSING', }, rightSide: { expression: rightSideExpression, missingValueStrategy: 'SKIP_IF_ANY_VALUE_MISSING', }, }; const createdVR = await dhis2Client.createValidationRule(validationRule); return { content: [ { type: 'text', text: JSON.stringify(createdVR, null, 2), }, ], }; case 'dhis2_run_validation': const validationParams = args; const validationResults = await dhis2Client.runValidation(validationParams); return { content: [ { type: 'text', text: JSON.stringify(validationResults, null, 2), }, ], }; case 'dhis2_get_data_values': const dataValueParams = args; const dataValues = await dhis2Client.getDataValues(dataValueParams); return { content: [ { type: 'text', text: JSON.stringify(dataValues, null, 2), }, ], }; case 'dhis2_bulk_import_data_values': const { dataValues: valuesToImport } = args; const importResult = await dhis2Client.bulkImportDataValues(valuesToImport); return { content: [ { type: 'text', text: JSON.stringify(importResult, null, 2), }, ], }; case 'dhis2_get_analytics': const analyticsParams = args; const analytics = await dhis2Client.getAnalytics(analyticsParams); return { content: [ { type: 'text', text: JSON.stringify(analytics, null, 2), }, ], }; case 'dhis2_list_programs': const { filter: progFilter, pageSize: progPageSize } = args; const programs = await dhis2Client.getPrograms(filterUndefinedValues({ filter: progFilter, pageSize: progPageSize })); return { content: [ { type: 'text', text: JSON.stringify(programs, null, 2), }, ], }; case 'dhis2_create_program': const newProgram = args; const createdProg = await dhis2Client.createProgram(newProgram); return { content: [ { type: 'text', text: JSON.stringify(createdProg, null, 2), }, ], }; case 'dhis2_list_tracked_entity_types': const { filter: tetFilter, pageSize: tetPageSize } = args; const trackedEntityTypes = await dhis2Client.getTrackedEntityTypes(filterUndefinedValues({ filter: tetFilter, pageSize: tetPageSize })); return { content: [ { type: 'text', text: JSON.stringify(trackedEntityTypes, null, 2), }, ], }; case 'dhis2_create_tracked_entity_type': const newTET = args; const createdTET = await dhis2Client.createTrackedEntityType(newTET); return { content: [ { type: 'text', text: JSON.stringify(createdTET, null, 2), }, ], }; case 'dhis2_list_tracked_entity_attributes': const { filter: teaFilter, pageSize: teaPageSize } = args; const trackedEntityAttributes = await dhis2Client.getTrackedEntityAttributes(filterUndefinedValues({ filter: teaFilter, pageSize: teaPageSize })); return { content: [ { type: 'text', text: JSON.stringify(trackedEntityAttributes, null, 2), }, ], }; case 'dhis2_create_tracked_entity_attribute': const newTEA = args; const createdTEA = await dhis2Client.createTrackedEntityAttribute(newTEA); return { content: [ { type: 'text', text: JSON.stringify(createdTEA, null, 2), }, ], }; case 'dhis2_list_program_stages': const { filter: psFilter, pageSize: psPageSize } = args; const programStages = await dhis2Client.getProgramStages(filterUndefinedValues({ filter: psFilter, pageSize: psPageSize })); return { content: [ { type: 'text', text: JSON.stringify(programStages, null, 2), }, ], }; case 'dhis2_create_program_stage': const newPS = args; const createdPS = await dhis2Client.createProgramStage(newPS); return { content: [ { type: 'text', text: JSON.stringify(createdPS, null, 2), }, ], }; case 'dhis2_list_program_rules': const { filter: prFilter, pageSize: prPageSize } = args; const programRules = await dhis2Client.getProgramRules(filterUndefinedValues({ filter: prFilter, pageSize: prPageSize })); return { content: [ { type: 'text', text: JSON.stringify(programRules, null, 2), }, ], }; case 'dhis2_create_program_rule': const newPR = args; const createdPR = await dhis2Client.createProgramRule(newPR); return { content: [ { type: 'text', text: JSON.stringify(createdPR, null, 2), }, ], }; case 'dhis2_list_tracked_entity_instances': const teiParams = args; const trackedEntityInstances = await dhis2Client.getTrackedEntityInstances(teiParams); return { content: [ { type: 'text', text: JSON.stringify(trackedEntityInstances, null, 2), }, ], }; case 'dhis2_create_tracked_entity_instance': const newTEI = args; const createdTEI = await dhis2Client.createTrackedEntityInstance(newTEI); return { content: [ { type: 'text', text: JSON.stringify(createdTEI, null, 2), }, ], }; case 'dhis2_list_enrollments': const enrollmentParams = args; const enrollments = await dhis2Client.getEnrollments(enrollmentParams); return { content: [ { type: 'text', text: JSON.stringify(enrollments, null, 2), }, ], }; case 'dhis2_create_enrollment': const newEnrollment = args; const createdEnrollment = await dhis2Client.createEnrollment(newEnrollment); return { content: [ { type: 'text', text: JSON.stringify(createdEnrollment, null, 2), }, ], }; case 'dhis2_list_events': const eventParams = args; const events = await dhis2Client.getEvents(eventParams); return { content: [ { type: 'text', text: JSON.stringify(events, null, 2), }, ], }; case 'dhis2_create_event': const newEvent = args; const createdEvent = await dhis2Client.createEvent(newEvent); return { content: [ { type: 'text', text: JSON.stringify(createdEvent, null, 2), }, ], }; case 'dhis2_bulk_import_events': const { events: eventsToImport } = args; const eventImportResult = await dhis2Client.bulkImportEvents(eventsToImport); return { content: [ { type: 'text', text: JSON.stringify(eventImportResult, null, 2), }, ], }; case 'dhis2_get_event_analytics': const eventAnalyticsParams = args; const eventAnalytics = await dhis2Client.getEventAnalytics(eventAnalyticsParams); return { content: [ { type: 'text', text: JSON.stringify(eventAnalytics, null, 2), }, ], }; case 'dhis2_get_enrollment_analytics': const enrollmentAnalyticsParams = args; const enrollmentAnalytics = await dhis2Client.getEnrollmentAnalytics(enrollmentAnalyticsParams); return { content: [ { type: 'text', text: JSON.stringify(enrollmentAnalytics, null, 2), }, ], }; case 'dhis2_get_data_statistics': const dataStatistics = await dhis2Client.getDataStatistics(); return { content: [ { type: 'text', text: JSON.stringify(dataStatistics, null, 2), }, ], }; case 'dhis2_list_dashboards': const { filter: dbFilter, pageSize: dbPageSize } = args; const dashboards = await dhis2Client.getDashboards(filterUndefinedValues({ filter: dbFilter, pageSize: dbPageSize })); return { content: [ { type: 'text', text: JSON.stringify(dashboards, null, 2), }, ], }; case 'dhis2_create_dashboard': const newDashboard = args; const createdDashboard = await dhis2Client.createDashboard(newDashboard); return { content: [ { type: 'text', text: JSON.stringify(createdDashboard, null, 2), }, ], }; case 'dhis2_list_visualizations': const { filter: vizFilter, pageSize: vizPageSize } = args; const visualizations = await dhis2Client.getVisualizations(filterUndefinedValues({ filter: vizFilter, pageSize: vizPageSize })); return { content: [ { type: 'text', text: JSON.stringify(visualizations, null, 2), }, ], }; case 'dhis2_create_visualization': const newVisualization = args; const createdVisualization = await dhis2Client.createVisualization(newVisualization); return { content: [ { type: 'text', text: JSON.stringify(createdVisualization, null, 2), }, ], }; case 'dhis2_list_reports': const { filter: reportFilter, pageSize: reportPageSize } = args; const reports = await dhis2Client.getReports(filterUndefinedValues({ filter: reportFilter, pageSize: reportPageSize })); return { content: [ { type: 'text', text: JSON.stringify(reports, null, 2), }, ], }; case 'dhis2_generate_report': const { reportId, ...reportParams } = args; const generatedReport = await dhis2Client.generateReport(reportId, reportParams); return { content: [ { type: 'text', text: 'Report generated successfully (binary data)', }, ], }; // Web App Platform Integration Tools case 'dhis2_init_webapp': const { appName, appTitle, appDescription, namespace, appType, template, typescript, pwa, outputPath } = args; const initInstructions = generateWebAppInitInstructions(appName, appTitle, appDescription, { namespace, appType, template, typescript, pwa, outputPath }); return { content: [ { type: 'text', text: initInstructions, }, ], }; case 'dhis2_configure_app_manifest': const manifestArgs = args; const manifestContent = generateManifestContent(manifestArgs); return { content: [ { type: 'text', text: manifestContent, }, ], }; case 'dhis2_configure_build_system': const buildSystemArgs = args; const buildConfig = generateBuildSystemConfig(buildSystemArgs); return { content: [ { type: 'text', text: buildConfig, }, ], }; case 'dhis2_setup_dev_environment': const devEnvArgs = args; const devEnvConfig = generateDevEnvironmentConfig(devEnvArgs); return { content: [ { type: 'text', text: devEnvConfig, }, ], }; case 'dhis2_generate_app_runtime_config': const runtimeConfigArgs = args; const runtimeConfig = generateAppRuntimeConfig(runtimeConfigArgs); return { content: [ { type: 'text', text: runtimeConfig, }, ], }; case 'dhis2_create_datastore_namespace': const datastoreNsArgs = args; const result = await dhis2Client.createDataStoreNamespace(datastoreNsArgs.namespace, datastoreNsArgs); return { content: [ { type: 'text', text: `DataStore namespace '${datastoreNsArgs.namespace}' configured successfully`, }, ], }; case 'dhis2_manage_datastore_key': const datastoreKeyArgs = args; const keyResult = await dhis2Client.manageDataStoreKey(datastoreKeyArgs); return { content: [ { type: 'text', text: JSON.stringify(keyResult, null, 2), }, ], }; case 'dhis2_setup_authentication_patterns': const authArgs = args; const authPatterns = generateAuthenticationPatterns(authArgs); return { content: [ { type: 'text', text: authPatterns, }, ], }; case 'dhis2_create_ui_components': const uiArgs = args; const uiComponents = generateUIComponents(uiArgs); return { content: [ { type: 'text', text: uiComponents, }, ], }; // Phase 4: UI Library Integration case 'dhis2_generate_ui_form_patterns': const formArgs = args; const formCode = generateUIFormPatterns(formArgs); return { content: [ { type: 'text', text: formCode } ] }; case 'dhis2_generate_ui_data_display': const displayArgs = args; const displayCode = generateUIDataDisplayPatterns(displayArgs); return { content: [ { type: 'text', text: displayCode } ] }; case 'dhis2_generate_ui_navigation_layout': const navArgs = args; const navCode = generateUINavigationLayout(navArgs); return { content: [ { type: 'text', text: navCode } ] }; case 'dhis2_generate_design_system': const dsArgs = args; const dsConfig = generateDesignSystemConfig(dsArgs); return { content: [ { type: 'text', text: dsConfig } ] }; // Android UI pattern tools (Phase 4) case 'android_generate_material_form': const aFormArgs = args; const aForm = generateAndroidMaterialForm(aFormArgs); return { content: [{ type: 'text', text: aForm }] }; case 'android_generate_list_adapter': const aListArgs = args; const aList = generateAndroidListAdapter(aListArgs); return { content: [{ type: 'text', text: aList }] }; case 'android_generate_navigation_drawer': const aNavArgs = args; const aNav = generateAndroidNavigationDrawer(aNavArgs); return { content: [{ type: 'text', text: aNav }] }; case 'android_generate_bottom_sheet': const aSheetArgs = args; const aSheet = generateAndroidBottomSheet(aSheetArgs); return { content: [{ type: 'text', text: aSheet }] }; case 'dhis2_generate_test_setup': const testArgs = args; const testSetup = generateTestSetup(testArgs); return { content: [ { type: 'text', text: testSetup, }, ], }; // DHIS2 Debugging and Troubleshooting Tools case 'dhis2_diagnose_cors_issues': const corsArgs = args; const corsAnalysis = diagnoseCORSIssues(corsArgs); return { content: [ { type: 'text', text: corsAnalysis, }, ], }; case 'dhis2_configure_cors_allowlist': const corsAllowlistArgs = args; const corsConfig = generateCORSConfiguration(corsAllowlistArgs); return { content: [ { type: 'text', text: corsConfig, }, ], }; case 'dhis2_debug_authentication': const authDebugArgs = args; const authAnalysis = debugAuthentication(authDebugArgs); return { content: [ { type: 'text', text: authAnalysis, }, ], }; case 'dhis2_fix_proxy_configuration': const proxyArgs = args; const proxyConfig = generateProxyConfiguration(proxyArgs); return { content: [ { type: 'text', text: proxyConfig, }, ], }; case 'dhis2_resolve_build_issues': const buildIssueArgs = args; const buildSolution = resolveBuildIssues(buildIssueArgs); return { content: [ { type: 'text', text: buildSolution, }, ], }; case 'dhis2_optimize_performance': const perfArgs = args; const perfOptimizations = generatePerformanceOptimizations(perfArgs); return { content: [ { type: 'text', text: perfOptimizations, }, ], }; case 'dhis2_validate_environment': const envArgs = args; const envValidation = validateEnvironment(envArgs); return { content: [ { type: 'text', text: envValidation, }, ], }; case 'dhis2_migration_assistant': const migrationArgs = args; const migrationGuide = generateMigrationGuide(migrationArgs); return { content: [ { type: 'text', text: migrationGuide, }, ], }; // Phase 3: Android SDK Integration Tools case 'dhis2_android_init_project': const androidProjectArgs = args; const androidProjectInstructions = generateAndroidProjectInit(androidProjectArgs); return { content: [ { type: 'text', text: androidProjectInstructions, }, ], }; case 'dhis2_android_configure_gradle': const gradleArgs = args; const gradleConfig = generateGradleBuildConfig(gradleArgs); return { content: [ { type: 'text', text: gradleConfig, }, ], }; case 'dhis2_android_setup_sync': const syncArgs = args; const syncConfig = generateSyncConfiguration(syncArgs); return { content: [ { type: 'text', text: syncConfig, }, ], }; case 'dhis2_android_configure_storage': const storageArgs = args; const storageConfig = generateStorageConfiguration(storageArgs); return { content: [ { type: 'text', text: storageConfig, }, ], }; case 'dhis2_android_setup_location_services': const locationArgs = args; const locationConfig = generateLocationServicesConfig(locationArgs); return { content: [ { type: 'text', text: locationConfig, }, ], }; case 'dhis2_android_configure_camera': const cameraArgs = args; const cameraConfig = generateCameraConfiguration(cameraArgs); return { content: [ { type: 'text', text: cameraConfig, }, ], }; case 'dhis2_android_setup_authentication': const androidAuthArgs = args; const authConfig = generateAndroidAuthenticationConfig(androidAuthArgs); return { content: [ { type: 'text', text: authConfig, }, ], }; case 'dhis2_android_generate_data_models': const dataModelsArgs = args; const dataModelsConfig = generateDataModelsConfiguration(dataModelsArgs); return { content: [ { type: 'text', text: dataModelsConfig, }, ], }; case 'dhis2_android_setup_testing': const testingArgs = args; const testingConfig = generateAndroidTestingConfiguration(testingArgs); return { content: [ { type: 'text', text: testingConfig, }, ], }; case 'dhis2_android_configure_ui_patterns': const androidUIArgs = args; const uiConfig = generateAndroidUIConfiguration(androidUIArgs); return { content: [ { type: 'text', text: uiConfig, }, ], }; case 'dhis2_android_setup_offline_analytics': const analyticsArgs = args; const analyticsConfig = generateOfflineAnalyticsConfiguration(analyticsArgs); return { content: [ { type: 'text', text: analyticsConfig, }, ], }; case 'dhis2_android_configure_notifications': const notificationsArgs = args; const notificationsConfig = generateNotificationsConfiguration(notificationsArgs); return { content: [ { type: 'text', text: notificationsConfig, }, ], }; case 'dhis2_android_performance_optimization': const androidPerfArgs = args; const perfConfig = generatePerformanceOptimizationConfiguration(androidPerfArgs); return { content: [ { type: 'text', text: perfConfig, }, ], }; // System Management and Audit Tools case 'dhis2_get_audit_lo