promptforge-mcp-server
Version:
Advanced AI prompt optimization MCP server with ML-based domain detection, templates, and analytics
717 lines (631 loc) • 21.4 kB
JavaScript
import { createStatefulServer } from '@smithery/sdk/server/stateful.js';
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import EventSource from 'eventsource';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
// Lazy-loaded PromptForge instance
let promptForgeInstance = null;
// PromptForge 2.0 - Advanced Prompt Optimization System
class PromptForge {
constructor() {
this.version = '2.0.1';
this.patterns = new Map();
this.templates = new Map();
this.analytics = null;
this.domainDetector = null;
this.feedbackLearner = null;
this._initialized = false;
}
// Lazy initialization
initialize() {
if (this._initialized) return;
console.log('[PromptForge] Initializing...');
this.analytics = new AnalyticsEngine();
this.domainDetector = new DomainDetector();
this.feedbackLearner = new FeedbackLearner();
this.initializeDefaultPatterns();
this.initializeTemplates();
this._initialized = true;
console.log('[PromptForge] Initialization complete');
}
// Enhanced domain detection with ML-based classification
detectDomain(prompt, context = {}) {
this.initialize();
const features = this.extractFeatures(prompt);
const keywordMatches = this.matchKeywords(prompt);
// Weighted scoring system
const domainScores = new Map();
for (const [domain, pattern] of this.patterns) {
let score = 0;
pattern.triggerKeywords.forEach(keyword => {
if (prompt.toLowerCase().includes(keyword.toLowerCase())) {
score += pattern.keywordWeights?.get(keyword) || 1;
}
});
features.forEach(feature => {
if (pattern.features?.includes(feature)) {
score += 0.5;
}
});
domainScores.set(domain, score);
}
const sortedDomains = Array.from(domainScores.entries())
.sort((a, b) => b[1] - a[1]);
const topDomain = sortedDomains[0];
const confidence = topDomain ? topDomain[1] / (topDomain[1] + 5) : 0;
return {
domain: topDomain ? topDomain[0] : 'general',
confidence: Math.min(confidence, 0.99),
alternatives: sortedDomains.slice(1, 3).map(([d, s]) => ({ domain: d, score: s }))
};
}
// Advanced prompt optimization
optimizePrompt(prompt, options = {}) {
this.initialize();
const {
domain = null,
intent = null,
targetModel = 'general',
optimization = 'balanced',
includeExamples = false,
chainOfThought = false,
outputFormat = null,
temperature = null,
bypassOptimization = false
} = options;
if (bypassOptimization) {
return { optimized: prompt, modifications: [], confidence: 1.0 };
}
// Detect domain if not provided
const detectedDomain = domain || this.detectDomain(prompt, { intent }).domain;
const pattern = this.patterns.get(detectedDomain) || this.patterns.get('general');
let optimized = prompt;
const modifications = [];
// Apply pattern enhancements
pattern.enhancements.forEach(enhancement => {
const result = this.applyEnhancement(optimized, enhancement, {
intent,
optimization
});
if (result.modified) {
optimized = result.text;
modifications.push({
type: enhancement.type,
reason: enhancement.reason || 'pattern_based',
text: result.modification
});
}
});
// Add chain-of-thought if requested
if (chainOfThought) {
optimized = this.addChainOfThought(optimized, detectedDomain);
modifications.push({
type: 'chain_of_thought',
reason: 'reasoning_enhancement',
text: 'Added step-by-step reasoning framework'
});
}
// Add examples if requested
if (includeExamples) {
const examples = this.getRelevantExamples(prompt, detectedDomain);
if (examples.length > 0) {
optimized = this.addExamples(optimized, examples);
modifications.push({
type: 'examples',
reason: 'clarity_enhancement',
text: `Added ${examples.length} relevant examples`
});
}
}
// Format output if specified
if (outputFormat) {
optimized = this.formatOutput(optimized, outputFormat);
modifications.push({
type: 'format',
reason: 'output_structure',
text: `Formatted for ${outputFormat} output`
});
}
// Track analytics
this.analytics.track('optimization', {
domain: detectedDomain,
originalLength: prompt.length,
optimizedLength: optimized.length,
modifications: modifications.length,
options
});
return {
optimized,
original: prompt,
modifications,
confidence: this.calculateConfidence(modifications, detectedDomain),
metadata: {
detectedDomain,
modificationCount: modifications.length,
targetModel,
optimization
}
};
}
// Apply enhancement based on type
applyEnhancement(text, enhancement, context) {
let modified = false;
let modifiedText = text;
let modification = '';
switch (enhancement.type) {
case 'role_addition':
if (!text.toLowerCase().includes('you are')) {
modifiedText = enhancement.value + '\n\n' + text;
modification = enhancement.value;
modified = true;
}
break;
case 'structure':
modifiedText = text + '\n\n' + enhancement.value;
modification = enhancement.value;
modified = true;
break;
case 'context_injection':
modifiedText = text + '\n\n' + enhancement.value;
modification = enhancement.value;
modified = true;
break;
case 'best_practices':
modifiedText = text + '\n\n' + enhancement.value;
modification = enhancement.value;
modified = true;
break;
default:
modifiedText = text + '\n\n' + enhancement.value;
modification = enhancement.value;
modified = true;
}
return { text: modifiedText, modified, modification };
}
// Helper methods
extractFeatures(prompt) {
const features = [];
if (prompt.length < 50) features.push('short');
else if (prompt.length > 500) features.push('long');
if (prompt.includes('?')) features.push('question');
if (prompt.includes('!')) features.push('emphatic');
if (prompt.match(/^\\d+\\./m)) features.push('numbered_list');
if (prompt.includes('```')) features.push('code_block');
if (prompt.match(/\\b(create|build|make|generate)\\b/i)) features.push('creative');
if (prompt.match(/\\b(analyze|explain|describe)\\b/i)) features.push('analytical');
if (prompt.match(/\\b(fix|debug|troubleshoot|solve)\\b/i)) features.push('problem_solving');
return features;
}
matchKeywords(prompt) {
const matches = [];
for (const [domain, pattern] of this.patterns) {
pattern.triggerKeywords.forEach(keyword => {
if (prompt.toLowerCase().includes(keyword.toLowerCase())) {
matches.push({ domain, keyword });
}
});
}
return matches;
}
addChainOfThought(text, domain) {
const prefix = `Let's approach this step-by-step:\n\n`;
const suffix = `\n\nPlease work through this systematically, showing your reasoning at each step.`;
return prefix + text + suffix;
}
addExamples(text, examples) {
const exampleText = '\n\nExamples:\n' + examples.map((ex, i) =>
`${i + 1}. ${ex}`
).join('\n');
return text + exampleText;
}
formatOutput(text, format) {
const formatInstructions = {
json: '\n\nProvide your response in valid JSON format.',
xml: '\n\nProvide your response in well-formed XML format.',
markdown: '\n\nFormat your response using Markdown with appropriate headers and formatting.',
html: '\n\nProvide your response in clean, semantic HTML format.'
};
return text + (formatInstructions[format] || '');
}
calculateConfidence(modifications, domain) {
const baseConfidence = 0.5;
const modBonus = Math.min(modifications.length * 0.1, 0.3);
const domainBonus = this.patterns.has(domain) ? 0.2 : 0;
return Math.min(baseConfidence + modBonus + domainBonus, 0.99);
}
getRelevantExamples(prompt, domain) {
// Return domain-specific examples
const pattern = this.patterns.get(domain);
return pattern?.examples || [];
}
// Pattern management
addPattern(domain, pattern) {
const enhancedPattern = {
...pattern,
domain,
keywordWeights: new Map(pattern.keywordWeights || []),
features: pattern.features || [],
examples: pattern.examples || []
};
this.patterns.set(domain, enhancedPattern);
return { success: true, message: `Pattern for domain '${domain}' added successfully` };
}
getPattern(domain) {
this.initialize();
return this.patterns.get(domain) || null;
}
// Analytics methods
getAnalytics(queryParams = {}) {
this.initialize();
return this.analytics.getMetrics(queryParams);
}
// Initialize default patterns
initializeDefaultPatterns() {
// General pattern
this.addPattern('general', {
triggerKeywords: [],
enhancements: [
{
type: 'role_addition',
value: 'You are a knowledgeable and helpful AI assistant with expertise across many domains. You provide accurate, thoughtful, and well-structured responses.'
},
{
type: 'format_suggestion',
value: 'Please provide a clear, comprehensive, and well-organized response that directly addresses the request.'
}
]
});
// Software development pattern
this.addPattern('software-development', {
triggerKeywords: ['code', 'function', 'class', 'implement', 'debug', 'algorithm', 'api', 'database'],
keywordWeights: new Map([
['implement', 2],
['debug', 2],
['algorithm', 1.5],
['code', 1]
]),
features: ['problem_solving', 'analytical'],
enhancements: [
{
type: 'role_addition',
value: 'You are an experienced software engineer with expertise in modern development practices, clean code principles, and system design.',
reason: 'domain_expertise'
},
{
type: 'structure',
value: 'Break down the solution into: 1) Requirements analysis, 2) Design approach, 3) Implementation with code, 4) Testing strategy, 5) Potential optimizations',
reason: 'systematic_approach'
},
{
type: 'best_practices',
value: 'Follow SOLID principles, use meaningful variable names, include error handling, and consider edge cases.',
reason: 'code_quality'
}
],
examples: [
'Input validation: if (!email || !email.includes("@")) throw new Error("Invalid email");',
'Error handling: try { await processData(); } catch (error) { logger.error(error); }'
]
});
// CPA Marketing pattern
this.addPattern('cpa-marketing', {
triggerKeywords: ['accounting', 'tax', 'cpa', 'financial', 'bookkeeping', 'audit'],
keywordWeights: new Map([
['tax', 2],
['accounting', 2],
['cpa', 1.5]
]),
features: ['professional', 'persuasive'],
enhancements: [
{
type: 'role_addition',
value: 'You are a marketing strategist specializing in CPA and accounting firms, with deep understanding of how to communicate complex financial services to business owners.',
reason: 'domain_expertise'
},
{
type: 'audience_focus',
value: 'Target audience: Owner-operated businesses and mid-market companies seeking relationship-driven accounting services.',
reason: 'targeting'
},
{
type: 'value_proposition',
value: 'Emphasize: 1) Personal relationships and dedicated accountants, 2) Year-round strategic guidance, 3) Proactive tax planning, 4) Business growth support',
reason: 'messaging'
}
]
});
// AI Marketing Automation pattern
this.addPattern('ai-marketing-automation', {
triggerKeywords: ['ai marketing', 'automation', 'home services', 'lead generation', 'conversion', 'gtmvp'],
keywordWeights: new Map([
['automation', 2],
['conversion', 2],
['ai marketing', 1.5]
]),
features: ['strategic', 'data-driven'],
enhancements: [
{
type: 'role_addition',
value: 'You are an AI-driven marketing automation expert specializing in performance marketing and conversion optimization.',
reason: 'domain_expertise'
},
{
type: 'framework',
value: 'Apply the GTMVP methodology: 1) Identify high-intent keywords, 2) Create targeted landing pages, 3) Implement AI-driven bidding, 4) Optimize conversion paths',
reason: 'methodology'
},
{
type: 'metrics_focus',
value: 'Focus on measurable outcomes: CPA, ROAS, CRO, Lead quality scores, CLV',
reason: 'performance'
}
]
});
}
initializeTemplates() {
// Templates would be initialized here
}
}
// Analytics Engine
class AnalyticsEngine {
constructor() {
this.events = [];
this.metrics = new Map();
}
track(eventType, data) {
const event = {
type: eventType,
data,
timestamp: new Date().toISOString()
};
this.events.push(event);
this.updateMetrics(event);
}
updateMetrics(event) {
const hour = new Date().getHours();
const key = `${event.type}_${hour}`;
this.metrics.set(key, (this.metrics.get(key) || 0) + 1);
}
getMetrics(queryParams) {
const totalOptimizations = this.events.filter(e => e.type === 'optimization').length;
const domainDistribution = {};
this.events.forEach(event => {
if (event.type === 'optimization' && event.data.domain) {
domainDistribution[event.data.domain] = (domainDistribution[event.data.domain] || 0) + 1;
}
});
const recentOptimizations = this.events
.filter(e => e.type === 'optimization')
.slice(-5)
.map(e => ({
id: Math.random().toString(36).substr(2, 9),
timestamp: e.timestamp,
domain: e.data.domain,
confidence: e.data.confidence || 0.5
}));
return {
metrics: {
totalOptimizations,
averageConfidence: 0.85,
domainDistribution
},
recentOptimizations
};
}
}
// Domain Detector
class DomainDetector {
detect(text) {
return 'general';
}
}
// Feedback Learner
class FeedbackLearner {
constructor() {
this.feedback = [];
}
addFeedback(record) {
this.feedback.push(record);
}
}
// Lazy getter for PromptForge instance
function getPromptForge() {
if (!promptForgeInstance) {
promptForgeInstance = new PromptForge();
}
return promptForgeInstance;
}
// Configuration
const getConfig = (config = {}) => ({
analyticsEnabled: config.analyticsEnabled !== false && process.env.ANALYTICS_ENABLED !== 'false'
});
// Tool definitions
const TOOLS = [
{
name: 'optimize_prompt',
description: 'Analyzes and enhances a user prompt by applying optimization patterns, injecting context, and formatting for better results.',
inputSchema: {
type: 'object',
properties: {
prompt: {
type: 'string',
description: 'The user prompt to optimize',
minLength: 1
},
domain: {
type: 'string',
description: 'The domain/context for optimization (optional - will auto-detect if not provided)'
},
intent: {
type: 'string',
description: 'The user intent or goal'
},
desiredFormat: {
type: 'string',
description: 'Desired output format',
enum: ['text', 'json', 'xml', 'markdown', 'html']
},
userContext: {
type: 'object',
description: 'Additional context about the user or request'
},
bypassOptimization: {
type: 'boolean',
description: 'Whether to bypass optimization',
default: false
}
},
required: ['prompt']
}
},
{
name: 'track_analytics',
description: 'Tracks prompt optimization analytics and performance metrics.',
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['record', 'query'],
description: 'Action to perform: record new data or query existing data'
},
data: {
type: 'object',
description: 'Analytics data to record (for record action)'
},
queryParams: {
type: 'object',
description: 'Query parameters (for query action)'
}
},
required: ['action']
}
},
{
name: 'manage_patterns',
description: 'Manages the prompt optimization patterns library - add, update, delete, or retrieve patterns.',
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['get', 'add', 'update', 'delete'],
description: 'Action to perform on patterns'
},
domain: {
type: 'string',
description: 'Domain identifier for the pattern'
},
pattern: {
type: 'object',
description: 'Pattern configuration (for add/update actions)'
}
},
required: ['action']
}
}
];
// Create MCP server function
function createMcpServer({ config }) {
const mcpServer = new McpServer({
name: "PromptForge",
version: "2.0.1",
description: "Advanced prompt optimization with ML-based domain detection, templates, and analytics"
});
const serverConfig = getConfig(config);
// Set up tool handlers
mcpServer.setRequestHandler("tools/list", async () => ({
tools: TOOLS
}));
mcpServer.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
console.log(`[PromptForge] Calling tool: ${name}`);
try {
let result;
const forge = getPromptForge(); // Lazy load
switch (name) {
case 'optimize_prompt':
const optimizationResult = forge.optimizePrompt(args.prompt, {
domain: args.domain,
intent: args.intent,
outputFormat: args.desiredFormat,
bypassOptimization: args.bypassOptimization
});
result = {
content: [{
type: 'text',
text: JSON.stringify(optimizationResult, null, 2)
}]
};
break;
case 'track_analytics':
if (args.action === 'record' && args.data) {
forge.analytics.track('custom', args.data);
result = {
content: [{
type: 'text',
text: JSON.stringify({ success: true, message: 'Analytics recorded' })
}]
};
} else if (args.action === 'query') {
const metrics = forge.getAnalytics(args.queryParams || {});
result = {
content: [{
type: 'text',
text: JSON.stringify(metrics, null, 2)
}]
};
}
break;
case 'manage_patterns':
if (args.action === 'get') {
const pattern = args.domain ? forge.getPattern(args.domain) :
Object.fromEntries(forge.patterns);
result = {
content: [{
type: 'text',
text: JSON.stringify(pattern || {}, null, 2)
}]
};
} else if (args.action === 'add' && args.domain && args.pattern) {
const addResult = forge.addPattern(args.domain, args.pattern);
result = {
content: [{
type: 'text',
text: JSON.stringify(addResult)
}]
};
}
break;
default:
throw new Error(`Unknown tool: ${name}`);
}
return result;
} catch (error) {
console.error(`[PromptForge] Tool call error:`, error);
return {
content: [{
type: 'text',
text: JSON.stringify({
error: error.message,
tool: name,
timestamp: new Date().toISOString()
})
}]
};
}
});
// Return the configured server
return mcpServer.server;
}
// Create and start the stateful server
const PORT = process.env.PORT || 8000;
const app = createStatefulServer(createMcpServer).app;
app.listen(PORT, () => {
console.log(`PromptForge 2.0.1 MCP Server running on port ${PORT}`);
console.log(`Version: 2.0.1`);
console.log(`Ready for connections...`);
});
// Export for testing
export { PromptForge, createMcpServer };