Skip to main content
Glama
marco-looy
by marco-looy

get_case_stages

Retrieve detailed stages list for a specific case ID, including processes, steps, and visited status, via Pega DX MCP Server to streamline case management.

Instructions

Retrieve the stages list for a given case ID with processes, steps, and visited status information.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
caseIDYesFull case handle (e.g.,ON6E5R-DIYRECIPE-WORK-RECIPECOLLECTION R-1008)

Implementation Reference

  • The main handler function that executes the get_case_stages tool. It validates parameters, initializes session if provided, and calls pegaClient.getCaseStages to fetch the stages.
    async execute(params) { const { caseID } = params; let sessionInfo = null; try { // Initialize session configuration if provided sessionInfo = this.initializeSessionConfig(params); // Validate required parameters using base class const requiredValidation = this.validateRequiredParams(params, ['caseID']); if (requiredValidation) { return requiredValidation; } // Execute with standardized error handling return await this.executeWithErrorHandling( `Case Stages: ${caseID}`, async () => await this.pegaClient.getCaseStages(caseID.trim()), { caseID, sessionInfo } ); } catch (error) { return { content: [{ type: 'text', text: `## Error: Get Case Stages\n\n**Unexpected Error**: ${error.message}\n\n${sessionInfo ? `**Session**: ${sessionInfo.sessionId} (${sessionInfo.authMode} mode)\n` : ''}*Error occurred at: ${new Date().toISOString()}*` }] }; } }
  • The tool schema definition including name, description, and input schema for MCP protocol.
    static getDefinition() { return { name: 'get_case_stages', description: 'Retrieve the stages list for a given case ID with processes, steps, and visited status information.', inputSchema: { type: 'object', properties: { caseID: { type: 'string', description: 'Full case handle (e.g.,ON6E5R-DIYRECIPE-WORK-RECIPECOLLECTION R-1008)' }, sessionCredentials: getSessionCredentialsSchema() }, required: ['caseID'] } }; }
  • Custom overridden formatSuccessResponse method that formats the stages data into a detailed markdown report with progress tracking, visited status, and hierarchical view of stages/processes/steps.
    formatSuccessResponse(operation, data, options = {}) { const { caseID, sessionInfo } = options; let response = `## ${operation}\n\n`; response += `*Operation completed at: ${new Date().toISOString()}*\n\n`; // Session Information (if applicable) if (sessionInfo) { response += `### Session Information\n`; response += `- **Session ID**: ${sessionInfo.sessionId}\n`; response += `- **Authentication Mode**: ${sessionInfo.authMode.toUpperCase()}\n`; response += `- **Configuration Source**: ${sessionInfo.configSource}\n\n`; } // Display case stages information if (data.stages && Array.isArray(data.stages)) { response += `### Stage Overview\n`; response += `- **Total Stages**: ${data.stages.length}\n`; // Count visited and unvisited stages const visitedStages = data.stages.filter(stage => stage.visited === true); const unvisitedStages = data.stages.filter(stage => stage.visited === false); response += `- **Visited Stages**: ${visitedStages.length}\n`; response += `- **Remaining Stages**: ${unvisitedStages.length}\n\n`; // Display each stage with details data.stages.forEach((stage, stageIndex) => { const stageNumber = stageIndex + 1; const visitedIcon = stage.visited ? '✅' : '⏸️'; const stageType = stage.stageType || 'Primary'; response += `### ${visitedIcon} Stage ${stageNumber}: ${stage.name}\n`; response += `- **Type**: ${stageType}\n`; response += `- **Status**: ${stage.visited ? 'Visited' : 'Not Visited'}\n`; if (stage.description) { response += `- **Description**: ${stage.description}\n`; } // Display processes within the stage if (stage.processes && Array.isArray(stage.processes)) { response += `- **Processes**: ${stage.processes.length}\n\n`; stage.processes.forEach((process, processIndex) => { const processNumber = processIndex + 1; const processVisitedIcon = process.visited ? '✅' : '⏸️'; response += `#### ${processVisitedIcon} Process ${stageNumber}.${processNumber}: ${process.name}\n`; response += ` - **Status**: ${process.visited ? 'Visited' : 'Not Visited'}\n`; if (process.description) { response += ` - **Description**: ${process.description}\n`; } // Display steps within the process if (process.steps && Array.isArray(process.steps)) { response += ` - **Steps**: ${process.steps.length}\n`; process.steps.forEach((step, stepIndex) => { const stepNumber = stepIndex + 1; const stepVisitedIcon = step.visited ? '✅' : '⏸️'; response += ` ${stepVisitedIcon} **Step ${stageNumber}.${processNumber}.${stepNumber}**: ${step.name}`; response += ` (${step.visited ? 'Visited' : 'Not Visited'})\n`; if (step.description) { response += ` - ${step.description}\n`; } }); } response += '\n'; }); } else { response += '\n'; } }); // Summary section response += '### Progress Summary\n'; const totalProcesses = data.stages.reduce((sum, stage) => sum + (stage.processes ? stage.processes.length : 0), 0); const visitedProcesses = data.stages.reduce((sum, stage) => sum + (stage.processes ? stage.processes.filter(p => p.visited).length : 0), 0); const totalSteps = data.stages.reduce((sum, stage) => sum + (stage.processes ? stage.processes.reduce((pSum, process) => pSum + (process.steps ? process.steps.length : 0), 0) : 0), 0); const visitedSteps = data.stages.reduce((sum, stage) => sum + (stage.processes ? stage.processes.reduce((pSum, process) => pSum + (process.steps ? process.steps.filter(s => s.visited).length : 0), 0) : 0), 0); if (totalProcesses > 0) { response += `- **Processes**: ${visitedProcesses}/${totalProcesses} completed\n`; } if (totalSteps > 0) { response += `- **Steps**: ${visitedSteps}/${totalSteps} completed\n`; } // Progress percentage if (totalSteps > 0) { const progressPercent = Math.round((visitedSteps / totalSteps) * 100); response += `- **Overall Progress**: ${progressPercent}%\n`; } } else if (data.stages) { response += '### Stages Information\n'; response += '- Stages data available but not in expected array format\n'; response += `- Raw data type: ${typeof data.stages}\n`; } else { response += '### No Stages Information\n'; response += '- No stages data found for this case\n'; } return response; }
  • The PegaClient router method delegated by the tool's pegaClient.getCaseStages call. Routes to v1 or v2 specific implementation based on config.
    async getCaseStages(caseID) { return this.client.getCaseStages(caseID); }
  • Dynamic registration logic in configurable tool loader that discovers, validates, instantiates, and registers the GetCaseStagesTool by scanning the 'cases' directory and loading get-case-stages.js.
    /** * Discover and load tools based on configuration * @returns {Promise<Map>} Map of categories to tool classes */ async discoverTools() { try { // Load configuration first this.config = await toolConfig.load(); console.error(`🔧 Loading tools with simplified configuration`); console.error(`📋 Environment: ${toolConfig.getEnvironment()}`); console.error(`⚙️ Log Level: ${toolConfig.getLogLevel()}`); const categories = await this.scanCategories(); for (const category of categories) { const tools = await this.loadCategoryTools(category); if (tools.length > 0) { this.categories.set(category, tools); } } this.logLoadingSummary(); return this.categories; } catch (error) { console.error('❌ Error discovering tools:', error); throw new Error(`Failed to discover tools: ${error.message}`); } } /** * Scan for tool categories (subdirectories in tools/) * @returns {Promise<Array>} Array of category names */ async scanCategories() { try { const entries = await fs.readdir(this.toolsPath, { withFileTypes: true }); const categories = []; for (const entry of entries) { if (entry.isDirectory()) { const categoryName = entry.name; // Check if category should be loaded if (toolConfig.isCategoryEnabled(categoryName)) { categories.push(categoryName); console.error(`✅ Category enabled: ${categoryName}`); } else { console.error(`⏭️ Category skipped: ${categoryName} (disabled in configuration)`); } } } return categories.sort(); } catch (error) { if (error.code === 'ENOENT') { console.warn(`⚠️ Tools directory not found: ${this.toolsPath}`); return []; } throw error; } } /** * Load all tools from a specific category directory * @param {string} category - Category name * @returns {Promise<Array>} Array of tool class instances */ async loadCategoryTools(category) { const categoryPath = resolve(this.toolsPath, category); const tools = []; const skippedInCategory = []; try { const files = await fs.readdir(categoryPath); const jsFiles = files.filter(file => file.endsWith('.js')); console.error(`🔍 Scanning category: ${category} (${jsFiles.length} files)`); for (const file of jsFiles) { try { const result = await this.loadToolFile(categoryPath, file, category); if (result.loaded) { tools.push(result.tool); console.error(` ✅ Loaded: ${result.toolName}`); } else { skippedInCategory.push({ file, toolName: result.toolName, reason: result.reason }); console.error(` ⏭️ Skipped: ${result.toolName} (${result.reason})`); } } catch (error) { console.warn(` ❌ Failed to load ${file}: ${error.message}`); skippedInCategory.push({ file, toolName: file.replace('.js', ''), reason: `Load error: ${error.message}` }); } } // Store skipped tools for reporting if (skippedInCategory.length > 0) { this.skippedTools.set(category, skippedInCategory); } return tools.sort((a, b) => a.constructor.name.localeCompare(b.constructor.name)); } catch (error) { console.warn(`❌ Failed to read category directory ${category}: ${error.message}`); return []; } } /** * Load a single tool file with configuration checking * @param {string} categoryPath - Path to category directory * @param {string} filename - Tool filename * @param {string} category - Category name * @returns {Promise<Object>} Load result with tool instance or skip reason */ async loadToolFile(categoryPath, filename, category) { const filePath = resolve(categoryPath, filename); const fileUrl = pathToFileURL(filePath).href; try { const module = await import(fileUrl); // Find the tool class in the module const ToolClass = this.findToolClass(module);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marco-looy/pega-dx-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server