Borrowing it
Nothing to install: this file belongs to ebragas/recruitcrm-mcp. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/ebragas/recruitcrm-mcp/main/CLAUDE.mdgit clone --depth 1 https://github.com/ebragas/recruitcrm-mcpWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/ebragas/recruitcrm-mcp/claude-md)<a href="https://agentmods.dev/instructions/ebragas/recruitcrm-mcp/claude-md"><img src="https://agentmods.dev/badge/instructions/ebragas/recruitcrm-mcp/claude-md/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/instructions/ebragas/recruitcrm-mcp/claude-md"><img src="https://agentmods.dev/badge/instructions/ebragas/recruitcrm-mcp/claude-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.04166 | $0.04166 |
| Opus 5 | $0.02083 | $0.02083 |
| Sonnet 5 | $0.00833 | $0.00833 |
| Haiku 4.5 | $0.00417 | $0.00417 |
Grade A, and why
recruitcrm-mcp CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 184 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Recruit CRM MCP
Project Overview
MCP (Model Context Protocol) server for Recruit CRM, built with Python and FastMCP. Distributed via PyPI for zero-touch updates using uvx.
Tech Stack
- Language: Python 3.10+
- Framework: FastMCP
- HTTP Client: httpx
- Package Manager: uv
- Distribution: PyPI via
uvx
Development Setup
uv sync # install dependencies and create venv
uv run <cmd> # run commands in the venv
Recruit CRM API Reference
- Base URL:
https://api.recruitcrm.io/v1 - Auth:
Authorization: Bearer <RECRUIT_CRM_API_KEY> - Rate limit: 60 requests/minute (<6 licenses)
- Docs: https://docs.recruitcrm.io/docs/rcrm-api-reference/9033e3227d21f-recruit-crm-api
Key Endpoints
| Endpoint | Docs |
|---|---|
GET /candidates |
Search candidates |
GET /candidates/{slug} |
Find by slug |
GET /jobs |
Jobs list |
GET /jobs/{slug} |
Job by slug |
GET /jobs/{slug}/assigned-candidates |
Candidates assigned to a job |
GET /contacts |
Contacts list |
GET /contacts/search |
Search contacts |
GET /contacts/{slug} |
Contact by slug |
GET /users |
List team members/users |
GET /companies |
Companies list |
GET /companies/search |
Search companies |
GET /companies/{slug} |
Company by slug |
GET /notes |
Notes list |
GET /notes/search |
Search notes |
GET /notes/{id} |
Note by ID |
GET /tasks |
Tasks list |
GET /tasks/search |
Search tasks |
GET /tasks/{id} |
Task by ID |
GET /meetings |
Meetings list |
GET /meetings/search |
Search meetings |
GET /meetings/{id} |
Meeting by ID |
Field Mapping Gotchas
- Candidate company →
current_organization(notcompany_name) - Candidate job title →
position(primary populated field) - Candidate resume → object:
{"filename": "...", "file_link": "..."} - Job status →
job_statusobject:{"id": 1, "label": "Open"} - Job description →
job_description_text(HTML) - Pagination:
/candidatesuseslimitparam;/jobsusesper_page(min 15/page, below minimum is ignored) /candidates/searchsupports:first_name,last_name,email,linkedin,contact_number,state,country,created_from/to,updated_from/to— does NOT supportper_page,search,city,job_title,sort_by, orsort_order/candidateslist endpoint only acceptslimit— rejectssort_by/sort_orderwith 422 (despite docs listing them)- sort_by/sort_order: The API docs list these as supported on candidate endpoints, but the live API rejects them with 422 on both
/candidatesand/candidates/search. Do not add these params without first verifying via integration test. - Country filter uses fuzzy matching: Searching
country=United Statesalso returns candidates withcountry=United States of America. State filter uses exact matching. /jobs/searchrejectsper_pagewith 400/jobs/searchsupports:created_from,created_to,updated_from,updated_to,owner_id— does NOT acceptcreated_on,updated_on, orowner(400 rejected)- Job salary fields use
min_annual_salary/max_annual_salary(notminimum_/maximum_prefix) job_location_typeis a string:"0"=On-site,"1"=Remote,"2"=Hybridownerfield on jobs is an integer user ID — use/usersendpoint to resolve to names/contacts/searchsupports:first_name,last_name,email,linkedin,contact_number,company_slug,created_from/to,updated_from/to,owner_id— does NOT acceptdesignation(400 rejected)/contactslist endpoint acceptslimitparam- Search endpoints return
[]when called with no filter params - "Closed" job status has ID
0, which the API treats as no-filter — closed jobs cannot be filtered via/jobs/search /companies/searchsupports:company_name,created_from/to,updated_from/to,owner_id,owner_name,owner_email,sort_by,sort_order,exact_search,marked_as_off_limit/companies/searchsort_byacceptscreatedonorupdatedon;sort_orderacceptsascordesc/companies/searchexact_searchtoggles exact vs fuzzy name matching (default is fuzzy/like)/companieslist endpoint acceptslimitparam/companies/searchreturns[]with no filter params- Companies are referenced by
slug— jobs reference companies viacompany_slug - Notes use
id(integer) notslug—GET /notes/{id} /notes/searchsupports:added_from/to,updated_from/to— does NOT acceptcreated_from/to(400 rejected),related_toorrelated_to_type(422 rejected)/notes/searchusesadded_from/added_toinstead ofcreated_from/created_to(unique naming)/noteslist endpoint acceptslimitparam/notes/searchreturns[]with no filter params- Note
note_typeis an object:{"id": 48622, "label": "Note"} - Note / task / meeting
descriptionis HTML in Recruit CRM. The web editor stores and renders it as rich-text HTML (<p>,<ul>,<strong>, etc.). Plain-text and Markdown bodies render as a wall of text in the UI (newlines collapse,**and[link](url)show literal — verified empirically across notes, tasks, and meetings). The MCP layer normalizes Markdown↔HTML at the tool boundary:create_note/update_note/create_task/update_task/log_meeting/update_meetingconvert Markdown→HTML before POST;get_note/search_notes(viaNoteSummary.from_api_response) /get_task/get_meetingconvert HTML→Markdown on return. The model writes Markdown and reads Markdown; the CRM stores HTML. Seesrc/recruit_crm_mcp/formatting.py. The raw client layer does NOT convert — pass HTML if you call it directly. - Tasks use
id(integer) notslug—GET /tasks/{id} /tasks/searchsupports:title,created_from/to,updated_from/to,starting_from/to,owner_id— does NOT acceptrelated_toorrelated_to_type(422 rejected)/taskslist endpoint acceptslimitparam/tasks/searchreturns[]with no filter params- Task
task_typecan be null or an object:{"id": 1, "label": "Call"} - Meetings use
id(integer) notslug—GET /meetings/{id} - Meeting
meeting_typeis an object:{"id": 40014, "label": "Candidate Interview"} - Meeting
statusis an integer (not an object like job_status) /meetings/searchsupports:title,created_from/to,updated_from/to,starting_from/to,owner_id— does NOT acceptrelated_toorrelated_to_type(422 rejected)/meetingslist endpoint acceptslimitparam/meetings/searchreturns[]with no filter params- Custom fields are inline on update, not a sub-endpoint.
POST /companies/{slug},POST /contacts/{slug},POST /jobs/{slug},POST /candidates/{slug}all acceptcustom_fields: [{field_id, value}]inline in the body. There is NO/associated-fieldssub-endpoint for company/contact/candidate — that path exists only for candidate-on-job application-question answers, which is out of scope. - Job create required fields (seven):
name,number_of_openings,company_slug,contact_slug,job_description_text,currency_id,enable_job_application_form. Omit any of these and the API 422s. - Assign / unassign use
job_slugas a QUERY PARAM, not a body field.POST /candidates/{slug}/assign?job_slug=...andPOST /candidates/{slug}/unassign?job_slug=.... No body. - Hiring stage update path uses both slugs and the plural segment:
POST /candidates/{candidate_slug}/hiring-stages/{job_slug}with body{status_id, remark?, stage_date?, create_placement?}. - File upload uses one endpoint for every entity type.
POST /v1/fileswith multipart form fieldsrelated_to,related_to_type,folder, andfiles[].files[]accepts a public URL string OR a file — we support URLs in the MCP. There is no DELETE /files endpoint. - Contact multi-company uses comma-separated
company_slug. OnPOST /contacts/POST /contacts/{slug}, pass"slug1,slug2"as thecompany_slugfield. The read response returnscompany_slug(primary) andadditional_company_slugs(others) separately, but writes expect one combined comma-separated string. - Hiring pipeline stages key mismatch:
GET /hiring-pipelines/{id}returns items shaped{status_id, label}despite API docs claimingstage_id. Code must readstatus_id./sales-pipelinecorrectly returnsstage_idas documented. - All
update_*endpoints accept true partial POST. Per eachedit-*.md, every body field is optional; the live API confirms this for/companies/{slug},/contacts/{slug},/candidates/{slug},/jobs/{slug},/meetings/{id}, and/tasks/{id}. Send only fields you want to change; omitted fields are preserved server-side. - Do not fetch-merge-POST on update endpoints. The read shape diverges from the write shape (nested
task_type/meeting_typevs scalar*_type_id; arrayassociated_*vs comma-separated string; stringownervs integerowner_id) — re-posting the GET body yields 422 on every associated field. - Task
statusis NOT writable via any public endpoint. The edit-task.md write body omitsstatus; sending it returns 200 but the API silently ignores it. Probed every plausible field name (status,is_complete,completed,mark_complete,task_status,task_status_id,is_done— across int/string/bool shapes on 2026-04-24) — all silently ignored,statusstays at0. No dedicated task-completion endpoint exists indocs/api-reference/. Clients needing this must either delete the task or use the Recruit CRM UI. Treat as a product gap; file a vendor request if needed. do_not_send_calendar_invitesrejects JSONfalsewith 422. The API accepts PythonTrue,"1","0",0,1— butFalsetriggers"The selected do not send calendar invites is invalid."Server code must serialize bool to"1"/"0"strings before POSTing./jobscreate requires a lot:name,number_of_openings,company_slug,contact_slug,currency_id,job_description_text, andenable_job_application_form— heavy enough that inline test fixtures for jobs aren't cheap./jobscreate also requires contact/company linkage: thecontact_slugmust be linked to the samecompany_slugat contact-creation time (passcompany_slugonPOST /contacts). OtherwisePOST /jobsreturns 422contact_slug should be linked with provided company_slug. This constraint is undocumented.- Meeting attendees asymmetric on read vs write:
POST /meetingstakesattendee_candidates/attendee_contacts/attendee_usersas comma-separated slug strings.GET /meetings/{id}does NOT echo those fields — returnsNonefor them. Attendees instead appear under a separateattendees: [{attendee_id, attendee_type, display_name}]list withattendee_typediscriminating"Candidate"/"Contact"/"User".
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 9d ago First seen · 184 lines · 4,166 tokens per session scan A 05616fd0c3ae
recruitcrm-mcp CLAUDE.md is an instructions file published in the GitHub repository ebragas/recruitcrm-mcp (0 stars, last pushed 3mo ago), licensed MIT. It adds 4,166 tokens to every session, about $0.0208 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other instructions, from other repositories
next.js AGENTS.md
AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.
codex AGENTS.md
AGENTS.md instructions for openai/codex, covering rust/codex-rs, the codex-core crate, code review rules, crate api surface and model visible context.
vscode buildNext.instructions.md
Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).
spec-kit AGENTS.md
AGENTS.md instructions for github/spec-kit, covering agents.md, about spec kit and specify, quickstart — add a new integration in 5 steps, integration architecture and integrationmanifest — file tracking.
vscode oss-third-party-notices.instructions.md
Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, applying the notice (cutover) and fallback chain (never fail the build).
langchain AGENTS.md
AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.