mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-04 02:33:47 +10:00
* feat(ats): add ATS checker and replace resume analysis Adds a public, browser-only ATS checker at /ats-checker and an ATS Check section in the builder's right sidebar. PDFs are parsed locally: text extraction, reading order, contact and date recovery, section detection, and file-level readability are scored deterministically, with evidence cited per finding and skipped checks reported rather than counted as passes. Removes the AI-scored resume analysis it supersedes: the resume_analysis table (dropped via migration), the get_resume_analysis MCP tool, and POST /ai/analyze-resume. The replacement, POST /ai/ats-review, reviews extracted resume text and returns qualitative feedback with no score. Also bumps the version to 5.2.9 and adds the changelog entry. * chore(deps): bump workspace dependencies * fix(ats-checker): keep negation inside each 'what this does not do' bullet The three bullets were bare fragments whose negation came from the section heading, which translators never see. A dozen locales rendered them as affirmative assertions or imperatives, so the page claimed the checker enforces a one-page rule and predicts rejection -- the opposite of the source, and directly contradicted by the sentence beside it. Each bullet now carries its own negation, so the polarity cannot be lost in translation. Re-extracted and refilled across all 53 target locales.
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import type { RouterClient } from "@orpc/server";
|
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
import { onError } from "@orpc/client";
|
|
import { createRouterClient } from "@orpc/server";
|
|
import router from "@reactive-resume/api/routers";
|
|
import { MCP_TOOL_NAME, registerPrompts, registerResources, registerTools } from "@reactive-resume/mcp";
|
|
import { appVersion } from "../app-version";
|
|
import { getRequestLocale } from "../rpc/locale";
|
|
|
|
function createRequestClient(request: Request): RouterClient<typeof router> {
|
|
return createRouterClient(router, {
|
|
interceptors: [
|
|
onError((error) => {
|
|
console.error("[MCP oRPC]", error);
|
|
}),
|
|
],
|
|
context: () => ({
|
|
locale: getRequestLocale(request),
|
|
reqHeaders: request.headers,
|
|
resHeaders: new Headers(),
|
|
}),
|
|
});
|
|
}
|
|
|
|
export function createMcpServer(request: Request) {
|
|
const server = new McpServer(
|
|
{
|
|
name: "reactive-resume",
|
|
version: appVersion,
|
|
title: "Reactive Resume",
|
|
websiteUrl: "https://rxresu.me",
|
|
description:
|
|
"Reactive Resume is a free and open-source resume builder. Use this MCP server to interact with your resume using an LLM of your choice.",
|
|
icons: [
|
|
{
|
|
src: "https://rxresu.me/icon/light.svg",
|
|
mimeType: "image/svg+xml",
|
|
theme: "light",
|
|
},
|
|
{
|
|
src: "https://rxresu.me/icon/dark.svg",
|
|
mimeType: "image/svg+xml",
|
|
theme: "dark",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
instructions: [
|
|
"You are connected to Reactive Resume over MCP.",
|
|
"Authenticate with OAuth (recommended) or an API key (`x-api-key`).",
|
|
`Discover resume IDs with \`${MCP_TOOL_NAME.listResumes}\` (not \`resources/list\`).`,
|
|
`List distinct tags with \`${MCP_TOOL_NAME.listResumeTags}\`.`,
|
|
`Read schema at \`resume://_meta/schema\`; read resume JSON via \`resume://{id}\` or \`${MCP_TOOL_NAME.getResume}\`.`,
|
|
`Apply body edits with JSON Patch through \`${MCP_TOOL_NAME.patchResume}\`.`,
|
|
`Change name, slug, tags, or public visibility with \`${MCP_TOOL_NAME.updateResume}\` (returns canonical share URL; anonymous access only when \`isPublic\` is true; passwords are managed in the web app only).`,
|
|
`Create short-lived authenticated PDF download URLs with \`${MCP_TOOL_NAME.downloadResumePdf}\`; set target to \`cover-letter\` to export a visible cover letter separately.`,
|
|
`Import full ResumeData JSON with \`${MCP_TOOL_NAME.importResume}\`.`,
|
|
].join(" "),
|
|
},
|
|
);
|
|
|
|
const client = createRequestClient(request);
|
|
registerResources(server, client);
|
|
registerTools(server, client, request.headers);
|
|
registerPrompts(server);
|
|
|
|
return server;
|
|
}
|