get_project_info
Retrieve Optimizely DXP project configuration details using project ID or name. Input API key and secret to access specific project info for deployment and environment management.
Instructions
Get current Optimizely project configuration details or info for a specific project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| apiKey | No | ||
| apiSecret | No | ||
| projectId | No | ||
| projectName | No |
Implementation Reference
- lib/tools/project-tools.ts:894-1139 (handler)The main handler function for the get_project_info tool. Retrieves detailed project information, handles project lookup by name or ID, supports inline credential provision for new/upgrade projects, renaming, and formats comprehensive project status output.static async getProjectInfo(args: GetProjectArgs): Promise<any> { try { // Handle multiple ways connection string might be passed let connectionString = args.connectionString; // Check if connection string was mistakenly passed as projectId if (!connectionString && args.projectId && args.projectId.startsWith('DefaultEndpointsProtocol=')) { connectionString = args.projectId; args.projectId = undefined; // Clear the misused field } // Check if connection string was mistakenly passed as apiKey if (!connectionString && args.apiKey && args.apiKey.startsWith('DefaultEndpointsProtocol=')) { connectionString = args.apiKey; args.apiKey = undefined; // Clear the misused field args.apiSecret = undefined; // Also clear apiSecret as it's not needed for self-hosted } // Check if connection string was mistakenly passed as apiSecret if (!connectionString && args.apiSecret && args.apiSecret.startsWith('DefaultEndpointsProtocol=')) { connectionString = args.apiSecret; args.apiSecret = undefined; // Clear the misused field args.apiKey = undefined; // Also clear apiKey as it's not needed for self-hosted } // Handle rename request if (args.projectName && args.renameTo) { const projects = this.getConfiguredProjects(); const project = projects.find(p => p.name === args.projectName || p.name.toLowerCase() === args.projectName!.toLowerCase() ); if (project) { // Create renamed configuration const renamedConfig: ProjectConfig = { ...project, name: args.renameTo, originalName: project.name, // Track original name for replacement configSource: 'dynamic', lastUpdated: new Date().toISOString() }; // Add to dynamic configurations (will replace by projectId or originalName) this.addConfiguration(renamedConfig); OutputLogger.log(`Project '${project.name}' renamed to '${args.renameTo}'`); // Return renamed project info return this.formatProjectInfo(renamedConfig, projects.length); } else { return ResponseBuilder.formatResponse({ success: false, message: `Project '${args.projectName}' not found`, details: `Available projects: ${projects.map(p => p.name).join(', ')}` }); } } // Check if this is an attempt to upgrade a project with inline connection string if (args.projectName && connectionString) { // User is providing a connection string for a project const projects = this.getConfiguredProjects(); const project = projects.find(p => p.name === args.projectName || p.name.toLowerCase() === args.projectName!.toLowerCase() ); if (project) { // Upgrade or update the existing project to Self-Hosted const upgradedConfig: ProjectConfig = { ...project, connectionString: connectionString, isSelfHosted: true, isUnknown: false, projectType: 'self-hosted', configSource: 'dynamic', lastUpdated: new Date().toISOString() }; // Update project ID for unknown projects if (upgradedConfig.projectId.startsWith('unknown-')) { upgradedConfig.projectId = upgradedConfig.projectId.replace('unknown-', 'self-hosted-'); } // Remove fields not relevant to self-hosted delete upgradedConfig.needsConfiguration; delete upgradedConfig.configurationHint; delete upgradedConfig.apiKey; delete upgradedConfig.apiSecret; // Add to dynamic configurations this.addConfiguration(upgradedConfig); // DXP-148 FIX: Set as last used project (inline connection string provided) this.setLastUsedProject(upgradedConfig.name); const actionType = project.isUnknown ? 'upgraded' : 'updated'; OutputLogger.log(`Project '${project.name}' ${actionType} with connection string`); // Return updated project info return this.formatProjectInfo(upgradedConfig, projects.length); } else { // Project doesn't exist yet - create new self-hosted project const newProject: ProjectConfig = { name: args.projectName, projectId: `self-hosted-${args.projectName.toLowerCase().replace(/\s+/g, '-')}`, connectionString: connectionString, isSelfHosted: true, projectType: 'self-hosted', environments: ['Production'], configSource: 'dynamic', addedAt: new Date().toISOString(), lastUsed: new Date().toISOString() }; // Add to dynamic configurations this.addConfiguration(newProject); // DXP-148 FIX: Set as last used project (inline connection string provided) this.setLastUsedProject(newProject.name); OutputLogger.log(`New self-hosted project '${newProject.name}' created`); // Return new project info return this.formatProjectInfo(newProject, projects.length + 1); } } // If inline credentials provided, check for existing project to upgrade or create new if (args.projectName && args.projectId && args.apiKey && args.apiSecret) { const projects = this.getConfiguredProjects(); // Check if there's ANY existing project with this name (Unknown or otherwise) const existingProject = projects.find(p => p.name === args.projectName || p.name.toLowerCase() === args.projectName!.toLowerCase() ); if (existingProject) { // Upgrade or update existing project const upgradedConfig: ProjectConfig = { ...existingProject, projectId: args.projectId, apiKey: args.apiKey, apiSecret: args.apiSecret, isUnknown: false, projectType: 'dxp-paas', configSource: 'dynamic', lastUpdated: new Date().toISOString() }; // Remove Unknown project specific fields delete upgradedConfig.needsConfiguration; delete upgradedConfig.configurationHint; delete upgradedConfig.isSelfHosted; delete upgradedConfig.connectionString; // Add to dynamic configurations this.addConfiguration(upgradedConfig); // DXP-148 FIX: Set as last used project (inline credentials provided) this.setLastUsedProject(upgradedConfig.name); const actionType = existingProject.isUnknown ? 'upgraded' : 'updated'; OutputLogger.log(`Project '${existingProject.name}' ${actionType} with DXP credentials`); // Return upgraded project info return this.formatProjectInfo(upgradedConfig, projects.length); } else { // No existing project - create new const project: ProjectConfig = { name: args.projectName, projectId: args.projectId, apiKey: args.apiKey, apiSecret: args.apiSecret, environments: ['Integration', 'Preproduction', 'Production'], projectType: 'dxp-paas', configSource: 'dynamic', addedAt: new Date().toISOString(), lastUsed: new Date().toISOString() }; // Add to dynamic configurations this.addConfiguration(project); // DXP-148 FIX: Set as last used project (inline credentials provided) this.setLastUsedProject(project.name); OutputLogger.log(`New DXP project '${project.name}' created`); // Get total projects including this one const totalProjects = projects.find(p => p.projectId === project.projectId) ? projects.length : projects.length + 1; return this.formatProjectInfo(project, totalProjects); } } const requestedProjectId = args.projectId || args.projectName; const projects = this.getConfiguredProjects(); // If no projects configured if (projects.length === 0) { return ResponseBuilder.formatResponse({ success: false, message: 'No projects configured', details: 'Please configure at least one project with API credentials.' }); } // If specific project requested if (requestedProjectId) { const project = projects.find(p => p.projectId === requestedProjectId || p.name === requestedProjectId || p.name.toLowerCase() === requestedProjectId.toLowerCase() ); if (!project) { return ResponseBuilder.formatResponse({ success: false, message: `Project '${requestedProjectId}' not found`, details: `Available projects: ${projects.map(p => p.name).join(', ')}` }); } return this.formatProjectInfo(project, projects.length); } // Show current/default project const currentProject = this.getCurrentProject(); if (currentProject) { return this.formatProjectInfo(currentProject, projects.length); } // Fallback to listing all projects return this.listProjects(args); } catch (error: any) { return ResponseBuilder.formatResponse({ success: false, message: 'Failed to get project information', error: error.message }); } }
- lib/tools/project-tools.ts:108-115 (schema)Input schema (TypeScript interface) defining parameters for the getProjectInfo handler, including project identifiers, credentials, and rename options.interface GetProjectArgs { projectName?: string; projectId?: string; apiKey?: string; apiSecret?: string; connectionString?: string; renameTo?: string; }
- lib/tools/project-tools.ts:1144-1227 (helper)Helper function that formats the project information response with status icons, credentials status, environments, and configuration tips.static formatProjectInfo(project: ProjectConfig, totalProjects: number): any { const sections: string[] = []; // Header sections.push('🏢 **Project Configuration**'); sections.push('📋 Found ' + totalProjects + ' configured project' + (totalProjects > 1 ? 's' : '') + ':'); let typeLabel = ' ☁️ (DXP PaaS)'; if (project.isSelfHosted) { typeLabel = ' 🏠 (Self-Hosted)'; } else if (project.isUnknown) { typeLabel = ' ❓ (Unknown - Needs Config)'; } sections.push(' ' + project.name + typeLabel); sections.push(''); sections.push('✅ **Connection Details:**'); sections.push(' Project ID: ' + project.projectId.substring(0, 8) + '...'); // Show appropriate credentials based on project type let hasCredentials: boolean; if (project.isUnknown) { sections.push(' Type: Unknown (Paths Only)'); sections.push(' Status: ⚠️ Needs Configuration'); if (project.blobPath) sections.push(' Blob Path: ' + project.blobPath); if (project.logPath) sections.push(' Log Path: ' + project.logPath); if (project.dbPath) sections.push(' DB Path: ' + project.dbPath); sections.push(''); sections.push(' 💡 **How to configure this project:**'); sections.push(' • For self-hosted: Add connectionString=DefaultEndpointsProtocol=...'); sections.push(' • For DXP PaaS: Add id=UUID;key=...;secret=...'); hasCredentials = false; // Unknown projects need configuration } else if (project.isSelfHosted) { sections.push(' Type: Self-Hosted Azure'); sections.push(' Connection String: ' + (project.connectionString ? '✅ Configured' : '❌ Not configured')); if (project.blobPath) sections.push(' Blob Path: ' + project.blobPath); if (project.logPath) sections.push(' Log Path: ' + project.logPath); hasCredentials = !!project.connectionString; } else { sections.push(' Type: DXP PaaS'); sections.push(' API Key: ' + (project.apiKey ? '✅ Configured' : '❌ Not configured')); sections.push(' API Secret: ' + (project.apiSecret ? '✅ Configured' : '❌ Not configured')); hasCredentials = !!(project.apiKey && project.apiSecret); } // Show permissions if known if (project.environments && project.environments.length > 0) { sections.push(''); sections.push('🔑 **Configured Environments:**'); project.environments.forEach(env => { sections.push(' • ' + env); }); } // Status sections.push(''); sections.push(hasCredentials ? '✅ **Ready to Use!**' : '❌ **Missing Credentials**'); if (hasCredentials) { sections.push(''); sections.push('💡 Run "test connection" to see your exact permissions.'); } // Configuration tips sections.push(''); sections.push('=' .repeat(50)); sections.push('💡 Tips:'); if (!hasCredentials) { sections.push('• Add API credentials to use this project'); sections.push('• Get credentials from your DXP Portal'); } else { sections.push('• This project is ready to use'); sections.push('• All commands will use this project by default'); } if (totalProjects > 1) { sections.push('• Switch projects by using project name in commands'); } return ResponseBuilder.formatResponse({ success: true, message: hasCredentials ? 'Project configured and ready' : 'Project needs configuration', details: sections.join('\n') }); }