A Model Context Protocol (MCP) server that automatically generates expert-level prompts for LLM applications with tools. Perfect for use with Dedalus and other MCP clients.
LLMs like GPT-4 often fail to properly use tools or output results without explicit instructions. This MCP server automatically generates expert prompts that:
- ✅ Force the LLM to use available tools instead of hallucinating
- ✅ Ensure results are always shown to the user
- ✅ Create proper tool transition workflows
- ✅ Handle errors gracefully
Perfect for Dedalus users who want reliable, consistent tool usage without manual prompt engineering!
npm install
npm run buildimport asyncio
from dedalus_labs import AsyncDedalus, DedalusRunner
async def main():
client = AsyncDedalus()
runner = DedalusRunner(client)
result = await runner.run(
input="Convert 22 Celsius to Fahrenheit and recommend what to wear",
model=["openai/gpt-4"],
tools=[celsius_to_fahrenheit, get_clothing_recommendation],
mcp_servers=["prompt-engineer-mcp"], # This MCP server!
stream=False
)
print(result.final_output)
asyncio.run(main())The prompt engineering MCP will automatically:
- Analyze your available tools
- Generate expert instructions for the LLM
- Ensure tools are used properly and results are shown
See examples/dedalus-integration.py for complete examples.
This MCP server provides a single, powerful tool that generates expert-level system prompts. When used with Dedalus or other MCP clients, it automatically:
- Explicitly define when and how to use each tool
- Create proper transition dynamics between tools
- Ensure results are always outputted to the user
- Address common LLM pitfalls and mistakes
Many nontechnical builders struggle with prompt engineering. A bad prompt might:
- ❌ Not specify that tools should be used, leading to hallucinated responses
- ❌ Fail to instruct the LLM to output results, leaving users without answers
- ❌ Miss tool transition patterns, causing inefficient multi-step workflows
- ❌ Lack error handling instructions, resulting in poor UX
This tool fixes all of these issues automatically.
{
"name": "generate_expert_prompt",
"params": {
"currentPrompt": "Your existing prompt (optional)",
"applicationPurpose": "Description of what your application does",
"tools": [
{
"name": "tool_name",
"description": "What the tool does",
"parameters": [
{
"name": "param_name",
"type": "string",
"description": "Parameter description",
"required": true
}
]
}
]
}
}Input:
{
"applicationPurpose": "Search and retrieve information from a knowledge base",
"tools": [
{
"name": "search_database",
"description": "Search the knowledge base using keywords and filters",
"parameters": [
{
"name": "query",
"type": "string",
"description": "Search query string",
"required": true
}
]
}
]
}Output: A complete, production-ready system prompt that includes:
- Clear tool usage instructions
- When to use each tool
- Mandatory output requirements
- Error handling patterns
- Workflow guidelines
Input:
{
"currentPrompt": "You are a helpful shopping assistant.",
"applicationPurpose": "Help users find products and manage their cart",
"tools": [
{
"name": "search_products",
"description": "Search for products by name or category"
},
{
"name": "add_to_cart",
"description": "Add a product to shopping cart"
}
]
}Output: An enhanced prompt that preserves your original context while adding:
- Explicit tool usage mandates
- Tool transition patterns (search → add to cart)
- Output formatting requirements
- User experience guidelines
-
Mandatory Tool Usage Instructions
- Explicitly states WHEN to use each tool
- Emphasizes that tools are not optional
- Prevents hallucination by enforcing tool usage
-
Output Requirements
- Forces LLM to always show results to users
- Provides formatting guidelines
- Includes examples of proper response patterns
-
Tool Transition Dynamics
- Automatically generates sequential patterns
- Identifies parallel execution opportunities
- Creates conditional usage guidelines
-
Error Handling
- Instructs LLM on how to handle failures
- Provides user-friendly error communication patterns
- Suggests alternative approaches
-
Context Preservation
- Integrates with existing prompts
- Enhances rather than replaces
- Maintains brand voice and specific instructions
The generated prompt includes:
# SYSTEM PROMPT: [Application Purpose]
## Core Responsibilities
[Clear objectives and primary goals]
## Available Tools
[Detailed tool documentation with usage guidelines]
## Tool Usage Workflow
[Step-by-step workflow for every request]
## Tool Transition Dynamics
[How to chain tools together effectively]
## Output Requirements
[CRITICAL: Always provide output - with examples]
## Error Handling
[How to handle and communicate errors]
## Final Reminders
[Key principles to remember]
Perfect for:
- 🤖 AI application developers
- 📱 Chatbot creators
- 🛠️ Tool-calling LLM systems
- 🎓 Teams without prompt engineering expertise
- 🚀 Rapid prototyping of AI features
See examples/test-prompt-engineer.json for more examples including:
- Data analysis assistants
- Multi-tool workflows
- Complex parameter handling
def celsius_to_fahrenheit(celsius: float) -> float:
"""Convert temperature from Celsius to Fahrenheit."""
return (celsius * 9/5) + 32
def get_clothing_recommendation(temp_f: float) -> str:
"""Recommend clothing based on temperature."""
if temp_f < 50:
return "Warm jacket, long pants"
elif temp_f < 80:
return "Light shirt, comfortable pants"
else:
return "T-shirt, shorts"
async def main():
client = AsyncDedalus()
runner = DedalusRunner(client)
# The prompt engineering MCP ensures the LLM:
# 1. Uses celsius_to_fahrenheit first
# 2. Then uses get_clothing_recommendation
# 3. Shows the final result to the user
result = await runner.run(
input="It's 22°C today. What should I wear?",
model=["openai/gpt-4"],
tools=[celsius_to_fahrenheit, get_clothing_recommendation],
mcp_servers=["prompt-engineer-mcp"],
stream=False
)
print(result.final_output)Without this MCP: The LLM might hallucinate the conversion or not use the tools at all.
With this MCP: The LLM reliably converts the temperature and provides clothing recommendations.
def search_products(query: str) -> list:
"""Search product catalog"""
pass
def get_product_details(product_id: str) -> dict:
"""Get detailed product information"""
pass
def add_to_cart(product_id: str, quantity: int) -> dict:
"""Add product to shopping cart"""
pass
result = await runner.run(
input="Find a laptop under $1000 and add it to my cart",
model=["openai/gpt-4"],
tools=[search_products, get_product_details, add_to_cart],
mcp_servers=["prompt-engineer-mcp"],
stream=False
)The prompt engineering MCP creates instructions that ensure:
- Products are searched first
- Details are fetched for the best match
- Item is added to cart
- User receives confirmation with all details
See examples/dedalus-integration.py for complete working examples!
# Without prompt engineering MCP
result = await runner.run(
input="Convert 22C to Fahrenheit",
tools=[celsius_to_fahrenheit],
mcp_servers=[]
)
# LLM might respond: "22C is approximately 71.6F" (hallucinated, didn't use tool!)# With prompt engineering MCP
result = await runner.run(
input="Convert 22C to Fahrenheit",
tools=[celsius_to_fahrenheit],
mcp_servers=["prompt-engineer-mcp"]
)
# LLM: [Calls celsius_to_fahrenheit(22)] → "22°C equals 71.6°F"You can explicitly tell Dedalus to use the prompt engineering tool:
result = await runner.run(
input="""Use the prompt engineering MCP to create expert instructions,
then convert 22C to Fahrenheit and recommend clothing.""",
model=["openai/gpt-4"],
tools=[celsius_to_fahrenheit, get_clothing_recommendation],
mcp_servers=["prompt-engineer-mcp"],
stream=False
)This makes the process explicit and gives you more control.
result = await runner.run(
input="Get weather in Paris, convert to Fahrenheit, recommend clothing",
model=["openai/gpt-4"],
tools=[celsius_to_fahrenheit, get_clothing_recommendation],
mcp_servers=[
"prompt-engineer-mcp", # Ensures proper tool usage
"joerup/open-meteo-mcp", # Provides weather data
],
stream=False
)