@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
123 lines • 7.4 kB
JavaScript
/**
* Get Project Data Tool - Individual Module
* @description Retrieves comprehensive project data with aggregation
* @since 2025-08-04
* @author Tool Modularization Team
*
* Migration Status: COMPLETED
* Original Method: OptimizelyMCPTools.getProjectData
* Complexity: LOW
* Dependencies: storage.query, logger, errorMapper, cacheManager
*/
/**
* Creates the Get Project Data tool with injected dependencies
* @param deps - Injected dependencies (storage, logger, errorMapper, etc.)
* @returns Tool definition with handler
*/
export function createGetProjectDataTool(deps) {
return {
name: 'get_project_data',
requiresCache: true,
category: 'discovery',
description: 'Retrieves comprehensive project data with aggregation',
handler: async (args) => {
try {
const { project_id: projectId, options = {} } = args;
deps.logger.debug({
projectId,
options
}, 'OptimizelyMCPTools.getProjectData: Getting comprehensive project data from cache');
// Set defaults: if no specific include options are provided, include everything
const defaults = {
include_flags: true,
include_experiments: true,
include_audiences: true,
include_attributes: true,
include_events: true,
include_environments: true,
include_rulesets: true
};
// Only use defaults if no include options were explicitly provided
const hasAnyIncludes = Object.keys(options).some(key => key.startsWith('include_'));
const finalOptions = hasAnyIncludes ? options : { ...defaults, ...options };
if (!deps.cacheManager) {
throw deps.errorMapper.toMCPError(new Error("Cache manager not initialized"), { operation: 'Get project data' });
}
// Build result object with requested entities from cache
const result = {
result: "success",
metadata: {
operation: "get_project_data",
project_id: projectId,
operation_successful: true,
timestamp: new Date().toISOString(),
data_source: "cache"
}
};
// Get project details first
const projectQuery = await deps.storage.query('SELECT * FROM projects WHERE id = ?', [projectId]);
if (!projectQuery.length) {
throw deps.errorMapper.toMCPError(new Error(`Project ${projectId} not found in cache`), { operation: 'Get project data', metadata: { projectId } });
}
result.project = projectQuery[0];
const isFeatureExperimentation = result.project.platform === 'custom' || result.project.is_flags_enabled;
// Include requested entities using efficient cache queries
if (finalOptions.include_flags) {
result.flags = await deps.storage.query('SELECT id, key, name, description, archived, created_time, updated_time FROM flags WHERE project_id = ? AND archived = 0 ORDER BY updated_time DESC', [projectId]);
}
if (finalOptions.include_experiments) {
if (isFeatureExperimentation) {
// For Feature Experimentation, get A/B test rulesets
result.experiments = await deps.storage.query('SELECT flag_key, environment_key, enabled, archived, rules_summary FROM flag_environments WHERE project_id = ? AND (data_json LIKE ? OR data_json LIKE ?) ORDER BY environment_key', [projectId, '%"type":"a/b_test"%', '%"type":"experiment"%']);
}
else {
// For Web Experimentation, get standalone experiments
result.experiments = await deps.storage.query('SELECT id, key, name, description, status, archived, created_time, updated_time FROM experiments WHERE project_id = ? AND archived = 0 ORDER BY updated_time DESC', [projectId]);
}
}
if (finalOptions.include_audiences) {
result.audiences = await deps.storage.query('SELECT id, name, description, conditions, archived, created_time, last_modified FROM audiences WHERE project_id = ? AND archived = 0 ORDER BY last_modified DESC', [projectId]);
}
if (finalOptions.include_attributes) {
result.attributes = await deps.storage.query('SELECT id, key, name, condition_type, archived, last_modified FROM attributes WHERE project_id = ? AND archived = 0 ORDER BY last_modified DESC', [projectId]);
}
if (finalOptions.include_events) {
result.events = await deps.storage.query('SELECT id, key, name, description, event_type, category, archived, created_time FROM events WHERE project_id = ? AND archived = 0 ORDER BY created_time DESC', [projectId]);
}
if (finalOptions.include_environments) {
result.environments = await deps.storage.query('SELECT key, name, is_primary, priority, archived FROM environments WHERE project_id = ? ORDER BY priority, key', [projectId]);
}
if (finalOptions.include_rulesets && isFeatureExperimentation) {
result.rulesets = await deps.storage.query('SELECT flag_key, environment_key, enabled, archived, rules_summary FROM flag_environments WHERE project_id = ? ORDER BY flag_key, environment_key', [projectId]);
}
// Add summary counts
result.summary = {
total_entities: 0,
platform_type: isFeatureExperimentation ? 'Feature Experimentation' : 'Web Experimentation'
};
// Count entities that were included
['flags', 'experiments', 'audiences', 'attributes', 'events', 'environments', 'rulesets'].forEach(entityType => {
if (result[entityType]) {
result.summary.total_entities += result[entityType].length;
result.summary[`${entityType}_count`] = result[entityType].length;
}
});
deps.logger.debug({
projectId,
totalEntities: result.summary.total_entities,
includedTypes: Object.keys(result).filter(key => Array.isArray(result[key]))
}, 'OptimizelyMCPTools.getProjectData: Successfully retrieved project data from cache');
return result;
}
catch (error) {
deps.logger.error({
projectId: args.project_id,
error: error.message,
stack: error.stack
}, 'OptimizelyMCPTools.getProjectData: Failed to get project data');
throw deps.errorMapper.toMCPError(error, 'Failed to get comprehensive project data');
}
}
};
}
//# sourceMappingURL=GetProjectData.js.map