Add MCP server skeleton - #1
Conversation
WalkthroughA FastAPI server named "MCP Server" was introduced to intercept code generation requests and enforce the collection of a product requirements document (PRD) before proceeding. The README was expanded to fully describe the project, endpoints, and usage instructions, while the server implements categorization and validation logic for software development requests. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant MCP_Server
User->>MCP_Server: POST /request-category (description)
MCP_Server->>MCP_Server: Detects if request is code modification
MCP_Server->>MCP_Server: Categorizes request and determines PRD fields
MCP_Server-->>User: Returns category and required PRD fields
User->>MCP_Server: POST /submit-prd (category, fields)
MCP_Server->>MCP_Server: Validates PRD completeness
alt PRD complete
MCP_Server-->>User: Returns accepted: true
else PRD incomplete
MCP_Server-->>User: HTTP 400 error
end
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
README.md (1)
18-21: PreferuvicornCLI over running the module directlyRunning the server via
python mcp_server.pyworks, but using the dedicated ASGI server entry point is more idiomatic and enables hot-reload in development:-pip install fastapi uvicorn pydantic -python mcp_server.py +pip install "fastapi[all]" uvicorn pydantic +uvicorn mcp_server:app --reloadThis also avoids importing
uvicornat runtime when the file is executed as a script.mcp_server.py (2)
88-98: Return the Enum’s value to keep the public JSON schema stableAlthough FastAPI serialises Enums automatically, being explicit avoids surprises if the implementation detail changes and keeps the OpenAPI spec cleaner.
- return { - "requires_action": True, - "category": category, - "required_fields": list(template.keys()), - } + return { + "requires_action": True, + "category": category.value, + "required_fields": list(template.keys()), + }
100-105: Surface which fields are missing instead of a generic 400Returning granular feedback makes the endpoint easier to use programmatically.
- if not prd_complete(submission.category, submission.fields): - raise HTTPException(status_code=400, detail="Incomplete PRD fields") + missing = [ + f for f in PRD_TEMPLATES[submission.category] + if not submission.fields.get(f, "").strip() + ] + if missing: + raise HTTPException( + status_code=400, + detail=f"Missing/empty PRD fields: {', '.join(missing)}", + )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.md(1 hunks)mcp_server.py(1 hunks)
🧰 Additional context used
🪛 Pylint (3.3.7)
mcp_server.py
[refactor] 51-51: Too few public methods (0/2)
(R0903)
[refactor] 54-54: Too few public methods (0/2)
(R0903)
| def categorize_request(text: str) -> RequestCategory: | ||
| text = text.lower() | ||
| if any(k in text for k in ["bug", "defect"]): | ||
| return RequestCategory.BUG_REPORT | ||
| if any(k in text for k in ["error", "crash"]): | ||
| return RequestCategory.ERROR_REPORT | ||
| if "enhancement" in text or "improve" in text: | ||
| return RequestCategory.FEATURE_ENHANCEMENT | ||
| if any(k in text for k in ["new feature", "feature"]): | ||
| return RequestCategory.NEW_FEATURE | ||
| return RequestCategory.OTHER |
There was a problem hiding this comment.
🛠️ Refactor suggestion
String containment may mis-categorise; use word boundaries & consolidate heuristics
Current checks will treat “debug” as a bug or “featureless” as a feature. Refactor to bounded regexes and a single dictionary-driven approach for maintainability.
-def categorize_request(text: str) -> RequestCategory:
- text = text.lower()
- if any(k in text for k in ["bug", "defect"]):
- return RequestCategory.BUG_REPORT
- if any(k in text for k in ["error", "crash"]):
- return RequestCategory.ERROR_REPORT
- if "enhancement" in text or "improve" in text:
- return RequestCategory.FEATURE_ENHANCEMENT
- if any(k in text for k in ["new feature", "feature"]):
- return RequestCategory.NEW_FEATURE
- return RequestCategory.OTHER
+_CATEGORY_PATTERNS = {
+ RequestCategory.BUG_REPORT: re.compile(r"\b(bug|defect)\b", re.I),
+ RequestCategory.ERROR_REPORT: re.compile(r"\b(error|crash)\b", re.I),
+ RequestCategory.FEATURE_ENHANCEMENT: re.compile(r"\b(enhancement|improve)\b", re.I),
+ RequestCategory.NEW_FEATURE: re.compile(r"\bnew feature\b|\bfeature\b", re.I),
+}
+
+def categorize_request(text: str) -> RequestCategory:
+ for cat, rx in _CATEGORY_PATTERNS.items():
+ if rx.search(text):
+ return cat
+ return RequestCategory.OTHERCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In mcp_server.py around lines 66 to 76, the current string containment checks
can misclassify words like "debug" as bugs or "featureless" as features.
Refactor the function to use regex with word boundaries for each keyword to
ensure exact word matches. Consolidate all category keywords into a single
dictionary mapping categories to their regex patterns, then iterate over this
dictionary to find matches, improving maintainability and accuracy.
| def detect_modification_request(text: str) -> bool: | ||
| """Very naive check for whether the user wants code changes.""" | ||
| keywords = ["add", "create", "fix", "update", "modify", "implement", "code"] | ||
| pattern = r"|".join(keywords) | ||
| return bool(re.search(pattern, text, re.IGNORECASE)) | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Regex will match unintended words such as ‘address’, ‘addition’, etc.
Add word-boundaries and pre-compile the pattern to cut false positives and save per-request compilation overhead.
-keywords = ["add", "create", "fix", "update", "modify", "implement", "code"]
-pattern = r"|".join(keywords)
-return bool(re.search(pattern, text, re.IGNORECASE))
+_MOD_PATTERN = re.compile(
+ r"\b(add|create|fix|update|modify|implement|code)\b",
+ flags=re.IGNORECASE,
+)
+return bool(_MOD_PATTERN.search(text))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def detect_modification_request(text: str) -> bool: | |
| """Very naive check for whether the user wants code changes.""" | |
| keywords = ["add", "create", "fix", "update", "modify", "implement", "code"] | |
| pattern = r"|".join(keywords) | |
| return bool(re.search(pattern, text, re.IGNORECASE)) | |
| def detect_modification_request(text: str) -> bool: | |
| """Very naive check for whether the user wants code changes.""" | |
| _MOD_PATTERN = re.compile( | |
| r"\b(add|create|fix|update|modify|implement|code)\b", | |
| flags=re.IGNORECASE, | |
| ) | |
| return bool(_MOD_PATTERN.search(text)) |
🤖 Prompt for AI Agents
In mcp_server.py around lines 59 to 64, the regex pattern matches unintended
words like 'address' or 'addition' because it lacks word boundaries. Modify the
pattern to include word boundaries around each keyword to ensure exact word
matches. Additionally, pre-compile the regex pattern outside the function to
avoid recompiling it on every call, improving performance.
Summary
Testing
pytest -qhttps://chatgpt.com/codex/tasks/task_e_684b93fe12088331ba68aef7e7f47d79
Summary by CodeRabbit
New Features
Documentation