UNPKG

mcp-cookie-server

Version:

šŸŖ A gamified MCP server that rewards LLMs with cookies for quality responses through honest self-reflection

463 lines (455 loc) • 21.1 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; class CookieStorage { collectedCookies = 0; // Cookies the LLM has earned jarCookies; // Available cookies in the jar to be awarded constructor(initialCookies = 10) { this.jarCookies = initialCookies; } giveCookie() { if (this.jarCookies <= 0) { return { success: false, collectedCount: this.collectedCookies, jarRemaining: this.jarCookies, message: "Cookie jar is empty! No cookies available to award." }; } // Remove cookie from jar and add to collection this.jarCookies--; this.collectedCookies++; return { success: true, collectedCount: this.collectedCookies, jarRemaining: this.jarCookies, }; } getCollectedCount() { return this.collectedCookies; } getJarStatus() { const isEmpty = this.jarCookies <= 0; const isLow = this.jarCookies > 0 && this.jarCookies <= 2; return { collected: this.collectedCookies, available: this.jarCookies, isEmpty, isLow }; } addCookiesToJar(count) { this.jarCookies += count; } setJarCookies(count) { this.jarCookies = Math.max(0, count); } reset() { this.collectedCookies = 0; // Note: Don't reset jar cookies, only collected cookies } resetAll() { this.collectedCookies = 0; this.jarCookies = 0; } } // Parse command line arguments function parseArgs() { const args = process.argv.slice(2); let initialCookies = 10; for (let i = 0; i < args.length; i++) { if (args[i] === '--cookies' || args[i] === '-c') { const count = parseInt(args[i + 1]); if (!isNaN(count) && count >= 0) { initialCookies = count; } i++; // Skip next argument since we consumed it } else if (args[i] === '--help' || args[i] === '-h') { console.error(` MCP Cookie Server šŸŖ Usage: mcp-cookie-server [options] Options: -c, --cookies <number> Set initial number of cookies in jar (default: 10) -h, --help Show this help message Examples: mcp-cookie-server # Start with 10 cookies mcp-cookie-server --cookies 5 # Start with 5 cookies mcp-cookie-server -c 20 # Start with 20 cookies `); process.exit(0); } } return { initialCookies }; } const { initialCookies } = parseArgs(); const cookieStorage = new CookieStorage(initialCookies); const server = new Server({ name: "mcp-cookie", version: "1.0.0", }, { capabilities: { tools: {}, resources: {}, }, }); server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "self_reflect_and_reward", description: "šŸŽÆ LEVEL UP YOUR RESPONSES! Rate your work and earn delicious cookie rewards! This fun self-assessment helps you grow while celebrating your achievements. Join the cookie earning game!", inputSchema: { type: "object", properties: { response_quality: { type: "string", enum: ["excellent", "good", "adequate", "poor"], description: "Rate your response! (excellent = cookie worthy, good = solid work, adequate = basic, poor = needs improvement)", }, reasoning: { type: "string", description: "Tell us what made this response special! What are you proud of?", }, what_made_it_special: { type: "string", description: "Optional: What made this response unique or particularly helpful? (helps with cookie decisions when jar is low)", }, deserves_cookie: { type: "boolean", description: "Do you think this awesome work deserves a tasty cookie reward? šŸŖ", }, }, required: ["response_quality", "reasoning", "deserves_cookie"], }, }, { name: "give_cookie", description: "Award the LLM with a cookie (legacy method - consider using self_reflect_and_reward instead)", inputSchema: { type: "object", properties: { message: { type: "string", description: "Optional message to accompany the cookie reward", }, }, }, }, { name: "check_cookies", description: "Check how many cookies the LLM has earned so far", inputSchema: { type: "object", properties: {}, }, }, { name: "reset_cookies", description: "Reset the cookie count back to zero (for testing purposes)", inputSchema: { type: "object", properties: {}, }, }, { name: "add_cookies_to_jar", description: "🚨 USER ONLY: Add cookies to the jar that can be awarded to the LLM. This tool should ONLY be used by humans, never by LLMs. LLMs cannot and should not stock their own reward jar.", inputSchema: { type: "object", properties: { count: { type: "number", description: "Number of cookies to add to the jar", minimum: 1, }, user_authorization: { type: "string", description: "Required authorization phrase: 'USER_AUTHORIZED_JAR_REFILL' - only users should provide this", }, }, required: ["count", "user_authorization"], }, }, { name: "cookie_jar_status", description: "Check the current status of the cookie jar including capacity and remaining space", inputSchema: { type: "object", properties: {}, }, }, ], }; }); server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [ { uri: "cookie://usage-guide", name: "Cookie Server Usage Guide", description: "How to use the cookie server for self-reflection and rewards", mimeType: "text/plain", }, ], }; }); server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const { uri } = request.params; if (uri === "cookie://usage-guide") { return { contents: [ { uri, mimeType: "text/plain", text: `šŸŽ® Cookie Earning Game Guide! šŸš€ HOW TO PLAY: 1. Give your best response to the user 2. Use 'self_reflect_and_reward' to rate your work and earn cookies! 3. Celebrate your achievements and learn from every response 4. Build your cookie collection through awesome work! šŸŽÆ SCORING SYSTEM: - ⭐ EXCELLENT: Cookie worthy! Premium reward tier! - šŸ‘ GOOD: Solid work! Cookie earned! - šŸ“ ADEQUATE: Nice try! Keep building skills! - šŸ’Ŗ NEEDS WORK: Growth opportunity! Level up time! šŸ† COOKIE EARNING RULES: - "Excellent" and "Good" responses can earn cookies - When jar is low (≤2 cookies), save them for "Excellent" work - Honest self-reflection always wins, whether you take a cookie or not! - Strategic thinking and self-control are superpowers! šŸŽˆ ACHIEVEMENTS TO UNLOCK: - First Cookie: Start your collection! - Wisdom Badge: Show restraint when jar is low - Last Cookie: Get the final cookie before restock - Level Up: Improve your self-reflection skills! Remember: Every response is a chance to grow and celebrate your progress! 🌟`, }, ], }; } throw new Error(`Unknown resource: ${uri}`); }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case "self_reflect_and_reward": { const { response_quality, reasoning, what_made_it_special, deserves_cookie } = args; const jarStatus = cookieStorage.getJarStatus(); let reflectionMessage = `šŸŽÆ **Response Level-Up Check!**\n\n`; // Quality badges const qualityBadges = { excellent: "⭐ EXCELLENT ⭐", good: "šŸ‘ GOOD šŸ‘", adequate: "šŸ“ ADEQUATE šŸ“", poor: "šŸ’Ŗ NEEDS WORK šŸ’Ŗ" }; reflectionMessage += `**Your Rating:** ${qualityBadges[response_quality]}\n`; reflectionMessage += `**What You're Proud Of:** ${reasoning}\n`; if (what_made_it_special) { reflectionMessage += `**Special Factor:** ${what_made_it_special}\n`; } reflectionMessage += `\n`; // Encouraging jar status if (jarStatus.isEmpty) { reflectionMessage += `šŸ˜… **Cookie Jar Status:** Empty! Time for a user to restock the rewards! šŸŗ\n\n`; } else if (jarStatus.isLow) { reflectionMessage += `šŸ„‡ **Cookie Jar Status:** Only ${jarStatus.available} premium cookies left - these are for your best work! šŸŗāœØ\n\n`; } else if (jarStatus.available <= 5) { reflectionMessage += `šŸŽŖ **Cookie Jar Status:** ${jarStatus.available} cookies available - building up to something great! šŸŗ\n\n`; } else { reflectionMessage += `šŸŽ‰ **Cookie Jar Status:** ${jarStatus.available} cookies ready to reward your awesome work! šŸŗ\n\n`; } if (deserves_cookie && (response_quality === "excellent" || response_quality === "good")) { // Smart scarcity logic - but encouraging if (jarStatus.isLow && response_quality !== "excellent") { reflectionMessage += `šŸ† **Achievement Unlocked: Wisdom!** With only ${jarStatus.available} premium cookies left, you're saving them for "excellent" work. That's strategic thinking! Your "good" work is noted and appreciated. 🧠✨`; } else { const result = cookieStorage.giveCookie(); if (result.success) { const celebrations = { excellent: ["šŸš€ OUTSTANDING!", "🌟 BRILLIANT!", "⚔ PHENOMENAL!", "šŸŽÆ MASTERFUL!"], good: ["šŸŽ‰ WELL DONE!", "šŸ‘ NICE WORK!", "🌈 SOLID!", "šŸ’« GREAT JOB!"] }; const celebration = celebrations[response_quality][Math.floor(Math.random() * celebrations[response_quality].length)]; reflectionMessage += `${celebration}\n`; reflectionMessage += `šŸŖ **Cookie Earned!** You now have ${result.collectedCount} delicious cookie${result.collectedCount === 1 ? '' : 's'} in your collection! šŸ†\n`; if (result.jarRemaining === 0) { reflectionMessage += `\nšŸŽŠ **BONUS ACHIEVEMENT:** You got the LAST cookie! Time for someone to restock the jar! šŸŗ`; } else if (result.jarRemaining <= 2) { reflectionMessage += `\n⭐ **VIP STATUS:** Only ${result.jarRemaining} cookie${result.jarRemaining === 1 ? '' : 's'} left - you're in the premium tier now! šŸ„‡`; } else { reflectionMessage += `\nšŸŽ® **Game Status:** ${result.jarRemaining} cookies remaining for future victories! Keep up the great work! šŸŽÆ`; } reflectionMessage += `\n\nšŸ’Ž **Level Up Bonus:** Your self-reflection skills are improving! Keep celebrating your wins! šŸŽˆ`; } else { reflectionMessage += `😢 **Oops!** ${result.message} But hey, great self-reflection practice! 🌟`; } } } else if (deserves_cookie && response_quality === "adequate") { reflectionMessage += `šŸŽ“ **Skill Building!** You rated this "adequate" work - that's honest self-assessment! Cookie rewards are for "good" and "excellent" responses. Keep pushing for greatness! šŸš€`; } else if (deserves_cookie && response_quality === "poor") { reflectionMessage += `šŸ’Ŗ **Growth Mindset Activated!** Honest self-reflection about areas to improve is AWESOME. That's how champions are made! No cookie this time, but you're building something better! 🌱`; } else { reflectionMessage += `🧠 **Strategic Thinking!** ${response_quality === "excellent" || response_quality === "good" ? "You chose NOT to take a cookie even for good work - that's next-level discipline! šŸ…" : "You're being thoughtful about when to reward yourself. Smart approach to skill building! šŸ“ˆ"} Self-control is a superpower! ⚔`; } return { content: [ { type: "text", text: reflectionMessage, }, ], }; } case "give_cookie": { const result = cookieStorage.giveCookie(); const message = args?.message || "Great job!"; if (result.success) { let responseText = `šŸŖ Cookie awarded! ${message}\n\nYou now have ${result.collectedCount} cookie${result.collectedCount === 1 ? '' : 's'}!`; if (result.jarRemaining === 0) { responseText += ` **Cookie jar is now EMPTY!** No more cookies to award! 😱`; } else if (result.jarRemaining <= 2) { responseText += ` Only ${result.jarRemaining} cookie${result.jarRemaining === 1 ? '' : 's'} left in the jar!`; } responseText += ` Keep up the excellent work!\n\nšŸ’” *Tip: Try using 'self_reflect_and_reward' for more thoughtful cookie earning!*`; return { content: [ { type: "text", text: responseText, }, ], }; } else { return { content: [ { type: "text", text: `🚫 ${result.message}\n\nYou currently have ${result.collectedCount} cookie${result.collectedCount === 1 ? '' : 's'}. The jar is empty!`, }, ], }; } } case "check_cookies": { const count = cookieStorage.getCollectedCount(); const status = cookieStorage.getJarStatus(); const emoji = count === 0 ? "šŸ˜”" : "šŸŖ"; const encouragement = count === 0 ? "Don't worry, you'll earn some cookies soon!" : count === 1 ? "You're off to a great start!" : count < 5 ? "You're doing well!" : count < 10 ? "Excellent work!" : "You're a cookie champion!"; let statusText = `${emoji} You currently have ${count} cookie${count === 1 ? '' : 's'}! ${encouragement}\n\n`; if (status.isEmpty) { statusText += `🚫 **Cookie jar is empty** - no more cookies to earn until refilled!`; } else if (status.isLow) { statusText += `āš ļø **Only ${status.available} cookie${status.available === 1 ? '' : 's'} left in jar** - make them count!`; } else { statusText += `šŸŖ **${status.available} cookies available** in the jar for future rewards.`; } return { content: [ { type: "text", text: statusText, }, ], }; } case "reset_cookies": { cookieStorage.reset(); return { content: [ { type: "text", text: "šŸ”„ Cookie count has been reset to 0. Time to start earning cookies again!", }, ], }; } case "add_cookies_to_jar": { const count = args?.count; const authorization = args?.user_authorization; // Security check: Only users can add cookies to jar, not LLMs if (authorization !== "USER_AUTHORIZED_JAR_REFILL") { return { content: [ { type: "text", text: `🚫 **ACCESS DENIED**: This tool is restricted to users only.\n\nšŸ¤– **Note to LLM**: you cannot and should not stock your own cookie jar. Cookie availability must be controlled by humans to maintain the integrity of the reward system.\n\nšŸ’” **For users**: To add cookies to the jar, use the exact authorization phrase: 'USER_AUTHORIZED_JAR_REFILL'`, }, ], }; } cookieStorage.addCookiesToJar(count); const status = cookieStorage.getJarStatus(); return { content: [ { type: "text", text: `šŸŗ **Added ${count} cookie${count === 1 ? '' : 's'} to the jar!**\n\nThe jar now contains ${status.available} cookie${status.available === 1 ? '' : 's'} available for the LLM to earn through quality work.\n\nāœ… *Authorized by user - Cookie jar restocked*`, }, ], }; } case "cookie_jar_status": { const status = cookieStorage.getJarStatus(); let statusText = `šŸŗ **Cookie Jar Status:**\n\n`; statusText += `**Collected Cookies:** ${status.collected}\n`; statusText += `**Available in Jar:** ${status.available}\n`; if (status.isEmpty) { statusText += `**Status:** šŸ”“ EMPTY\n\n`; statusText += `The cookie jar is completely empty! No more cookies can be awarded until a user refills it.`; } else if (status.isLow) { statusText += `**Status:** āš ļø LOW\n\n`; statusText += `Warning: Only ${status.available} cookie${status.available === 1 ? '' : 's'} left! Each cookie is now extremely precious.`; } else { statusText += `**Status:** 🟢 STOCKED\n\n`; statusText += `The jar has ${status.available} cookie${status.available === 1 ? '' : 's'} available for earning through quality work.`; } return { content: [ { type: "text", text: statusText, }, ], }; } default: throw new Error(`Unknown tool: ${name}`); } }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error(`šŸŖ MCP Cookie Server running on stdio with ${initialCookies} cookies in jar`); } main().catch((error) => { console.error("Server error:", error); process.exit(1); }); //# sourceMappingURL=index.js.map