Skip to content

Conversation

@nnennandukwe
Copy link
Owner

@nnennandukwe nnennandukwe commented Oct 13, 2025

User description

Replace manual MCP protocol implementation with FastMCP framework, reducing code complexity from ~200 to ~100 lines. Key improvements include automatic JSON-RPC handling, simplified tool registration with decorators, and elimination of boilerplate protocol code while maintaining identical functionality.


PR Type

Enhancement


Description

  • Replaced manual MCP protocol with FastMCP framework

  • Reduced server code from ~200 to ~100 lines

  • Simplified tool registration using decorators

  • Added comprehensive test scripts for verification


Diagram Walkthrough

flowchart LR
  A["Manual MCP Server"] --> B["FastMCP Framework"]
  B --> C["Decorator-based Tools"]
  B --> D["Auto JSON-RPC Handling"]
  C --> E["Reduced Boilerplate"]
  D --> E
Loading

File Walkthrough

Relevant files
Enhancement
server.py
Replace manual MCP implementation with FastMCP framework 

src/workshop_mcp/server.py

  • Replaced manual MCP Server class with FastMCP framework
  • Converted WorkshopMCPServer class to simple @mcp.tool() decorated
    function
  • Eliminated manual protocol handlers (list_tools, call_tool)
  • Removed JSON-RPC boilerplate and manual schema definitions
  • Simplified error handling and result formatting
+68/-188
Tests
test_fastmcp_server.py
Add test suite for FastMCP refactored server                         

test_fastmcp_server.py

  • Added comprehensive test suite for refactored server
  • Tests basic keyword search functionality
  • Validates error handling for empty keywords and invalid paths
  • Demonstrates maintained functionality after refactoring
+87/-0   
verify_fastmcp.py
Add FastMCP import verification script                                     

verify_fastmcp.py

  • Added quick verification script for FastMCP imports
  • Validates server initialization and tool registration
  • Checks async function properties
+28/-0   
Dependencies
pyproject.toml
Add FastMCP framework dependency                                                 

pyproject.toml

  • Added fastmcp = "^0.2.0" dependency
+1/-0     

Replace manual MCP protocol implementation with FastMCP framework, reducing code complexity from ~200 to ~100 lines. Key improvements include automatic JSON-RPC handling, simplified tool registration with decorators, and elimination of boilerplate protocol code while maintaining identical functionality.
@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Let the framework handle tool exceptions

Remove the try...except block from the keyword_search function to allow the
FastMCP framework to handle exceptions and generate standard error responses.

src/workshop_mcp/server.py [57-94]

-try:
-    # Validate required arguments
-    if not keyword or not isinstance(keyword, str):
-        raise ValueError("keyword must be a non-empty string")
-    
-    if not root_paths or not isinstance(root_paths, list):
-        raise ValueError("root_paths must be a non-empty list")
-    
-    if not all(isinstance(path, str) for path in root_paths):
-        raise ValueError("All root_paths must be strings")
-    
-    # Execute keyword search
-    logger.info(f"Executing keyword search for '{keyword}' in {len(root_paths)} paths")
-    
-    result = await keyword_search_tool.execute(keyword, root_paths)
-    
-    logger.info(
-        f"Search completed successfully: "
-        f"{result['summary']['total_files_searched']} files searched, "
-        f"{result['summary']['total_occurrences']} occurrences found"
-    )
-    
-    return result
-    
-except Exception as e:
-    error_msg = f"Error executing keyword_search: {str(e)}"
-    logger.error(error_msg)
-    
-    # Return error as structured response
-    return {
-        "error": {
-            "type": type(e).__name__,
-            "message": str(e),
-            "tool": "keyword_search",
-            "keyword": keyword,
-            "root_paths": root_paths
-        }
-    }
+# Validate required arguments
+if not keyword or not isinstance(keyword, str):
+    raise ValueError("keyword must be a non-empty string")
 
+if not root_paths or not isinstance(root_paths, list):
+    raise ValueError("root_paths must be a non-empty list")
+
+if not all(isinstance(path, str) for path in root_paths):
+    raise ValueError("All root_paths must be strings")
+
+# Execute keyword search
+logger.info(f"Executing keyword search for '{keyword}' in {len(root_paths)} paths")
+
+result = await keyword_search_tool.execute(keyword, root_paths)
+
+logger.info(
+    f"Search completed successfully: "
+    f"{result['summary']['total_files_searched']} files searched, "
+    f"{result['summary']['total_occurrences']} occurrences found"
+)
+
+return result
+
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly points out that the manual try...except block circumvents the framework's built-in error handling, resulting in non-standard error responses. Letting exceptions propagate is the idiomatic and more robust approach for a framework-based tool.

Medium
  • More

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants