anupamatrey/job-recommendations-mcp-server
If you are the rightful owner of job-recommendations-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
This document provides a comprehensive overview of an MCP server designed for AI-powered resume-to-job matching, leveraging AI embeddings and the JSearch API.
MCP Server POC - AI-Powered Resume-to-Job Matching
A Spring Boot-based Model Context Protocol (MCP) server that provides intelligent resume analysis and job matching capabilities using AI embeddings and the JSearch API.
🎯 Overview
This MCP server enables AI assistants (like Claude Desktop, Cline) to:
- Upload and analyze resumes - Extract structured information using LLM
- Store resume embeddings - Vector-based storage for semantic search
- Match resumes to jobs - Find relevant job postings using JSearch API (RapidAPI)
- Rank job matches - Score jobs based on semantic similarity and filters
🏗️ Architecture
┌─────────────────────┐
│ Claude Desktop / │
│ Cline (MCP Client) │
└──────────┬──────────┘
│ SSE/STDIO
▼
┌─────────────────────┐
│ MCP Server │
│ (Spring Boot) │
├─────────────────────┤
│ • ResumeTools │
│ • MatchingTools │
│ • CourseService │
└──────────┬──────────┘
│
┌──────┴──────┐
▼ ▼
┌─────────┐ ┌──────────┐
│ Vector │ │ JSearch │
│ Store │ │ API │
│(In-Mem) │ │(RapidAPI)│
└─────────┘ └──────────┘
📦 Components
MCP Tools
- upload_resume - Process resume text and generate structured summary
- get_resume_summary - Retrieve stored resume summary by ID
- match_resume_to_jobs - Find and rank matching jobs from JSearch API
- getAllCourse - Demo tool to list available courses
- getCourseById - Demo tool to get course by title
- print_env - Diagnostic tool to print environment variables
- llm_diagnostics - Diagnostic tool for LLM configuration and health check
Services
- ResumeService - Resume processing and LLM-based extraction
- VectorStoreService - In-memory vector storage with cosine similarity
- EmbeddingService - Text-to-vector embedding (stub implementation)
- JSearchService - Integration with JSearch API for job listings
- LlmClient - LLM interface for chat completions
🚀 Getting Started
Prerequisites
- Java 21+
- Gradle 8.14.3+
- RapidAPI account with JSearch API access
- Claude Desktop or Cline (VS Code extension)
Step 1: Clone and Setup
git clone <repository-url>
cd job-recommendations-mcp-server
Step 2: Configure API Keys
- Copy the example environment file:
copy .env.example .env
- Edit
.envand add your RapidAPI key:
JSEARCH_API_KEY=your_actual_rapidapi_key_here
JSEARCH_API_HOST=jsearch.p.rapidapi.com
Get your API key from: https://rapidapi.com/letscrape-6bRBa3QguO5/api/jsearch
Step 3: Build the Project
# Windows
gradlew.bat clean bootJar
# Unix/Linux/Mac
./gradlew clean bootJar
The JAR will be created at: build/libs/job-recommendations-mcp-server-0.0.1.jar
Step 4: Choose Transport Mode
Option A: STDIO (Local Development)
Configuration:
- Comment out SSE config in
application.properties - Uncomment:
spring.main.web-application-type=none
Claude Desktop Config (claude_desktop_config.json):
{
"mcpServers": {
"resume-matcher": {
"command": "java",
"args": [
"-jar",
"C:\\Workspace\\mcp\\job-recommendations-mcp-server\\build\\libs\\job-recommendations-mcp-server-0.0.1.jar"
]
}
}
}
Option B: SSE (Production Ready)
Configuration:
- Keep current
application.properties(SSE enabled) - Server runs on
http://localhost:8080
Run the server:
java -jar build/libs/job-recommendations-mcp-server-0.0.1.jar
Claude Desktop Config:
{
"mcpServers": {
"resume-matcher": {
"url": "http://localhost:8080/sse"
}
}
}
For Cline (VS Code): Add to VS Code settings.json:
{
"cline.mcpServers": {
"resume-matcher": {
"url": "http://localhost:8080/sse"
}
}
}
Step 5: Restart MCP Client
- Claude Desktop: Restart the application
- Cline: Reload VS Code window
💡 Usage Examples
Example 1: Upload Resume
In Claude Desktop or Cline:
Upload my resume:
John Doe
Senior Software Engineer
5 years experience in Java, Spring Boot, AWS
Skills: Microservices, Docker, Kubernetes
Location: San Francisco, CA
Response:
{
"resumeId": "abc-123-def",
"name": "John Doe",
"title": "Senior Software Engineer",
"years_experience": 5,
"skills": ["Java", "Spring Boot", "AWS", "Docker", "Kubernetes"],
"summary_text": "...",
"status": "processed"
}
Example 2: Match Jobs
Find jobs matching resume abc-123-def in San Francisco
The server will:
- Fetch resume summary from vector store
- Query JSearch API for relevant jobs
- Compute embeddings for jobs
- Rank jobs by semantic similarity
- Return top matches with scores
🔧 Configuration
Application Properties
| Property | Description | Default |
|---|---|---|
spring.ai.mcp.server.transport | Transport mode (sse/stdio) | sse |
server.port | HTTP server port (SSE mode) | 8080 |
jsearch.api.key | RapidAPI JSearch key | From .env |
jsearch.api.host | JSearch API host | jsearch.p.rapidapi.com |
Environment Variables
Create .env file (never commit this):
JSEARCH_API_KEY=your_key_here
JSEARCH_API_HOST=jsearch.p.rapidapi.com
🏭 Production Deployment
Deploy to AWS
Option 1: ECS Fargate
# Build Docker image
docker build -t mcp-server .
# Push to ECR
aws ecr get-login-password | docker login --username AWS --password-stdin <ecr-url>
docker tag mcp-server:latest <ecr-url>/mcp-server:latest
docker push <ecr-url>/mcp-server:latest
# Deploy to ECS (use Fargate)
Option 2: Elastic Beanstalk
# Package JAR
gradlew.bat bootJar
# Deploy via EB CLI
eb init
eb create mcp-server-env
eb deploy
Client Configuration (Production):
{
"mcpServers": {
"resume-matcher": {
"url": "https://mcp.yourcompany.com/sse",
"headers": {
"Authorization": "Bearer <api-token>"
}
}
}
}
🧪 Testing
Manual Testing with MCP Inspector
# Install MCP Inspector
npm install -g @modelcontextprotocol/inspector
# Test your server
mcp-inspector http://localhost:8080/sse
Unit Tests
gradlew.bat test
📁 Project Structure
job-recommendations-mcp-server/
├── src/main/java/com/anupam/
│ ├── job/recommendations/mcp/server/
│ │ ├── Course.java
│ │ ├── CourseService.java
│ │ └── JobRecommendationsMcpServerApplication.java
│ └── mcp/
│ ├── ai/ # LLM client interfaces
│ │ ├── chat/
│ │ ├── LlmClient.java
│ │ └── OpenAILlmClient.java
│ ├── service/ # Business logic services
│ │ ├── ResumeService.java
│ │ ├── VectorStoreService.java
│ │ ├── EmbeddingService.java
│ │ └── JSearchService.java
│ ├── tools/ # MCP-exposed tools
│ │ ├── ResumeTools.java
│ │ ├── MatchingTools.java
│ │ ├── LlmDiagnostics.java
│ │ ├── EnvPrinter.java
│ │ └── JobDto.java
│ └── util/ # Utilities
│ └── JsonUtils.java
├── src/main/resources/
│ └── application.properties
├── .env # API keys (gitignored)
├── .env.example # Template for .env
├── build.gradle
└── README.md
🔐 Security Notes
- Never commit
.env- Contains sensitive API keys - Use environment variables - For all secrets in production
- Add authentication - Implement API tokens for production SSE endpoints
- HTTPS only - Use TLS for production deployments
🛠️ Troubleshooting
Issue: "ClassNotFoundException: StandardServletEnvironment"
Solution: Ensure spring-boot-starter-web is in dependencies
Issue: "JSearch API returns 401"
Solution: Verify your RapidAPI key in .env file
Issue: "Server disconnected in Claude Desktop"
Solution:
- Check if Spring Boot banner is disabled (
spring.main.banner-mode=off) - Ensure no logs are written to stdout (only JSON-RPC messages)
Issue: "Cannot find .env file"
Solution: Create .env from .env.example in project root
📚 Resources
- Model Context Protocol Docs
- Spring AI MCP Server
- JSearch API Documentation
- Claude Desktop
- Cline VS Code Extension
🤝 Contributing
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
📝 License
This project is licensed under the MIT License.
👥 Authors
- Anupam - Initial work
🙏 Acknowledgments
- Spring AI team for MCP server support
- Anthropic for Claude and MCP protocol
- RapidAPI for JSearch API access