import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import {
CallToolRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
ListPromptsRequestSchema,
GetPromptRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as fs from "fs/promises";
import * as path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Helper function to read resource files
async function readResourceFile(filename: string): Promise<string> {
const resourcePath = path.join(__dirname, "..", "resources", filename);
return await fs.readFile(resourcePath, "utf-8");
}
// Helper function to read prompt files
async function readPromptFile(filename: string): Promise<string> {
const promptPath = path.join(__dirname, "..", "prompts", filename);
return await fs.readFile(promptPath, "utf-8");
}
export function createMCPServer(): Server {
// Create the MCP server
const server = new Server(
{
name: "senior-dev-job-description-mcp",
version: "1.0.0",
},
{
capabilities: {
resources: {},
prompts: {},
},
}
);
// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "hiring-guide://senior-developer",
name: "Senior Developer Hiring Guide",
description:
"Guidelines on defining the right job position, what senior developers care about, and how to structure a job description",
mimeType: "text/markdown",
},
{
uri: "checklist://recruiting-discovery",
name: "Recruiting Discovery Checklist",
description:
"Comprehensive checklist for defining the position and answering candidate questions",
mimeType: "text/markdown",
},
],
};
});
// Read resource content
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri === "hiring-guide://senior-developer") {
const content = await readResourceFile("hiring-guide.md");
return {
contents: [
{
uri,
mimeType: "text/markdown",
text: content,
},
],
};
}
if (uri === "checklist://recruiting-discovery") {
const content = await readResourceFile("recruiting-discovery-checklist.md");
return {
contents: [
{
uri,
mimeType: "text/markdown",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
// List available prompts
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: [
{
name: "refine-job-description",
description:
"Review a job description or information against the recruiting checklist and return clarifying questions",
arguments: [
{
name: "job_info",
description:
"The job description or other information about the position to refine",
required: true,
},
],
},
],
};
});
// Get prompt content
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "refine-job-description") {
const jobInfo = args?.job_info as string;
if (!jobInfo) {
throw new Error("job_info argument is required");
}
const promptTemplate = await readPromptFile("refine-job-description.md");
const hiringGuide = await readResourceFile("hiring-guide.md");
const checklist = await readResourceFile("recruiting-discovery-checklist.md");
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `${promptTemplate}
# Job Information Provided:
${jobInfo}
# Senior Developer Hiring Guide:
${hiringGuide}
# Recruiting Discovery Checklist:
${checklist}`,
},
},
],
};
}
throw new Error(`Unknown prompt: ${name}`);
});
return server;
}