hrmcp-server
Integrates with Stripe to manage credit-based billing, payment processing, and checkout sessions for the candidate scoring service.
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 |
| string | yes | — |
| string | yes | — |
| object | no |
|
| integer > 0 | no |
|
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_01J8XYZGET /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: 1712041234Self-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 |
| Balance is zero |
402 |
| 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 |
| 401 | Missing, invalid, or revoked API key |
| 429 | Rolling window limit hit; see |
| 402 | No credits remaining |
| 402 | Credits have passed their expiry date |
| 400 |
|
| 400 | Resume under 50 words |
| 400 | Input exceeds 15,000 characters |
| 400 | Weights do not sum to 1.0 |
| 400 | One or more weight keys absent |
| 400 | Weight value outside 0.0–1.0 |
| 400 |
|
| 400 |
|
| 503 | Anthropic API timeout or outage |
| 500 | Model returned unparseable output |
Warnings are non-fatal and appear alongside a 200 response:
Code | Trigger |
| Non-Latin characters in resume or JD |
| JD under 30 words |
Self-hosting
Deploy to Railway
Click the button above — Railway clones the repo and provisions a Postgres service
Add the five required environment variables (see below)
Register
POST /webhooks/stripein your Stripe dashboard; paste the signing secret intoSTRIPE_WEBHOOK_SECRETWatch the deploy log for
db_migratedandserver_startedHit
/healthto confirm
Run locally
git clone https://github.com/Spaceghost99/hrmcp-server.git
cd hrmcp-server
npm install
cp .env.example .env
# Fill in ANTHROPIC_API_KEY at minimum
npm run devScoring works without DATABASE_URL. Auth and billing require Postgres.
Environment variables
Five variables are required and will crash the server on startup if missing.
Variable | Required | Default | Description |
| yes | — | Anthropic API key |
| prod only | — | PostgreSQL connection string (Railway provides this) |
| prod only | — | Stripe secret key ( |
| prod only | — | Stripe webhook signing secret ( |
| no |
| Railway sets this automatically |
| no |
| Set to |
| no |
| Model for scoring |
| no |
| Anthropic API timeout in ms |
| no |
| bcrypt cost factor for key hashing |
| no |
| Set |
| no |
| Rolling per-minute limit per key |
| no |
| Rolling per-day limit per key |
| no |
| Max in-flight requests per key |
| no |
| Resume character limit |
| no |
| Job description character limit |
| no |
| Stripe price lookup key |
| no |
| Credits per purchase |
| no |
| Days before credits expire |
| no |
|
|
| no |
| Idempotency cache TTL in seconds |
| no |
| Public base URL; used in billing links |
See .env.example for descriptions of every variable.
Architecture
src/
index.ts — HTTP server, request routing, middleware wiring
config.ts — Environment variable loading
middleware/
auth.ts — API key extraction and validation
rateLimit.ts — Rolling window rate limiter (in-memory)
logger.ts — Structured JSON logging
billing/
keys.ts — Key generation, hashing, verification (pure functions)
db.ts — PostgreSQL pool, schema migration, all queries
stripe.ts — Checkout sessions, webhook handler, credit lifecycle
tools/
score-candidate/
handler.ts — Input validation, orchestration
scorer.ts — Anthropic API call, response parsing
schema.ts — Zod schemas and default weights
prompt.ts — System prompt and user prompt builder
errors/
codes.ts — Error code constants
envelope.ts — createError / createWarning helpersRequest flow for POST /score-candidate:
Auth — extract key, SHA-256 lookup, bcrypt verify
Rate limit — check rolling minute/day/concurrent windows
Parse + validate body
Idempotency — return cached response if key matches
Deduct credit — atomic
SELECT FOR UPDATEin PostgresScore — call Anthropic, parse and validate response
Cache response if idempotency key present
Apply
X-RateLimit-*headers, send responseRelease concurrent slot, write request log line
Alternatives
Other hosted candidate-scoring options exist. hrmcp-server is source-available, self-hostable, and speaks MCP natively — no wrapper required for agent frameworks that support the protocol.
License
Licensed under the Elastic License 2.0. Free to use, self-host, and modify. You may not offer the software to third parties as a hosted or managed service. For commercial hosting inquiries contact aaron@recruitapi.app.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Spaceghost99/hrmcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server