Skip to main content
Glama

mcp-adr-analysis-server

by tosin2013
MCP_BEST_PRACTICES_VIOLATIONS.md21 kB
# MCP Best Practices Violations - Newer Tools Audit **Date**: 2025-10-07 **Issue Type**: ✅ **RESOLVED** - Progress & Logging Notifications Now Implemented **Affected Tools**: 6 newer tools (4 critical fixes completed, 2 optional remaining) --- ## Executive Summary The 6 newer tools **violate MCP best practices** from the course notes regarding **Progress and Logging Notifications**. According to the notes: > "Tool functions automatically receive context argument as last parameter. Context object provides methods: info() for logging, report_progress() for progress updates." **Violation**: None of the newer tools accept or use a `context` parameter, preventing them from providing real-time feedback during long-running operations. **Impact**: Users experience poor UX with no visibility into tool execution progress, making long-running operations appear stalled. --- ## The MCP Best Practice (From Course Notes) ### **What Should Happen:** ```typescript // ✅ CORRECT - Following MCP best practices export async function myTool( args: ToolArgs, context: ToolContext // ← Context as last parameter ): Promise<CallToolResult> { context.info('Starting operation...'); // ← Logging context.report_progress(0, 100); // ← Progress updates // Do work... context.info('Processing files...'); context.report_progress(50, 100); // More work... context.info('Finalizing...'); context.report_progress(100, 100); return result; } ``` **Benefits** (from course notes): - ✅ Prevents user confusion about stalled/failed tool calls - ✅ Provides visibility into long-running operations - ✅ Real-time feedback during tool execution - ✅ Optional feature for UX enhancement --- ## Affected Tools Analysis ### **1. conversation-memory-tool.ts** 🔴 **Current Signature:** ```typescript export async function expandMemory( args: { expandableId: string; section?: string; includeContext?: boolean; }, memoryManager: ConversationMemoryManager // ← No context parameter ): Promise<CallToolResult> ``` **Problem**: ❌ No context parameter, no progress/logging **Duration**: Fast (memory lookup) **Severity**: 🟢 **LOW** - Operation is quick, progress not critical **Fix Needed:** ```typescript export async function expandMemory( args: { expandableId: string; section?: string; includeContext?: boolean; }, memoryManager: ConversationMemoryManager, context?: ToolContext // ← Add context parameter ): Promise<CallToolResult> { context?.info('Retrieving expanded content...'); // ... rest of implementation } ``` --- ### **2. expand-analysis-tool.ts** 🔴 **Current Signature:** ```typescript export async function expandAnalysisSection( params: ExpandAnalysisParams // ← No context parameter ): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> ``` **Problem**: ❌ No context parameter, no progress/logging **Duration**: Fast (tiered response lookup) **Severity**: 🟢 **LOW** - Operation is quick **Fix Needed:** ```typescript export async function expandAnalysisSection( params: ExpandAnalysisParams, context?: ToolContext // ← Add context parameter ): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> { context?.info(`Expanding section: ${params.section || 'full analysis'}`); // ... rest of implementation } ``` --- ### **3. perform-research-tool.ts** 🔴 **Current Signature:** ```typescript export async function performResearch(args: { question: string; projectPath?: string; adrDirectory?: string; confidenceThreshold?: number; performWebSearch?: boolean; }): Promise<any> // ← No context parameter ``` **Problem**: ❌ No context parameter in tool function **Partial Fix**: Wrapper method in `index.ts` HAS context but doesn't pass it down **Duration**: **SLOW** (multi-source research: files → knowledge graph → web) **Severity**: 🔴 **CRITICAL** - Long-running operation needs progress feedback **Current Wrapper (index.ts:6586):** ```typescript private async performResearch( args: Record<string, unknown>, context?: ToolContext // ← Has context here ): Promise<CallToolResult> { const ctx = context || createNoOpContext(); ctx.info('📊 Phase 1: Initializing research framework'); ctx.report_progress(10, 100); // ... more progress updates in wrapper ... // ❌ BUT: Calls tool function WITHOUT context! const { performResearch } = await import('./tools/perform-research-tool.js'); return await performResearch(args); // ← Context NOT passed! } ``` **Fix Needed:** ```typescript // In perform-research-tool.ts export async function performResearch( args: { question: string; projectPath?: string; adrDirectory?: string; confidenceThreshold?: number; performWebSearch?: boolean; }, context?: ToolContext // ← Add context parameter ): Promise<any> { context?.info('🔍 Searching project files...'); context?.report_progress(25, 100); // Research from files... context?.info('📊 Querying knowledge graph...'); context?.report_progress(50, 100); // Query knowledge graph... context?.info('🌐 Performing web search...'); context?.report_progress(75, 100); // Web search... context?.info('✅ Research complete'); context?.report_progress(100, 100); return results; } // In index.ts wrapper - PASS context down return await performResearch(args, ctx); // ← Pass context! ``` --- ### **4. llm-cloud-management-tool.ts** 🔴 **Current Signature:** ```typescript export async function llmCloudManagement(args: { provider: 'aws' | 'azure' | 'gcp' | 'redhat' | 'ubuntu' | 'macos'; action: string; parameters?: Record<string, any>; llmInstructions: string; researchFirst?: boolean; projectPath?: string; adrDirectory?: string; }): Promise<any> // ← No context parameter ``` **Problem**: ❌ No context parameter, no progress/logging **Duration**: **SLOW** (research + command generation + execution) **Severity**: 🔴 **CRITICAL** - Cloud operations are slow and critical **Current Wrapper (index.ts):** ```typescript private async llmCloudManagement( args: Record<string, unknown> ): Promise<CallToolResult> { // ❌ No context parameter AT ALL! const { llmCloudManagement } = await import('./tools/llm-cloud-management-tool.js'); return await llmCloudManagement(args); } ``` **Fix Needed:** ```typescript // In llm-cloud-management-tool.ts export async function llmCloudManagement( args: { /* ... */ }, context?: ToolContext // ← Add context parameter ): Promise<any> { context?.info(`🔧 Initializing ${args.provider} management...`); context?.report_progress(0, 100); if (args.researchFirst) { context?.info('📚 Researching best practices...'); context?.report_progress(20, 100); // Research phase... } context?.info('🤖 Generating commands with LLM...'); context?.report_progress(50, 100); // LLM generation... context?.info('☁️ Executing cloud operation...'); context?.report_progress(80, 100); // Execute... context?.info('✅ Operation complete'); context?.report_progress(100, 100); return results; } // In index.ts - Add context parameter and pass it down private async llmCloudManagement( args: Record<string, unknown>, context?: ToolContext // ← Add context ): Promise<CallToolResult> { const ctx = context || createNoOpContext(); const { llmCloudManagement } = await import('./tools/llm-cloud-management-tool.js'); return await llmCloudManagement(args, ctx); // ← Pass context! } ``` --- ### **5. llm-database-management-tool.ts** 🔴 **Current Signature:** ```typescript export async function llmDatabaseManagement(args: { database: string; action: string; parameters?: Record<string, any>; llmInstructions: string; // ... }): Promise<any> // ← No context parameter ``` **Problem**: ❌ No context parameter, no progress/logging **Duration**: **SLOW** (database operations can be lengthy) **Severity**: 🔴 **CRITICAL** - Database operations need progress feedback **Fix**: Same pattern as llm-cloud-management-tool --- ### **6. llm-web-search-tool.ts** 🔴 **Current Signature:** ```typescript export async function llmWebSearch(args: { query: string; maxResults?: number; includeContent?: boolean; llmInstructions?: string; // ... }): Promise<any> // ← No context parameter ``` **Problem**: ❌ No context parameter, no progress/logging **Duration**: **SLOW** (web search with Firecrawl + LLM analysis) **Severity**: 🔴 **CRITICAL** - Web search is slow, needs progress updates **Fix**: Same pattern as llm-cloud-management-tool --- ## Severity Summary | Tool | Operation Speed | Severity | Priority | |------|-----------------|----------|----------| | `conversation-memory-tool` | Fast | 🟢 Low | P3 - Optional | | `expand-analysis-tool` | Fast | 🟢 Low | P3 - Optional | | `perform-research-tool` | **Slow** | 🔴 Critical | **P1 - Must Fix** | | `llm-cloud-management-tool` | **Slow** | 🔴 Critical | **P1 - Must Fix** | | `llm-database-management-tool` | **Slow** | 🔴 Critical | **P1 - Must Fix** | | `llm-web-search-tool` | **Slow** | 🔴 Critical | **P1 - Must Fix** | --- ## Impact Analysis ### **User Experience Impact** 🔴 **Without Progress/Logging (Current State):** ``` User: "Research how authentication works in this project" [30 seconds pass with no feedback] [User thinks it's broken] [60 seconds pass] [User cancels operation] ``` **With Progress/Logging (Correct Implementation):** ``` User: "Research how authentication works in this project" 🔍 Searching project files... [Progress: 25%] 📊 Querying knowledge graph... [Progress: 50%] 🌐 Performing web search... [Progress: 75%] ✅ Research complete [Progress: 100%] [Results displayed] ``` ### **Production Impact** (HTTP Transport) From course notes: > "Setting certain flags to true breaks the workaround, making StreamableHTTP complex to understand and use properly" **Critical Point**: If deploying with `stateless=true` or `jsonResponse=true`: - ❌ Progress notifications won't work anyway - ❌ Logging statements will be lost - ❌ Users get NO feedback at all **Current Risk**: - These tools will have **ZERO feedback** in stateless HTTP deployment - Even worse than stdio transport (which would at least log to stdout) --- ## Comparison with Older Tools ### **✅ Older Tools That Got It Right** ```typescript // Example: analyzeProjectEcosystem (index.ts:4033) private async analyzeProjectEcosystem( args: AnalyzeProjectEcosystemArgs, context?: ToolContext // ← Has context parameter ): Promise<CallToolResult> { const ctx = context || createNoOpContext(); ctx.info('🌐 Starting comprehensive ecosystem analysis'); ctx.report_progress(0, 100); ctx.info('📊 Phase 1: Analyzing project structure'); ctx.report_progress(10, 100); ctx.info('🧠 Phase 2: Generating architectural knowledge'); ctx.report_progress(25, 100); // ... continues with detailed progress updates ... } ``` **Why It Works:** - ✅ Context parameter present - ✅ Progress updates at each phase - ✅ Informative logging messages - ✅ Users see exactly what's happening --- ## Root Cause Analysis ### **Why This Happened** 1. **Timeline**: Newer tools added after Phase 1-3 context decay work 2. **Pattern Inconsistency**: Older tools follow MCP pattern, newer tools don't 3. **No Enforcement**: TypeScript doesn't enforce context parameter 4. **Missing Documentation**: No guidelines on tool creation patterns 5. **Code Review Gap**: Pattern violation not caught in review ### **Why It Matters** From course notes: > "Key benefits: Prevents user confusion about stalled/failed tool calls, Provides visibility into long-running operations, Real-time feedback during tool execution" Long-running tools **MUST** have progress feedback or users will: - ❌ Think the tool is broken - ❌ Cancel operations prematurely - ❌ Have poor experience with the MCP server --- ## Action Plan ### **Priority 1: Critical Long-Running Tools** 🔴 Fix these 4 tools that MUST have progress/logging: 1. **perform-research-tool.ts** - Add `context?: ToolContext` parameter - Add progress updates for: file search, knowledge graph query, web search - Update wrapper in index.ts to pass context down - **Estimated effort**: 1 hour 2. **llm-cloud-management-tool.ts** - Add `context?: ToolContext` parameter - Add progress for: research phase, LLM generation, cloud execution - Update wrapper in index.ts to accept and pass context - **Estimated effort**: 1 hour 3. **llm-database-management-tool.ts** - Add `context?: ToolContext` parameter - Add progress for: research, query generation, database execution - Update wrapper in index.ts - **Estimated effort**: 1 hour 4. **llm-web-search-tool.ts** - Add `context?: ToolContext` parameter - Add progress for: query optimization, web search, LLM analysis - Update wrapper in index.ts - **Estimated effort**: 1 hour **Total P1 Effort**: 4 hours ### **Priority 2: Fast Tools** 🟢 Optional improvements for fast tools: 5. **conversation-memory-tool.ts** - Add context parameter (for consistency) - Single info message: "Retrieving expanded content..." - **Estimated effort**: 15 minutes 6. **expand-analysis-tool.ts** - Add context parameter (for consistency) - Single info message: "Expanding analysis section..." - **Estimated effort**: 15 minutes **Total P2 Effort**: 30 minutes ### **Priority 3: Documentation & Prevention** 📚 7. **Create Tool Development Guidelines** - Document MCP context parameter requirement - Provide template for new tools - Add to CLAUDE.md - **Estimated effort**: 30 minutes 8. **Add TypeScript Helper Type** ```typescript // types/tool-function.ts export type MCPToolFunction<TArgs, TResult = CallToolResult> = ( args: TArgs, context?: ToolContext // ← Enforces context parameter ) => Promise<TResult>; ``` - **Estimated effort**: 15 minutes **Total P3 Effort**: 45 minutes --- ## Implementation Example ### **Before (Violates MCP Best Practices)** ```typescript // ❌ BAD: No context parameter export async function performResearch(args: { question: string; projectPath?: string; }): Promise<any> { // Silent execution - user has no idea what's happening const files = await searchFiles(args.projectPath); const kgResults = await queryKnowledgeGraph(args.question); const webResults = await webSearch(args.question); return combineResults(files, kgResults, webResults); } ``` ### **After (Follows MCP Best Practices)** ```typescript // ✅ GOOD: Context parameter with progress/logging export async function performResearch( args: { question: string; projectPath?: string; }, context?: ToolContext // ← Add context parameter ): Promise<any> { context?.info('🔍 Starting research: ' + args.question); context?.report_progress(0, 100); context?.info('📁 Searching project files...'); const files = await searchFiles(args.projectPath); context?.report_progress(33, 100); context?.info('📊 Querying knowledge graph...'); const kgResults = await queryKnowledgeGraph(args.question); context?.report_progress(66, 100); context?.info('🌐 Performing web search...'); const webResults = await webSearch(args.question); context?.report_progress(90, 100); context?.info('✅ Research complete!'); context?.report_progress(100, 100); return combineResults(files, kgResults, webResults); } ``` --- ## Testing Checklist After implementing fixes, test each tool: - [ ] **Stdio Transport** (local development) - [ ] Progress updates appear in real-time - [ ] Logging messages display correctly - [ ] No errors with context parameter - [ ] **HTTP Transport** (production simulation) - [ ] Progress works with StreamableHTTP - [ ] Test with `stateless=false` (should work) - [ ] Test with `stateless=true` (progress disabled, should not error) - [ ] Logging messages stream correctly via SSE - [ ] **Context Handling** - [ ] Works with context parameter provided - [ ] Works with context=undefined (graceful degradation) - [ ] No crashes if context is null --- ## Conclusion **Severity**: 🔴 **CRITICAL** for 4 long-running tools **Impact**: Poor user experience, appears broken during execution **Fix Complexity**: **LOW** - Simple parameter addition **Total Effort**: ~5 hours for all fixes + documentation **Recommendation**: **Fix immediately** before deploying to production with HTTP transport. Without progress/logging, long-running operations will create terrible user experience. **Next Steps:** 1. Implement Priority 1 fixes (4 hours) 2. Test with both stdio and HTTP transports 3. Add tool development guidelines to prevent future violations 4. Consider Priority 2 fixes for consistency (30 mins) --- **References:** - MCP Course Notes: "Log and Progress Notifications" - MCP Course Notes: "StreamableHTTP Transport" (stateless limitations) - Existing implementation: `analyzeProjectEcosystem` (index.ts:4033) ← Good example --- ## ✅ IMPLEMENTATION COMPLETE **Completion Date**: 2025-10-07 ### Priority 1 Critical Fixes - ✅ COMPLETED (4/4 tools) All 4 critical long-running tools now have MCP progress/logging support: 1. ✅ **perform-research-tool.ts** - COMPLETED - Added `context?: ToolContext` parameter - Added progress updates at 0%, 25%, 50%, 75%, 100% - Added logging for: research start, file search, knowledge graph query, web search, completion - Updated wrapper in index.ts to pass context (line 6616) - **Files Modified**: - `src/tools/perform-research-tool.ts` (lines 8-9, 58-67, 76-98, 217-218) - `src/index.ts` (lines 6605-6619) 2. ✅ **llm-cloud-management-tool.ts** - COMPLETED - Added `context?: ToolContext` parameter - Added progress updates at 0%, 20%, 50%, 80%, 100% - Added logging for: initialization, research phase, LLM generation, cloud execution, completion - Updated wrapper in index.ts to accept and pass context - **Files Modified**: - `src/tools/llm-cloud-management-tool.ts` (lines 7-9, 57-68, 86-128) - `src/index.ts` (lines 6654-6683) 3. ✅ **llm-database-management-tool.ts** - COMPLETED - Added `context?: ToolContext` parameter - Added progress updates at 0%, 20%, 50%, 80%, 100% - Added logging for: initialization, research phase, query generation, database execution, completion - Updated wrapper in index.ts to accept and pass context - **Files Modified**: - `src/tools/llm-database-management-tool.ts` (lines 7-9, 57-68, 86-129) - `src/index.ts` (lines 6688-6717) 4. ✅ **llm-web-search-tool.ts** - COMPLETED - Added `context?: ToolContext` parameter - Added progress updates at 0%, 25%, 50%, 75%, 100% - Added logging for: initialization, query optimization, web search execution, LLM analysis, completion - Updated wrapper in index.ts to accept and pass context - **Files Modified**: - `src/tools/llm-web-search-tool.ts` (lines 7-9, 55-65, 79-115) - `src/index.ts` (lines 6634-6659) ### Verification ✅ **TypeScript Type Checking**: All changes compile without errors ✅ **MCP Best Practices**: All 4 tools now follow the course notes pattern ✅ **Backwards Compatible**: Context parameter is optional, existing code continues to work ✅ **Progress Feedback**: Users will see real-time updates for long-running operations (30-120s) ### User Experience Impact **Before (without progress/logging)**: ``` User: "Research how authentication works in this project" [60 seconds pass with no feedback - user thinks it's broken] ``` **After (with progress/logging)**: ``` User: "Research how authentication works in this project" 🔍 Starting research: how authentication works in this project [0%] 📁 Searching project files... [25%] 📊 Querying knowledge graph and environment resources... [50%] 🌐 Analyzing results and preparing response... [75%] ✅ Research complete! [100%] [Results displayed] ``` ### Remaining Work (Optional - Priority 2) Two fast tools remain without context (optional improvements for consistency): - 🟢 **conversation-memory-tool.ts** (<1s operations) - Low priority - 🟢 **expand-analysis-tool.ts** (<1s operations) - Low priority These are fast operations where progress feedback is less critical, but could be added for consistency. ### Testing Recommendations Before production deployment, test: 1. ✅ Stdio transport (local development) - Progress updates appear in real-time 2. 🔲 HTTP transport (production simulation) - Progress works with StreamableHTTP 3. 🔲 Context handling - Works with context=undefined (graceful degradation) **Status**: Ready for production deployment with stdio transport. HTTP transport testing recommended before production release.

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/tosin2013/mcp-adr-analysis-server'

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