Skip to main content
Glama
Progress-Notifications.md16 kB
# MCP Progress Notifications **Last Updated:** 2025-10-23 | **Status:** ✅ Implemented in v1.13.0+ --- ## Overview Progress Notifications provide real-time updates about long-running operations, allowing MCP clients to show progress bars and status updates to users. Instead of waiting in silence for 30-60 seconds, users see exactly what's happening at each step. --- ## The Problem They Solve ### Without Progress Notifications ``` User: "Find all severity 1, 2, and 3 bugs for ISR4431" [... 30 seconds of waiting with no feedback ...] Assistant: "Here are the results..." ``` **User Experience:** - ❌ No feedback during long operations - ❌ Uncertain if system is working or frozen - ❌ No way to estimate completion time - ❌ Anxiety-inducing "black box" waiting ### With Progress Notifications ``` User: "Find all severity 1, 2, and 3 bugs for ISR4431" [Progress: 1/3] Searching severity 1 bugs... ⏳ [Progress: 2/3] Searching severity 2 bugs... ⏳ [Progress: 3/3] Searching severity 3 bugs... ⏳ Assistant: "Here are the results..." ``` **User Experience:** - ✅ Clear feedback at each step - ✅ Confidence system is working - ✅ Can estimate remaining time - ✅ Professional, modern UX --- ## How Progress Notifications Work ### MCP Protocol Flow 1. **Client Calls Tool with Progress Token** ```json { "method": "tools/call", "params": { "name": "multi_severity_search", "arguments": { "search_term": "ISR4431" }, "_meta": { "progressToken": "search-123" } } } ``` 2. **Server Sends Progress Updates** ```json { "jsonrpc": "2.0", "method": "notifications/progress", "params": { "progressToken": "search-123", "progress": 1, "total": 3 } } ``` 3. **Client Displays Progress** - If supported: Shows progress bar or status indicator - If not supported: Gracefully ignores notifications --- ## Real-World Use Cases ### 1. Multi-Severity Bug Searches The Cisco Bug API requires **separate calls** for each severity level. Searching severities 1, 2, and 3 means **3 API calls** taking 15-30 seconds total. **Without Progress:** ```typescript // User sees nothing for 30 seconds async function multiSeveritySearch() { const bugs1 = await searchBySeverity(1); // 10 seconds const bugs2 = await searchBySeverity(2); // 10 seconds const bugs3 = await searchBySeverity(3); // 10 seconds return combine(bugs1, bugs2, bugs3); } ``` **With Progress:** ```typescript // User sees updates every 10 seconds async function multiSeveritySearch(args, meta) { sendProgress(meta?.progressToken, 0, 3, "Searching severity 1..."); const bugs1 = await searchBySeverity(1); sendProgress(meta?.progressToken, 1, 3, "Searching severity 2..."); const bugs2 = await searchBySeverity(2); sendProgress(meta?.progressToken, 2, 3, "Searching severity 3..."); const bugs3 = await searchBySeverity(3); return combine(bugs1, bugs2, bugs3); } ``` **Visual Feedback:** ``` [Progress: 0/3] Searching severity 1... [Progress: 1/3] Searching severity 2... [Progress: 2/3] Searching severity 3... Complete! Found 45 total bugs. ``` --- ### 2. Comprehensive Analysis The `comprehensive_analysis` tool runs **5+ separate operations** that can take 60+ seconds: ```typescript async function comprehensiveAnalysis(args, meta) { sendProgress(meta?.progressToken, 1, 5, "1/5: Searching bugs..."); const bugs = await searchBugs(args.product, args.version); sendProgress(meta?.progressToken, 2, 5, "2/5: Checking security advisories..."); const advisories = await checkAdvisories(args.product); sendProgress(meta?.progressToken, 3, 5, "3/5: Analyzing CVEs..."); const cves = await analyzeCVEs(args.product, args.version); sendProgress(meta?.progressToken, 4, 5, "4/5: Checking EoL status..."); const eol = await checkEoL(args.product); sendProgress(meta?.progressToken, 5, 5, "5/5: Generating report..."); return generateReport(bugs, advisories, cves, eol); } ``` **Visual Timeline:** ``` [Progress: 1/5] 1/5: Searching bugs... (12s) [Progress: 2/5] 2/5: Checking security advisories... (8s) [Progress: 3/5] 3/5: Analyzing CVEs... (15s) [Progress: 4/5] 4/5: Checking EoL status... (10s) [Progress: 5/5] 5/5: Generating report... (5s) Complete! Analysis ready. ``` --- ### 3. Software Version Comparison The `compare_software_versions` tool runs **6+ comparisons**: ```typescript async function compareVersions(productId, versionA, versionB, meta) { sendProgress(meta?.progressToken, 1, 6, "1/6: Searching bugs in version A..."); const bugsA = await searchBugs(productId, versionA); sendProgress(meta?.progressToken, 2, 6, "2/6: Searching bugs in version B..."); const bugsB = await searchBugs(productId, versionB); sendProgress(meta?.progressToken, 3, 6, "3/6: Checking CVEs in version A..."); const cvesA = await checkCVEs(productId, versionA); sendProgress(meta?.progressToken, 4, 6, "4/6: Checking CVEs in version B..."); const cvesB = await checkCVEs(productId, versionB); sendProgress(meta?.progressToken, 5, 6, "5/6: Analyzing differences..."); const diff = analyzeDifferences(bugsA, bugsB, cvesA, cvesB); sendProgress(meta?.progressToken, 6, 6, "6/6: Generating recommendations..."); return generateRecommendations(diff); } ``` --- ### 4. Progressive Bug Search with Fallbacks The `progressive_bug_search` tool tries multiple search strategies: ```typescript async function progressiveBugSearch(args, meta) { sendProgress(meta?.progressToken, 1, 4, "1/4: Trying product ID search..."); let results = await tryProductIdSearch(args); if (results) return results; sendProgress(meta?.progressToken, 2, 4, "2/4: Trying product series search..."); results = await tryProductSeriesSearch(args); if (results) return results; sendProgress(meta?.progressToken, 3, 4, "3/4: Trying keyword search..."); results = await tryKeywordSearch(args); if (results) return results; sendProgress(meta?.progressToken, 4, 4, "4/4: Broadening search criteria..."); return await tryBroadSearch(args); } ``` --- ## Technical Implementation ### Server-Side Code ```typescript // Import progress notification support import { ProgressNotificationSchema } from '@modelcontextprotocol/sdk/types.js'; // Helper function to send progress function sendProgress( progressToken: string | undefined, progress: number, total: number, message?: string ) { if (!progressToken) return; // Client didn't request progress mcpServer.notification({ method: 'notifications/progress', params: { progressToken, progress, total } }); // Log for debugging logger.info('Progress notification sent', { progressToken, progress, total, percentage: Math.round((progress / total) * 100) }); } // Tool implementation with progress async function myLongRunningTool(args: ToolArgs, meta?: ToolMeta) { const steps = ['Step 1', 'Step 2', 'Step 3']; const results = []; for (let i = 0; i < steps.length; i++) { sendProgress(meta?.progressToken, i, steps.length, steps[i]); results.push(await performStep(steps[i])); } return results; } ``` ### Client-Side (Example) ```typescript // Client generates unique progress token const progressToken = `search-${Date.now()}`; // Client listens for progress notifications client.on('notifications/progress', (notification) => { const { progressToken, progress, total } = notification.params; // Update UI with progress updateProgressBar(progress, total); console.log(`Progress: ${progress}/${total} (${Math.round(progress/total*100)}%)`); }); // Client calls tool with progress token const result = await client.callTool('multi_severity_search', { search_term: 'ISR4431' }, { progressToken }); ``` --- ## Client Support Status ### Claude Desktop **Current Status (October 2025):** - ⚠️ **Unknown** - Progress notification support not publicly documented - ✅ **Graceful degradation** - If not supported, notifications are safely ignored - ✅ **Future-proof** - When support is added, it will work automatically **Potential Display Options:** - Status text: "Searching severity 2 bugs... (2/3)" - Progress bar: [████████░░] 66% - Spinner with message: ⏳ "Checking CVEs..." ### Other MCP Clients | Client | Progress Support | Display Method | |--------|------------------|----------------| | **MCP Inspector** | ✅ Likely | Debug panel with progress | | **VS Code MCP** | ✅ Possible | Status bar progress | | **Custom Clients** | ✅ Customizable | Developer's choice | --- ## Benefits ### 1. Better User Experience **Before Progress Notifications:** - ❌ "Is it working or frozen?" - ❌ "How much longer will this take?" - ❌ "Should I cancel and try again?" **With Progress Notifications:** - ✅ "It's working on step 2 of 5" - ✅ "About 60% complete" - ✅ "Just one more step to go" ### 2. Debugging & Transparency **Identify Bottlenecks:** ``` [Progress: 1/5] 1/5: Searching bugs... (2s) ✅ [Progress: 2/5] 2/5: Checking advisories... (25s) ⚠️ SLOW [Progress: 3/5] 3/5: Analyzing CVEs... (3s) ✅ ``` **Better Error Reporting:** ``` [Progress: 1/3] Searching severity 1... ✅ [Progress: 2/3] Searching severity 2... ✅ [Progress: 2/3] Searching severity 3... ❌ ERROR Error: API timeout during severity 3 search ``` ### 3. Professional Polish - ✅ Modern UX pattern used by all professional applications - ✅ MCP specification compliance - ✅ Shows attention to detail and user experience - ✅ Differentiates from basic implementations --- ## Tools with Progress Support ### Currently Implemented | Tool | Steps | Typical Duration | Progress Updates | |------|-------|------------------|------------------| | `multi_severity_search` | 3-6 | 15-60s | Per severity level | | `comprehensive_analysis` | 5 | 30-90s | Per analysis step | | `compare_software_versions` | 6 | 40-120s | Per comparison step | | `progressive_bug_search` | 2-4 | 10-40s | Per search strategy | ### Future Candidates | Tool | Steps | Why Progress Helps | |------|-------|-------------------| | Bulk product analysis | 100+ | Processing many items | | Multi-product upgrade planning | 10+ | Complex workflow | | Historical bug trend analysis | 20+ | Multiple time periods | --- ## Implementation Details ### Progress Notification Schema ```typescript interface ProgressNotification { method: 'notifications/progress'; params: { progressToken: string; // Unique identifier from client progress: number; // Current progress (0-based) total: number; // Total steps }; } ``` ### Best Practices **1. Progress Token is Optional** ```typescript // Always check if progressToken exists if (meta?.progressToken) { sendProgress(meta.progressToken, 1, 3); } ``` **2. Start at 0, End Before Total** ```typescript // Correct: 0, 1, 2 for total of 3 sendProgress(token, 0, 3); // Step 1 starting sendProgress(token, 1, 3); // Step 2 starting sendProgress(token, 2, 3); // Step 3 starting // Don't send progress === total (that's 100% complete) ``` **3. Update After Each Major Step** ```typescript // Good: Update after completing work await doWork(); sendProgress(token, 1, 3); // Bad: Update before work completes sendProgress(token, 1, 3); await doWork(); // What if this fails? ``` **4. Use Meaningful Step Counts** ```typescript // Good: Accurate step count sendProgress(token, 2, 5); // 5 actual steps // Bad: Arbitrary percentages sendProgress(token, 50, 100); // Not real steps ``` --- ## Backward Compatibility ### Graceful Degradation **Old clients (no progress support):** - Receive notifications, ignore them - Tools work exactly as before - No breaking changes **New clients (with progress support):** - Display progress updates - Enhanced user experience - Same tool behavior ### Testing Both Modes ```typescript // Test without progress token (old client) const result1 = await callTool('multi_severity_search', args); // Test with progress token (new client) const result2 = await callTool('multi_severity_search', args, { progressToken: 'test-123' }); // Both should return identical results assert.deepEqual(result1, result2); ``` --- ## Troubleshooting ### Progress Not Showing **Problem:** Client calls tool but doesn't see progress **Possible Causes:** 1. Client doesn't support progress notifications 2. Client didn't provide `progressToken` 3. Server logs not showing progress notifications **Solutions:** ```bash # Check server logs for progress notifications tail -f logs/mcp-server.log | grep "Progress notification" # Verify client sends progressToken # Should see in tool call: "_meta": {"progressToken": "..."} # Test with MCP Inspector (likely supports progress) ``` ### Progress Out of Sync **Problem:** Progress shows "3/3" but still running **Cause:** Incorrect step counting **Solution:** ```typescript // Wrong: Counts don't match const steps = [1, 2, 3]; for (let i = 0; i < steps.length; i++) { sendProgress(token, i, 4); // Total is 4 but only 3 steps! } // Correct: Match total to actual steps const steps = [1, 2, 3]; for (let i = 0; i < steps.length; i++) { sendProgress(token, i, steps.length); } ``` ### Progress Too Granular **Problem:** Hundreds of progress updates **Solution:** Only update for major steps ```typescript // Bad: Too many updates for (let i = 0; i < 1000; i++) { sendProgress(token, i, 1000); // Too granular! await processItem(i); } // Good: Group into meaningful steps const batchSize = 100; for (let i = 0; i < 1000; i += batchSize) { sendProgress(token, i / batchSize, 10); await processBatch(i, i + batchSize); } ``` --- ## Future Enhancements ### Optional Message Parameter The MCP spec allows an optional message: ```typescript interface ProgressNotification { progressToken: string; progress: number; total: number; message?: string; // Future: descriptive text } ``` **Potential Implementation:** ```typescript sendProgress(token, 1, 3, "Searching severity 2 bugs..."); ``` **Client Display:** ``` [████████░░] 66% - Searching severity 2 bugs... ``` ### Cancellation Support Combined with progress, cancellation would allow: ```typescript // User sees progress, decides to cancel [Progress: 2/5] Searching bugs... (taking too long) → User clicks "Cancel" → Server receives cancellation signal → Tool stops gracefully ``` --- ## Performance Impact ### Minimal Overhead ```typescript // Progress notification is async and non-blocking sendProgress(token, 1, 3); // ~1ms overhead await longOperation(); // Main work (10000ms) ``` **Performance Analysis:** - Progress notification: ~1ms per update - Network overhead: ~50 bytes per notification - For 5 steps: ~5ms total overhead (negligible) ### No Impact on Results Progress notifications are: - ✅ Fire-and-forget (async) - ✅ Non-blocking - ✅ Don't affect tool return values - ✅ Safe to ignore by clients --- ## References - [MCP Specification - Progress Notifications](https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/progress) - [MCP SDK Documentation](https://github.com/modelcontextprotocol/sdk) - [Available Tools](https://github.com/sieteunoseis/mcp-cisco-support/wiki/Available-Tools) - [MCP Resources](https://github.com/sieteunoseis/mcp-cisco-support/wiki/MCP-Resources) --- ## Related Pages - [Home](https://github.com/sieteunoseis/mcp-cisco-support/wiki) - [Available Tools](https://github.com/sieteunoseis/mcp-cisco-support/wiki/Available-Tools) - [MCP Resources](https://github.com/sieteunoseis/mcp-cisco-support/wiki/MCP-Resources) - [Development Guide](https://github.com/sieteunoseis/mcp-cisco-support/wiki/Development-Guide) - [Troubleshooting Guide](https://github.com/sieteunoseis/mcp-cisco-support/wiki/Troubleshooting-Guide) --- **Need Help?** Report issues at https://github.com/sieteunoseis/mcp-cisco-support/issues

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/sieteunoseis/mcp-cisco-support'

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