Skip to main content
Glama

MCP Resume Chat Server

by TharakaJayz
resumeChatService.js•7.03 kB
const OpenAI = require("openai"); // Configuration const mcpConfig = { openai: { apiKey: process.env.OPENAI_API_KEY || "", model: "gpt-3.5-turbo", maxTokens: 1000, temperature: 0.7, }, }; class ResumeChatService { constructor(resumeParser) { this.openai = new OpenAI({ apiKey: mcpConfig.openai.apiKey, }); this.resumeParser = resumeParser; } /** * Answer questions about the resume */ async answerQuestion(query) { try { const resumeData = this.resumeParser.getResumeData(); if (!resumeData) { throw new Error("Resume data not loaded"); } const context = this.createContext(resumeData); const prompt = this.createPrompt(query.question, context); const completion = await this.openai.chat.completions.create({ model: mcpConfig.openai.model, messages: [ { role: "system", content: "You are a helpful assistant that answers questions about a person's resume/CV. Provide accurate, detailed, and professional responses based on the resume information provided.", }, { role: "user", content: prompt, }, ], max_tokens: mcpConfig.openai.maxTokens, temperature: mcpConfig.openai.temperature, }); const answer = completion.choices[0]?.message?.content || "I could not generate a response."; const confidence = this.calculateConfidence(query.question, resumeData); const sources = this.identifySources(query.question, resumeData); return { answer, confidence, sources, }; } catch (error) { console.error("Error answering resume question:", error); return { answer: "I encountered an error while processing your question. Please try again.", confidence: 0, sources: [], }; } } /** * Create context from resume data */ createContext(resumeData) { const sections = [ `Personal Information: ${resumeData.personalInfo.name}, ${ resumeData.personalInfo.email }, ${resumeData.personalInfo.location || "Location not specified"}`, `Summary: ${resumeData.summary}`, `Work Experience: ${resumeData.experience .map( (exp) => `${exp.position} at ${exp.company} (${exp.startDate} - ${ exp.endDate || "Present" }): ${exp.description}. Achievements: ${exp.achievements.join( ", " )}. Technologies: ${exp.technologies.join(", ")}` ) .join("; ")}`, `Education: ${resumeData.education .map( (edu) => `${edu.degree} in ${edu.field} from ${edu.institution} (${ edu.startDate } - ${edu.endDate || "Present"})` ) .join("; ")}`, `Skills: ${resumeData.skills.join(", ")}`, ]; if (resumeData.projects) { sections.push( `Projects: ${resumeData.projects .map( (proj) => `${proj.name}: ${ proj.description }. Technologies: ${proj.technologies.join(", ")}` ) .join("; ")}` ); } if (resumeData.certifications) { sections.push( `Certifications: ${resumeData.certifications .map((cert) => `${cert.name} from ${cert.issuer} (${cert.date})`) .join("; ")}` ); } return sections.join("\n\n"); } /** * Create prompt for OpenAI */ createPrompt(question, context) { return ` Based on the following resume information, please answer the question: "${question}" Resume Information: ${context} Please provide a detailed and accurate answer based on the information provided. If the question cannot be answered from the resume data, please say so clearly. `.trim(); } /** * Calculate confidence score for the response */ calculateConfidence(question, resumeData) { const questionLower = question.toLowerCase(); let confidence = 0.5; if ( questionLower.includes("work") || questionLower.includes("job") || questionLower.includes("position") || questionLower.includes("company") ) { confidence += 0.2; } if ( questionLower.includes("skill") || questionLower.includes("technology") || questionLower.includes("programming") ) { confidence += 0.2; } if ( questionLower.includes("education") || questionLower.includes("degree") || questionLower.includes("university") || questionLower.includes("college") ) { confidence += 0.2; } if (questionLower.includes("name") && resumeData.personalInfo.name) { confidence += 0.1; } if (questionLower.includes("email") && resumeData.personalInfo.email) { confidence += 0.1; } if ( questionLower.includes("location") && resumeData.personalInfo.location ) { confidence += 0.1; } return Math.min(confidence, 1.0); } /** * Identify sources used in the response */ identifySources(question, resumeData) { const sources = []; const questionLower = question.toLowerCase(); if ( questionLower.includes("work") || questionLower.includes("job") || questionLower.includes("position") ) { sources.push("Work Experience"); } if ( questionLower.includes("skill") || questionLower.includes("technology") ) { sources.push("Skills"); } if ( questionLower.includes("education") || questionLower.includes("degree") ) { sources.push("Education"); } if (questionLower.includes("project")) { sources.push("Projects"); } if ( questionLower.includes("certification") || questionLower.includes("certificate") ) { sources.push("Certifications"); } if ( questionLower.includes("name") || questionLower.includes("email") || questionLower.includes("contact") ) { sources.push("Personal Information"); } if (questionLower.includes("summary") || questionLower.includes("about")) { sources.push("Summary"); } return sources.length > 0 ? sources : ["General Resume Information"]; } /** * Get suggested questions based on resume content */ getSuggestedQuestions() { const resumeData = this.resumeParser.getResumeData(); if (!resumeData) { return []; } return [ "What is my current position?", "What companies have I worked for?", "What are my main skills?", "What is my educational background?", "What projects have I worked on?", "What certifications do I have?", "What was my last role?", "What technologies do I use?", "What is my experience level?", "What are my key achievements?", ]; } } module.exports = { ResumeChatService };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TharakaJayz/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server