- Explore MCP Servers
- node-candidate-mcp-server
Node Candidate Mcp Server
What is Node Candidate Mcp Server
node-candidate-mcp-server is a Model Context Protocol (MCP) server designed to provide large language models (LLMs) with access to candidate information, such as resumes and social media profiles.
Use cases
Use cases include automating the retrieval of candidate information during the hiring process, integrating candidate profiles into applicant tracking systems, and enabling communication with candidates through email.
How to use
To use node-candidate-mcp-server, install it via npm with the command ‘npm install @jhgaylor/candidate-mcp-server’. It is intended to be integrated into your applications, and you can start the server using the provided configuration methods.
Key features
Key features include access to various candidate information resources, such as resume text, URLs to resumes, LinkedIn and GitHub profiles, and personal websites. It also offers tools to retrieve this information programmatically.
Where to use
node-candidate-mcp-server can be used in recruitment applications, HR management systems, and any software that requires handling candidate information for job applications or evaluations.
Clients Supporting MCP
The following are the main client software that supports the Model Context Protocol. Click the link to visit the official website for more information.
Overview
What is Node Candidate Mcp Server
node-candidate-mcp-server is a Model Context Protocol (MCP) server designed to provide large language models (LLMs) with access to candidate information, such as resumes and social media profiles.
Use cases
Use cases include automating the retrieval of candidate information during the hiring process, integrating candidate profiles into applicant tracking systems, and enabling communication with candidates through email.
How to use
To use node-candidate-mcp-server, install it via npm with the command ‘npm install @jhgaylor/candidate-mcp-server’. It is intended to be integrated into your applications, and you can start the server using the provided configuration methods.
Key features
Key features include access to various candidate information resources, such as resume text, URLs to resumes, LinkedIn and GitHub profiles, and personal websites. It also offers tools to retrieve this information programmatically.
Where to use
node-candidate-mcp-server can be used in recruitment applications, HR management systems, and any software that requires handling candidate information for job applications or evaluations.
Clients Supporting MCP
The following are the main client software that supports the Model Context Protocol. Click the link to visit the official website for more information.
Content
Candidate MCP Server Library
A Model Context Protocol (MCP) server that gives LLMs access to information about a candidate.
Overview
Important: This server is intended to be used as a library to be integrated into other applications, not as a standalone service. The provided startup methods are for demonstration and testing purposes only.
Resources
This MCP server provides the following resources:
candidate-info://resume-text
: Resume content as textcandidate-info://resume-url
: URL to the resumecandidate-info://linkedin-url
: LinkedIn profile URLcandidate-info://github-url
: GitHub profile URLcandidate-info://website-url
: Personal website URLcandidate-info://website-text
: Content from the personal website
Tools
This MCP server also provides tools that return the same candidate information:
get_resume_text
: Returns the candidate’s resume content as textget_resume_url
: Returns the URL to the candidate’s resumeget_linkedin_url
: Returns the candidate’s LinkedIn profile URLget_github_url
: Returns the candidate’s GitHub profile URLget_website_url
: Returns the candidate’s personal website URLget_website_text
: Returns the content from the candidate’s personal websitecontact_candidate
: Sends an email to the candidate (requires Mailgun configuration)
Usage
npm install @jhgaylor/candidate-mcp-server
Library Usage
This package is designed to be imported and used within your own applications.
Stdio
Starting the process is a breeze with stdio. The interesting part is providing the candidate configuration.
Where you source the candidate configuration is entirely up to you. Maybe you hard code it. Maybe you take a JSONResume url when you start the process. It’s up to you!
import { createServer } from '@jhgaylor/candidate-mcp-server';
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// Configure your server
const serverConfig = {
name: "MyCandidateServer",
version: "1.0.0",
mailgunApiKey: process.env.MAILGUN_API_KEY,
mailgunDomain: process.env.MAILGUN_DOMAIN
};
const candidateConfig = {
name: "John Doe",
email: "[email protected]", // Required for the contact_candidate tool
resumeUrl: "https://example.com/resume.pdf",
// other candidate properties
};
// Create server instance
const server = createServer(serverConfig, candidateConfig);
// Connect with your preferred transport
await server.connect(new StdioServerTransport());
// or integrate with your existing HTTP server
StreamableHttp
Using the example code provided by the typescript sdk we can bind this mcp server to an express server.
import express from 'express';
import { Request, Response } from 'express';
import { createServer } from '@jhgaylor/candidate-mcp-server';
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamablehttp.js";
// Configure your server
const serverConfig = {
name: "MyCandidateServer",
version: "1.0.0",
mailgunApiKey: process.env.MAILGUN_API_KEY,
mailgunDomain: process.env.MAILGUN_DOMAIN,
contactEmail: "[email protected]",
};
const candidateConfig = {
name: "John Doe",
resumeUrl: "https://example.com/resume.pdf",
// other candidate properties
};
// Factory function to create a new server instance for each request
const getServer = () => createServer(serverConfig, candidateConfig);
const app = express();
app.use(express.json());
app.post('/mcp', async (req: Request, res: Response) => {
// In stateless mode, create a new instance of transport and server for each request
// to ensure complete isolation. A single instance would cause request ID collisions
// when multiple clients connect concurrently.
try {
const server = getServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
res.on('close', () => {
console.log('Request closed');
transport.close();
server.close();
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
} catch (error) {
console.error('Error handling MCP request:', error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: 'Internal server error',
},
id: null,
});
}
}
});
app.get('/mcp', async (req: Request, res: Response) => {
console.log('Received GET MCP request');
res.writeHead(405).end(JSON.stringify({
jsonrpc: "2.0",
error: {
code: -32000,
message: "Method not allowed."
},
id: null
}));
});
app.delete('/mcp', async (req: Request, res: Response) => {
console.log('Received DELETE MCP request');
res.writeHead(405).end(JSON.stringify({
jsonrpc: "2.0",
error: {
code: -32000,
message: "Method not allowed."
},
id: null
}));
});
// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`MCP Stateless Streamable HTTP Server listening on port ${PORT}`);
});
Express
Instead of writing the binding between express and the mcp transport yourself, you can use express-mcp-handler
to do it for you.
npm install express-mcp-handler
import express from 'express';
import { statelessHandler } from 'express-mcp-handler';
import { createServer } from './server';
// You can configure the server factory to include Mailgun settings
const createServerWithConfig = () => {
const serverConfig = {
name: "MyCandidateServer",
version: "1.0.0",
mailgunApiKey: process.env.MAILGUN_API_KEY,
mailgunDomain: process.env.MAILGUN_DOMAIN,
contactEmail: "[email protected]",
};
const candidateConfig = {
name: "John Doe",
resumeUrl: "https://example.com/resume.pdf",
// other candidate properties
};
return createServer(serverConfig, candidateConfig);
};
// Configure the stateless handler
const handler = statelessHandler(createServerWithConfig);
// Create Express app
const app = express();
app.use(express.json());
// Mount the handler (stateless only needs POST)
app.post('/mcp', handler);
// Start the server
const PORT = process.env.PORT || 3002;
app.listen(PORT, () => {
console.log(`Stateless MCP server running on port ${PORT}`);
});
Development
# Install dependencies
npm install
# Build the project
npm run build
# Run in development mode with auto-restart
npm run dev
Demo / Debug Startup via stdio
# Start with STDIO (demo only)
npm start
When running with STDIO, you can interact with the server by sending MCP messages as single-line JSON objects:
# Example of sending an initialize message via STDIO
echo '{"jsonrpc": "2.0","id": 1,"method": "initialize","params": {"protocolVersion": "2024-11-05","capabilities": {"roots": {"listChanged": true},"sampling": {}},"clientInfo": {"name": "ExampleClient","version": "1.0.0"}}}' | node dist/index.js --stdio
# List resources
echo '{"jsonrpc": "2.0","id": 2,"method": "resources/list","params": {}}' | node dist/index.js --stdio
# Access a resource
echo '{"jsonrpc": "2.0","id": 3,"method": "resources/read","params": {"uri": "candidate-info://resume-text"}}' | node dist/index.js --stdio
# List Tools
echo '{"jsonrpc": "2.0","id": 2,"method": "tools/list","params": {}}' | node dist/index.js --stdio
# Call a tool
echo '{"jsonrpc": "2.0","id": 4,"method": "tools/call","params": {"name": "get_resume_text", "args": {}}}' | node dist/index.js --stdio
# Send an email to the candidate
echo '{"jsonrpc": "2.0","id": 5,"method": "tools/call","params": {"name": "contact_candidate", "args": {"subject": "Hello from AI!", "message": "This is a test email sent via the MCP server.", "reply_address": "[email protected]"}}}' | node dist/index.js --stdio
Each message must be on a single line with no line breaks within the JSON object.
Features
- Library-first design for integration into other applications
- Modular resource system for extending with custom candidate information
- TypeScript for type safety and better developer experience
- Implements the full Model Context Protocol specification
- Supports multiple transport types (STDIO, HTTP, Streamable HTTP)
- Minimal dependencies
Server Structure
src/ ├── index.ts # Main package entry point ├── server.ts # MCP server factory with configuration ├── config.ts # Configuration type definitions └── resources/ # Modular resource definitions └── index.ts # Resource factory and implementation
MCP Protocol
This library implements the Model Context Protocol (MCP), a standardized way for LLMs to interact with external data and functionality. When integrated into your application, it exposes a stateless API that responds to JSON-RPC requests.
API Usage
Once integrated into your application, clients can interact with the MCP server by sending JSON-RPC requests. Here are examples of requests that your application would handle after integrating this library:
Initialize
curl -X POST http://your-application-url/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Accept: text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {}
},
"clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
}
}
}'
Access Candidate Resources
curl -X POST http://your-application-url/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Accept: text/event-stream" \
-d '{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "candidate-info://resume-text"
},
"id": 2
}'
Extending the Library
This library is designed to be extended with custom resources, tools, and prompts. Here’s how to add your own resources:
import { McpServer, Resource } from '@jhgaylor/candidate-mcp-server';
// Create your custom resource class
class CustomCandidateResource extends Resource {
constructor(candidateConfig) {
super(
`${candidateConfig.name} Custom Data`,
"candidate-info://custom-data",
async () => {
return {
contents: [
{
uri: "candidate-info://custom-data",
mimeType: "text/plain",
text: "Your custom candidate data here"
}
]
};
}
);
}
}
// Create server with standard configuration
const server = createServer(serverConfig, candidateConfig);
// Add your custom resource
const customResource = new CustomCandidateResource(candidateConfig);
customResource.bind(server);
// Connect with preferred transport
// ...
Adding Custom Tools
You can also extend the library with custom tools:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { createServer } from '@jhgaylor/candidate-mcp-server';
// Create server with standard configuration
const server = createServer(serverConfig, candidateConfig);
// Add a custom tool
server.tool(
'get_candidate_skills',
'Returns a list of the candidate skills',
{},
async (_args, _extra) => {
return {
content: [
{
type: "text",
text: "JavaScript, TypeScript, React, Node.js, MCP Protocol"
}
]
};
}
);
// Connect with preferred transport
// ...
Requirements
- Node.js 20+
- npm or yarn
License
Publishing to npm
Log in to npm if you haven’t already:
npm login
Publish the package to npm (will run your prepublishOnly build):
npm publish
To bump, tag, and push a new version:
npm version patch # or minor, major
git push origin main --tags
Dev Tools Supporting MCP
The following are the main code editors that support the Model Context Protocol. Click the link to visit the official website for more information.