recruitcrm-mcp: Instructions file for Claude Code

CLAUDE.md

recruitcrm-mcp CLAUDE.md is an instructions file for Claude Code from ebragas/recruitcrm-mcp. It costs 4,166 tokens per session, scanned A, original, MIT.

Development instructions for a Python MCP server that connects to Recruit CRM, a customer relationship management system for recruitment agencies. They cover the project setup and the Recruit CRM API, which is the interface used to access its data.

In plain words
What is it for?
Use them when setting up the server, searching candidates and contacts, listing jobs and users, or finding candidates assigned to a job.
Why use it?
They give contributors a shared reference for running the project and using its supported API endpoints correctly.

Instructions file for Claude Code

Written for Claude Code: the file is CLAUDE.md. Also seen: mentions Claude Code.

This is ebragas/recruitcrm-mcp's own configuration. It tells Claude Code how to work on recruitcrm-mcp itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything recruitcrm-mcp configures →

Reuse

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.

Copy the file
curl -O https://raw.githubusercontent.com/ebragas/recruitcrm-mcp/main/CLAUDE.md
Clone the repo
git clone --depth 1 https://github.com/ebragas/recruitcrm-mcp

Made for: Claude Code.

Wrote 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.

agentmods badge for recruitcrm-mcp CLAUDE.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/ebragas/recruitcrm-mcp/claude-md/github.svg)](https://agentmods.dev/instructions/ebragas/recruitcrm-mcp/claude-md)
Your own site
<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.

agentmods 80×15 button for recruitcrm-mcp CLAUDE.md

Your own site · 80×15
<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>
Per session 4,166 This file is loaded in full into every session.
When invoked 4,166 The same file — it is already loaded in full.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

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.

ModelPer sessionOnce 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

Measured 9d ago against content hash 05616fd0c3ae, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-10, from the pricing page.

Security

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.

CLAUDE.md · 184 lines

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

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 (not company_name)
  • Candidate job title → position (primary populated field)
  • Candidate resume → object: {"filename": "...", "file_link": "..."}
  • Job status → job_status object: {"id": 1, "label": "Open"}
  • Job description → job_description_text (HTML)
  • Pagination: /candidates uses limit param; /jobs uses per_page (min 15/page, below minimum is ignored)
  • /candidates/search supports: first_name, last_name, email, linkedin, contact_number, state, country, created_from/to, updated_from/to — does NOT support per_page, search, city, job_title, sort_by, or sort_order
  • /candidates list endpoint only accepts limit — rejects sort_by/sort_order with 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 /candidates and /candidates/search. Do not add these params without first verifying via integration test.
  • Country filter uses fuzzy matching: Searching country=United States also returns candidates with country=United States of America. State filter uses exact matching.
  • /jobs/search rejects per_page with 400
  • /jobs/search supports: created_from, created_to, updated_from, updated_to, owner_id — does NOT accept created_on, updated_on, or owner (400 rejected)
  • Job salary fields use min_annual_salary/max_annual_salary (not minimum_/maximum_ prefix)
  • job_location_type is a string: "0"=On-site, "1"=Remote, "2"=Hybrid
  • owner field on jobs is an integer user ID — use /users endpoint to resolve to names
  • /contacts/search supports: first_name, last_name, email, linkedin, contact_number, company_slug, created_from/to, updated_from/to, owner_id — does NOT accept designation (400 rejected)
  • /contacts list endpoint accepts limit param
  • 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/search supports: 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/search sort_by accepts createdon or updatedon; sort_order accepts asc or desc
  • /companies/search exact_search toggles exact vs fuzzy name matching (default is fuzzy/like)
  • /companies list endpoint accepts limit param
  • /companies/search returns [] with no filter params
  • Companies are referenced by slug — jobs reference companies via company_slug
  • Notes use id (integer) not slugGET /notes/{id}
  • /notes/search supports: added_from/to, updated_from/to — does NOT accept created_from/to (400 rejected), related_to or related_to_type (422 rejected)
  • /notes/search uses added_from/added_to instead of created_from/created_to (unique naming)
  • /notes list endpoint accepts limit param
  • /notes/search returns [] with no filter params
  • Note note_type is an object: {"id": 48622, "label": "Note"}
  • Note / task / meeting description is 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_meeting convert Markdown→HTML before POST; get_note / search_notes (via NoteSummary.from_api_response) / get_task / get_meeting convert HTML→Markdown on return. The model writes Markdown and reads Markdown; the CRM stores HTML. See src/recruit_crm_mcp/formatting.py. The raw client layer does NOT convert — pass HTML if you call it directly.
  • Tasks use id (integer) not slugGET /tasks/{id}
  • /tasks/search supports: title, created_from/to, updated_from/to, starting_from/to, owner_id — does NOT accept related_to or related_to_type (422 rejected)
  • /tasks list endpoint accepts limit param
  • /tasks/search returns [] with no filter params
  • Task task_type can be null or an object: {"id": 1, "label": "Call"}
  • Meetings use id (integer) not slugGET /meetings/{id}
  • Meeting meeting_type is an object: {"id": 40014, "label": "Candidate Interview"}
  • Meeting status is an integer (not an object like job_status)
  • /meetings/search supports: title, created_from/to, updated_from/to, starting_from/to, owner_id — does NOT accept related_to or related_to_type (422 rejected)
  • /meetings list endpoint accepts limit param
  • /meetings/search returns [] 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 accept custom_fields: [{field_id, value}] inline in the body. There is NO /associated-fields sub-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_slug as a QUERY PARAM, not a body field. POST /candidates/{slug}/assign?job_slug=... and POST /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/files with multipart form fields related_to, related_to_type, folder, and files[]. 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. On POST /contacts / POST /contacts/{slug}, pass "slug1,slug2" as the company_slug field. The read response returns company_slug (primary) and additional_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 claiming stage_id. Code must read status_id. /sales-pipeline correctly returns stage_id as documented.
  • All update_* endpoints accept true partial POST. Per each edit-*.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_type vs scalar *_type_id; array associated_* vs comma-separated string; string owner vs integer owner_id) — re-posting the GET body yields 422 on every associated field.
  • Task status is NOT writable via any public endpoint. The edit-task.md write body omits status; 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, status stays at 0. No dedicated task-completion endpoint exists in docs/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_invites rejects JSON false with 422. The API accepts Python True, "1", "0", 0, 1 — but False triggers "The selected do not send calendar invites is invalid." Server code must serialize bool to "1"/"0" strings before POSTing.
  • /jobs create requires a lot: name, number_of_openings, company_slug, contact_slug, currency_id, job_description_text, and enable_job_application_form — heavy enough that inline test fixtures for jobs aren't cheap.
  • /jobs create also requires contact/company linkage: the contact_slug must be linked to the same company_slug at contact-creation time (pass company_slug on POST /contacts). Otherwise POST /jobs returns 422 contact_slug should be linked with provided company_slug. This constraint is undocumented.
  • Meeting attendees asymmetric on read vs write: POST /meetings takes attendee_candidates/attendee_contacts/attendee_users as comma-separated slug strings. GET /meetings/{id} does NOT echo those fields — returns None for them. Attendees instead appear under a separate attendees: [{attendee_id, attendee_type, display_name}] list with attendee_type discriminating "Candidate"/"Contact"/"User".

Read the full file on GitHub · 184 lines

Changes

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.

  1. 9d ago First seen · 184 lines · 4,166 tokens per session scan A 05616fd0c3ae

Subscribe to this mod's changes

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.

Related

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.

vercel/next.js · 7,296 tokens

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.

openai/codex · 5,153 tokens

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).

microsoft/vscode · 6,785 tokens

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.

github/spec-kit · 7,104 tokens

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).

microsoft/vscode · 5,001 tokens

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.

langchain-ai/langchain · 4,469 tokens