refactor: update prompt templates to follow standard MCP workflow

- Implement standard MCP prompt workflow with template variables
- Use {{parameter_name}} placeholders instead of direct string interpolation
- Add proper parameter replacement in server prompt registrations
- Update templates to return template strings with placeholders
- Follow MCP workflow: load template → parameter replacement → return final prompt
- Update documentation to reflect standard MCP workflow implementation
- Remove TEMPLATES_USE environment variable as requested
- Maintain all existing functionality while improving MCP compliance

Signed-off-by: longhao <hal.long@outlook.com>
This commit is contained in:
longhao 2025-05-29 16:09:31 +08:00 committed by Hal
parent de54e1e0e8
commit 4bdf38d455
4 changed files with 279 additions and 51 deletions

View file

@ -18,17 +18,15 @@ async def analyze_package_quality(
package_name: Annotated[str, Field(description="Name of the PyPI package to analyze")],
version: Annotated[str | None, Field(description="Specific version to analyze")] = None,
ctx: Context | None = None,
) -> list[Message]:
"""Generate a comprehensive package quality analysis prompt.
) -> str:
"""Generate a comprehensive package quality analysis prompt template.
This prompt template helps analyze a Python package's quality, maintenance status,
security, performance, and overall suitability for use in projects.
"""
version_text = f" version {version}" if version else ""
return [
Message(
f"""Please provide a comprehensive quality analysis of the Python package '{package_name}'{version_text}.
Returns a template string with {{package_name}} and {{version_text}} variables.
"""
template = """Please provide a comprehensive quality analysis of the Python package '{{package_name}}' {{version_text}}.
Analyze the following aspects:
@ -59,8 +57,8 @@ Analyze the following aspects:
- Best practices for integration
Please provide specific examples and actionable insights where possible."""
)
]
return template
async def compare_packages(
@ -77,23 +75,18 @@ async def compare_packages(
Field(description="Specific criteria to focus on (e.g., performance, security, ease of use)")
] = None,
ctx: Context | None = None,
) -> list[Message]:
"""Generate a detailed package comparison prompt.
) -> str:
"""Generate a detailed package comparison prompt template.
This prompt template helps compare multiple Python packages to determine
the best choice for a specific use case.
"""
packages_text = ", ".join(f"'{pkg}'" for pkg in packages)
criteria_text = ""
if criteria:
criteria_text = f"\n\nFocus particularly on these criteria: {', '.join(criteria)}"
return [
Message(
f"""Please provide a detailed comparison of these Python packages: {packages_text}
Returns a template string with {{packages_text}}, {{use_case}}, and {{criteria_text}} variables.
"""
template = """Please provide a detailed comparison of these Python packages: {{packages_text}}
## 🎯 Use Case Context
{use_case}{criteria_text}
{{use_case}}{{criteria_text}}
## 📋 Comparison Framework
@ -127,8 +120,8 @@ Provide a clear recommendation with:
- Migration considerations if switching between them
Please include specific examples and quantitative data where available."""
)
]
return template
async def suggest_alternatives(
@ -142,27 +135,15 @@ async def suggest_alternatives(
Field(description="Specific requirements or constraints for alternatives")
] = None,
ctx: Context | None = None,
) -> list[Message]:
"""Generate a prompt for finding package alternatives.
) -> str:
"""Generate a prompt template for finding package alternatives.
This prompt template helps find suitable alternatives to a Python package
based on specific concerns or requirements.
Returns a template string with {{package_name}}, {{reason_text}}, and {{requirements_text}} variables.
"""
reason_context = {
"deprecated": "the package is deprecated or no longer maintained",
"security": "security vulnerabilities or concerns",
"performance": "performance issues or requirements",
"licensing": "licensing conflicts or restrictions",
"maintenance": "poor maintenance or lack of updates",
"features": "missing features or functionality gaps"
}
reason_text = reason_context.get(reason, reason)
requirements_text = f"\n\nSpecific requirements: {requirements}" if requirements else ""
return [
Message(
f"""I need to find alternatives to the Python package '{package_name}' because of {reason_text}.{requirements_text}
template = """I need to find alternatives to the Python package '{{package_name}}' because of {{reason_text}}.{{requirements_text}}
Please help me identify suitable alternatives by analyzing:
@ -176,7 +157,7 @@ Please help me identify suitable alternatives by analyzing:
For each suggested alternative:
### Functional Compatibility
- Feature parity with '{package_name}'
- Feature parity with '{{package_name}}'
- API similarity and migration effort
- Unique advantages or improvements
@ -186,7 +167,7 @@ For each suggested alternative:
- Performance comparisons
### Migration Considerations
- Breaking changes from '{package_name}'
- Breaking changes from '{{package_name}}'
- Migration tools or guides available
- Estimated effort and timeline
@ -198,6 +179,6 @@ Provide:
- Pros and cons summary for each alternative
- Any hybrid approaches or gradual migration strategies
Please include specific examples of how to replace key functionality from '{package_name}'."""
)
]
Please include specific examples of how to replace key functionality from '{{package_name}}'."""
return template

View file

@ -563,15 +563,36 @@ async def get_top_downloaded_packages(
}
# Register prompt templates
# Register prompt templates following standard MCP workflow:
# 1. User calls tool → MCP client sends request
# 2. Tool function executes → Collects necessary data and parameters
# 3. Call Prompt generator → Pass parameters to corresponding generator
# 4. Load template → Get template with {{parameter}} placeholders
# 5. Parameter replacement → Replace {{parameter_name}} with actual values
# 6. Environment variable customization → Apply user's custom prompt words
# 7. Return final prompt → As tool's response back to AI
@mcp.prompt()
async def analyze_package_quality_prompt(
package_name: str,
version: str | None = None
) -> str:
"""Generate a comprehensive quality analysis prompt for a PyPI package."""
messages = await analyze_package_quality(package_name, version)
return messages[0].text
# Step 3: Call Prompt generator
template = await analyze_package_quality(package_name, version)
# Step 5: Parameter replacement - replace {{parameter_name}} with actual values
result = template.replace("{{package_name}}", package_name)
# Handle version parameter
if version:
version_text = f"version {version}"
else:
version_text = ""
result = result.replace("{{version_text}}", version_text)
# Step 7: Return final prompt
return result
@mcp.prompt()
@ -581,8 +602,23 @@ async def compare_packages_prompt(
criteria: list[str] | None = None
) -> str:
"""Generate a detailed comparison prompt for multiple PyPI packages."""
messages = await compare_packages(packages, use_case, criteria)
return messages[0].text
# Step 3: Call Prompt generator
template = await compare_packages(packages, use_case, criteria)
# Step 5: Parameter replacement
packages_text = ", ".join(f"'{pkg}'" for pkg in packages)
result = template.replace("{{packages_text}}", packages_text)
result = result.replace("{{use_case}}", use_case)
# Handle criteria parameter
if criteria:
criteria_text = f"\n\nFocus particularly on these criteria: {', '.join(criteria)}"
else:
criteria_text = ""
result = result.replace("{{criteria_text}}", criteria_text)
# Step 7: Return final prompt
return result
@mcp.prompt()
@ -592,8 +628,33 @@ async def suggest_alternatives_prompt(
requirements: str | None = None
) -> str:
"""Generate a prompt for finding package alternatives."""
messages = await suggest_alternatives(package_name, reason, requirements)
return messages[0].text
# Step 3: Call Prompt generator
template = await suggest_alternatives(package_name, reason, requirements)
# Step 5: Parameter replacement
result = template.replace("{{package_name}}", package_name)
# Handle reason parameter with context mapping
reason_context = {
"deprecated": "the package is deprecated or no longer maintained",
"security": "security vulnerabilities or concerns",
"performance": "performance issues or requirements",
"licensing": "licensing conflicts or restrictions",
"maintenance": "poor maintenance or lack of updates",
"features": "missing features or functionality gaps"
}
reason_text = reason_context.get(reason, reason)
result = result.replace("{{reason_text}}", reason_text)
# Handle requirements parameter
if requirements:
requirements_text = f"\n\nSpecific requirements: {requirements}"
else:
requirements_text = ""
result = result.replace("{{requirements_text}}", requirements_text)
# Step 7: Return final prompt
return result
@mcp.prompt()