AI candidate scoring via MCP. Score resumes against job descriptions with Claude — returns dimension scores, strengths, and gaps.

by Spaceghost99

242 downloads
Not rated
GitHub

About

hrmcp-server is an MCP-native server for HR and recruiting workflows. Send a resume and job description, get back structured scores across four dimensions (skills match, experience, industry background, education), plus specific strengths and gaps grounded in the actual content.

Details

Author
Spaceghost99
Downloads
242
Categories
AI

- Scores candidates on four configurable dimensions with overall score (0–100)
- Returns 2–4 grounded strengths and gaps per candidate
- Supports idempotency caching for 24 hours with a header
- Self-hostable on Railway or locally with Anthropic API key
- Credit-based billing: 100 credits for $5, expire after 180 days
- Rolling rate limits: 30 requests/minute and 500 requests/day per key

Use the hosted API at recruitapi.app without running anything, or self-host by deploying to Railway in under 15 minutes. Send a POST /score-candidate request with resume_text and job_description fields, and optionally custom weights and recency_window_years. Pass an API key via X-API-Key or Authorization: Bearer header.

hrmcp-server

A source-available MCP server for HR and recruiting workflows. Scores candidates against job descriptions using Claude, returns structured dimension scores, strengths, and gaps. Any agent framework that speaks MCP can call it natively.

Hosted API — use it without running anything: recruitapi.app
Self-host — deploy to Railway in under 15 minutes (see below)

---

Endpoints

POST /score-candidate

Score a candidate's resume against a job description.

Request

{
  "resume_text": "...",
  "job_description": "...",
  "weights": {
    "skills_match": 0.40,
    "experience": 0.30,
    "industry_background": 0.20,
    "education": 0.10
  },
  "recency_window_years": 10
}

| Field | Type | Required | Default |
|---|---|---|---|
| resume_text | string | yes | — |
| job_description | string | yes | — |
| weights | object | no | {skills_match: 0.40, experience: 0.30, industry_background: 0.20, education: 0.10} |
| recency_window_years | integer > 0 | no | 10 |

Weights must sum to 1.0. Each value must be between 0.0 and 1.0.
Both text fields max out at 15,000 characters. Resume must be at least 50 words.

Response — 200

{
  "overall_score": 82,
  "dimension_scores": {
    "skills_match": 88,
    "experience": 85,
    "industry_background": 74,
    "education": 70
  },
  "strengths": [
    "Five years of hands-on Python in production ML pipelines",
    "Led cross-functional team during platform migration"
  ],
  "gaps": [
    "No experience with Kubernetes",
    "MBA preferred; candidate holds a BS"
  ],
  "recency_window_used": 10,
  "model": "claude-sonnet-4-20250514",
  "warnings": []
}

All scores are integers 0–100. strengths and gaps are 2–4 strings each, grounded in the resume and job description — not generic observations.

Idempotency

Pass an Idempotency-Key header to cache the response for 24 hours. A retry with the same key returns the cached response without calling the model or deducting a credit.

Idempotency-Key: req_01J8XYZ

---

GET /health

{ "status": "ok", "model": "claude-sonnet-4-20250514" }

---

Authentication

Every request to /score-candidate requires an API key. Pass it either way:

X-API-Key: hrmcp_sk_...
Authorization: Bearer hrmcp_sk_...

Keys are issued after a credit purchase. Get one at hrmcp-server-production.up.railway.app/billing.

---

Rate limits

Limits apply per API key on a rolling window — not a fixed clock boundary.

| Limit | Default |
|---|---|
| Per minute | 30 requests |
| Per day | 500 requests |
| Concurrent | 5 in-flight |

Every response includes current limit state:

X-RateLimit-Limit-Minute: 30
X-RateLimit-Remaining-Minute: 28
X-RateLimit-Reset-Minute: 1712000060
X-RateLimit-Limit-Day: 500
X-RateLimit-Remaining-Day: 497
X-RateLimit-Reset-Day: 1712041234

Self-hosted deployments can disable rate limiting entirely with RATE_LIMIT_ENABLED=false.

---

Credits

Each successful call to /score-candidate deducts one credit. Credits are purchased in bundles of 100 for $5 and expire after 180 days.

| Status | Code | Meaning |
|---|---|---|
| 402 | credits_exhausted | Balance is zero |
| 402 | credits_expired | Credits exist but the bundle has expired |

---

Error format

All errors use the same envelope:

{
  "error": {
    "code": "missing_required_field",
    "message": "One or more required fields are missing.",
    "detail": { "missing_fields": ["resume_text"] }
  }
}

| Code | Status | Description |
|---|---|---|
| unauthorized | 401 | Missing, invalid, or revoked API key |
| rate_limit_exceeded | 429 | Rolling window limit hit; see Retry-After header |
| credits_exhausted | 402 | No credits remaining |
| credits_expired | 402 | Credits have passed their expiry date |
| missing_required_field | 400 | resume_text or job_description absent |
| resume_too_short | 400 | Resume under 50 words |
| payload_too_large | 400 | Input exceeds 15,000 characters |
| weights_invalid_sum | 400 | Weights do not sum to 1.0 |
| weights_missing_keys | 400 | One or more weight keys absent |
| weights_negative_value | 400 | Weight value outside 0.0–1.0 |
| recency_window_invalid | 400 | recency_window_years is not a positive integer |
| idempotency_key_invalid | 400 | Idempotency-Key header value is invalid |
| model_unavailable | 503 | Anthropic API timeout or outage |
| response_parse_failure | 500 | Model returned unparseable output |

Warnings are non-fatal and appear alongside a 200 response:

| Code | Trigger |
|---|---|
| non_english_detected | Non-Latin characters in resume or JD |
| job_description_thin | JD under 30 words |

---

Self-hosting

Deploy to Railway

Deploy on Railway

1. Click the button above — Railway clones the repo and provisions a Postgres service
2. Add the five required environment variables (see below)
3. Register POST /webhooks/stripe in your Stripe dashboard; paste the signing secret into STRIPE_WEBHOOK_SECRET
4. Watch the deploy log for db_migrated and server_started
5. Hit /health to confirm

Run locally

```bash
git clone https://github.com/Spaceghost99/hrmcp-server.git
cd hrmcp-server
npm install
cp .env.example .env

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.