mcp-me
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-meList your projects using Python"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-me: Personal MCP Server
An MCP (Model Context Protocol) server that turns professional data into tools an LLM can consume. Instead of a recruiter reading a static CV PDF, they (or an agent) ask questions and get real, structured data back.
Status: Production | Version: 1.0.0 | Runtime: Node.js + TypeScript
Overview
mcp-me exposes 4 MCP tools that query:
Bilingual CVs (EN / PT-BR) in Markdown as the source of truth
Expanded project data (repository, demo, technical highlights, status)
Job ↔ profile fit analysis with skill matching
Keyword search across the entire professional history
It suits:
Recruiting agents that analyze job postings automatically
LLMs that need structured biographical data
Personal assistants that answer questions about experience
Automating candidate-job compatibility analyses
Related MCP server: Resume MCP Server
Characteristics
Full support for English and Brazilian Portuguese
Only 2 dependencies (MCP SDK + Zod)
Strict TypeScript with Zod validation
Efficient in-memory loading
Markdown parsed by hand
match_jobreports real gaps instead of inflating the profileStructured natural text, not raw JSON
MCP Tools
1. get_cv
Returns the complete CV or a specific section.
Input:
{
"lang": "en" | "pt-br", // optional, default: "en"
"section": "summary" | "skills" | "experience" | "projects" | "education" | "certifications" | "languages" // optional
}Output: Formatted Markdown text with the CV or the requested section.
Usage examples:
get_cv({ lang: "pt-br" })
→ Returns the full CV in Portuguese
get_cv({ lang: "en", section: "skills" })
→ Returns only the technical skills section, in English
get_cv({ section: "professional experience" })
→ Partial match: returns the experience section2. list_projects
Lists projects with full metadata: description, stack, highlights, repository URL, demo URL, and status.
Input:
{
"tech": "Next.js" | "Python" | "React" | ... // optional, case-insensitive, partial match
}Output: A formatted list of projects with structured fields.
Status: "completed" | "in-progress" | "active" | "experimental"
Category: "cv" (featured on the CV) | "additional" (extras on GitHub)
Usage examples:
list_projects()
→ Lists all 8+ projects
list_projects({ tech: "next" })
→ Filters projects using Next.js, returns 2-3 results
list_projects({ tech: "python" })
→ Filters projects using Python, returns the AI/data projects3. match_job
Analyzes the fit between the profile and a job description. It returns:
Fit Score (0-100): the percentage of the job description's technical skills present in the CV
Matching Skills: skills present on both sides
Gaps: required skills that are not in the CV
Relevant Experience: excerpts of professional experience aligned with the role
Suggested Pitch: an honest assessment calibrated to the score
Input:
{
"description": "Fullstack Engineer needed for Next.js/React + Python FastAPI microservices..."
}Output: A structured analysis with the score, matching skills, gaps, and pitch.
Score interpretation:
70-100: Strong fit — the candidate is clearly aligned with the role
40-69: Partial fit — there is overlap, but significant gaps
0-39: Low fit — this would be a career pivot, not a natural next step
Examples:
match_job({ description: "React + TypeScript + Node.js backend engineer needed..." })
→ Score: 92, Matching Skills: React, TypeScript, Node.js, ...
→ Gaps: (none), Suggested Pitch: Strong fit...
match_job({ description: "Lead Golang architect, 10 years Go experience required..." })
→ Score: 15, Matching Skills: (none), Gaps: Go, Kubernetes orchestration, ...
→ Suggested Pitch: Limited overlap, significant career pivot...4. ask_about_me
Runs a keyword search across the whole profile (CV + projects) and returns the 10 most relevant excerpts, grouped by section.
Input:
{
"question": "ETL experience?" | "databases usados?" | "tem experiência com IA?" | ...
}Output: Experience excerpts grouped by section (Professional Experience, Projects, and so on)
Supports:
Keywords in English and Portuguese
Searching by technology, role, or concept
Stop-word filtering to reduce noise
Examples:
ask_about_me({ question: "ETL experience" })
→ Returns experience with data pipelines, Airflow, and so on
ask_about_me({ question: "tem experiência com IA?" })
→ Returns projects and experience with LLMs, CrewAI, and so on
ask_about_me({ question: "Docker Kubernetes" })
→ Returns sections on DevOps, containerization, and orchestrationStack
Component | Technology |
Runtime | Node.js 22+ (ES Modules) |
Language | TypeScript 5.7 |
Protocol | MCP SDK |
Validation | Zod |
Build | tsup 8.0 |
Linting | Biome 1.9 |
Transport | stdio (standard stdin/stdout communication) |
Installation
Prerequisites
Node.js 22+ (check with
node --version)npm 10+ (or yarn/pnpm)
Steps
# 1. Clone the repository
git clone https://github.com/fe-m-bueno/mcp-me.git
cd mcp-me
# 2. Install the dependencies
npm install
# 3. Build
npm run build
# 4. Verify the build
ls dist/
# You should see: index.js, index.d.ts (sourcemaps), data/ (CVs + projects)Post-Build Structure
dist/
├── index.js # Compiled entry point
├── index.js.map # Sourcemap
├── index.d.ts # TypeScript types
└── data/
├── cv-en.md # CV in English
├── cv-ptbr.md # CV in Portuguese
└── projects.json # Project dataUsage
As an MCP Server (in a client)
Configure it in your MCP client (Claude Desktop, Cline, and so on):
macOS/Linux — ~/.config/Claude/claude_desktop_config.json:
{
"mcpServers": {
"me": {
"command": "node",
"args": ["/home/felipebueno/Development/mcp-me/dist/index.js"]
}
}
}Windows — %APPDATA%/Claude/claude_desktop_config.json:
{
"mcpServers": {
"me": {
"command": "node",
"args": ["C:/Users/felipebueno/Development/mcp-me/dist/index.js"]
}
}
}After configuring it, restart the MCP client. The 4 tools will show up as available.
Local Testing with MCP Inspector
npm run inspectThis opens a web interface at http://localhost:3000 for testing the tools interactively.
Testing with Node.js Directly
# Terminal 1: start the server
node dist/index.js
# Terminal 2: connect via stdio
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node dist/index.jsDevelopment
Code Structure
src/
├── index.ts # Entry point, stdio transport
├── server.ts # Definition of the 4 tools with descriptions
├── tools/
│ ├── cv.ts # get_cv handler
│ ├── projects.ts # list_projects handler
│ ├── match.ts # match_job handler
│ └── ask.ts # ask_about_me handler
├── lib/
│ ├── parser.ts # Parses Markdown into sections
│ ├── matcher.ts # Job ↔ profile matching logic
│ ├── projects.ts # Loads projects.json
│ ├── response.ts # Response utilities (ToolResponse)
│ └── paths.ts # Resolves data/ paths
└── data/
├── cv-en.md # CV in English
├── cv-ptbr.md # CV in Portuguese
└── projects.json # Project data with metadataDevelopment Workflow
# 1. Develop with watch
npm run dev
# 2. Lint as you go
npm run lint
npm run lint:fix
# 3. Final build
npm run build
# 4. Test with the Inspector
npm run inspectAdding a New Tool
Create
src/tools/new-tool.tswith an async handlerRegister it in
server.tswithserver.registerTool()Export it from
index.ts(this happens automatically)Rebuild and test via
npm run inspect
Example:
// src/tools/new-tool.ts
import { loadCv } from "../lib/parser.js";
import { ToolResponse, textResult } from "../lib/response.js";
export async function newToolHandler(args: {
query: string;
}): Promise<ToolResponse> {
const cv = loadCv("en");
// your logic here
return textResult("resultado");
}Updating the Data
CVs: Copy them from ~/Development/cv/ to src/data/cv-*.md
cp ~/Development/cv/cv-en.md src/data/
cp ~/Development/cv/cv-ptbr.md src/data/
npm run buildProjects: Edit src/data/projects.json directly
vim src/data/projects.json
npm run buildConfiguration
Environment Variables
None needed at the moment. All data is static, in src/data/.
Data Directory
The server looks for data in src/data/ at build time (resolved via lib/paths.ts). At runtime, the files live in dist/data/.
TypeScript/Zod
tsconfig.json:
Target: ES2022
Module: Node16 (ESM)
Strict mode enabled
JSON resolution enabled
biome.json:
Formatter: tabs (indentation)
Linter: recommended rules
Organize imports: enabled
Performance and Optimizations
In-Memory Cache
CVs and projects are loaded once at startup and kept in a cache:
const cvCache = new Map<string, CvData>();
export function loadCv(lang: "en" | "pt-br"): CvData {
const cached = cvCache.get(lang);
if (cached) return cached;
// load from disk, then cache
}Efficient Matching
Pre-compiled regexes for tech keywords (
TECH_PATTERNS)Skill normalization with simple rules (lowercase, strip . - /)
Stop-word filtering in
ask_about_me
Minimal Size
No extra dependencies (just the MCP SDK + Zod)
Manual parsing, no libraries
Bundle: ~200KB minified
Troubleshooting
"Data file not found"
Make sure you ran npm run build. The build copies src/data/ to dist/data/.
npm run build
ls dist/data/A Tool Returns an Undefined Error
Check that the absolute path in claude_desktop_config.json is correct:
ls /home/felipebueno/Development/mcp-me/dist/index.js
# It must existMCP Inspector Won't Open
Port 3000 may be in use. Change the port or kill the process:
lsof -i :3000
kill -9 <PID>
npm run inspectLinting Failing
npm run lint:fixBiome fixes formatting and import problems automatically.
Contributing
This is a personal project, but if you want to suggest improvements:
Fork it
Create a branch for your feature (
git checkout -b feature/my-feature)Commit your changes (
git commit -m "Add X")Push to the branch (
git push origin feature/my-feature)Open a Pull Request
Contact
Felipe Bueno GitHub: @fe-m-bueno Email: felipebueno.dev@gmail.com
This server cannot be deployed
Maintenance
Related MCP Connectors
Generate tailored, ATS-optimized resume PDFs and cover letters from a job description, over MCP.
CareerProof MCP gives AI agents direct access to a professional-grade career and workforce intelligence platform. Two namespaces: atlas_* for HR/TA teams (candidate evaluation, batch shortlisting, competency scoring, interview generation, JD analysis, custom eval frameworks, research reports) and ceevee_* for professionals (CV optimization, career positioning, salary intelligence, market reports). Backed by RAG knowledge from 50+ premium research sources (McKinsey, BCG, HBR, Gartner, WEF)
Job search and interview prep MCP. 11 tools, OAuth 2.1, cross-LLM. four-leaf.ai.
Build, version and render resumes as PDFs from Claude or any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceExposes a person's structured professional profile as MCP tools, enabling Claude and other MCP clients to answer questions about that person based on real data.5 npm1MIT
- AlicenseNot gradedqualityCmaintenanceExposes a structured professional resume as a set of AI-queryable tools, enabling AI clients like Claude Desktop to query summary, experience, skills, projects, and tailor resumes to job descriptions.1MIT
- FlicenseAqualityBmaintenanceMCP server that exposes a resume as callable tools and resources, enabling AI agents to query experience, skills, projects, and contact information via natural language.3-
- AlicenseAqualityBmaintenanceExposes a personal portfolio of projects, skills, and resume as callable tools for MCP-compatible AI assistants like Claude Desktop.4MIT