@kula-ai/mcp-server
OfficialClick on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@kula-ai/mcp-server list open jobs in the engineering department"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@kula-ai/mcp-server
An MCP (Model Context Protocol) server for the Kula recruiting API. Connect AI assistants like Claude to your Kula account to list jobs, manage applications, configure webhooks, and more.
Quick Start
With Claude Desktop
Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"kula": {
"command": "npx",
"args": ["-y", "@kula-ai/mcp-server"],
"env": {
"KULA_API_KEY": "your_api_key_here"
}
}
}
}Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"kula": {
"command": "npx",
"args": ["-y", "@kula-ai/mcp-server"],
"env": {
"KULA_API_KEY": "your_api_key_here"
}
}
}
}claude mcp add kula -- npx -y @kula-ai/mcp-serverThen set KULA_API_KEY in your environment.
Manual
npx @kula-ai/mcp-serverRelated MCP server: Recruit CRM MCP
Configuration
Environment Variable | Required | Description |
| Yes | Your Kula API key |
Get your API key from Kula Developer Settings.
Available Tools
51 tools across 13 categories:
Tool | Description |
| List all departments in the organization as a nested tree structure |
| List all offices in the organization |
| List all hiring milestones (pipeline stage groupings) |
| List all active internal users (recruiters, hiring managers, coordinators) |
Tool | Description |
| List all candidate sources in the organization |
Tool | Description |
| List all rejection reasons configured in the organization |
Tool | Description |
| List custom fields by subject type. Required — valid values: |
Tool | Description |
| List jobs with filters (status, department, office, date ranges, sort) |
| Search jobs by title (partial match) with optional filters |
| Get details of a specific job |
Tool | Description |
| List all pipeline stages for a specific job |
| Create a new pipeline stage for a job |
| List all activities configured for a specific job stage |
Tool | Description |
| List published job posts on the job board |
| Get details of a specific job post from the job board |
Tool | Description |
| Create a new candidate in the system |
| List candidates with simple filters (email, date ranges, sort) |
| Search candidates by name, email, skills, tags, location, and more |
| Get details of a specific candidate |
| Update an existing candidate's profile |
Tool | Description |
| List job applications |
| Get details of a specific application |
| Update the stage of a specific application |
| List notes on a specific application |
| Add a note to a specific application |
| Update an existing note on an application |
Tool | Description |
| List scorecard submissions for a specific application |
Tool | Description |
| List all configured webhooks |
| Create a new webhook subscription |
| Get details of a specific webhook |
| Update an existing webhook configuration |
| Delete a webhook |
| Enable a disabled webhook |
| Disable an active webhook |
| Rotate the signing secret for a webhook |
| Send a test payload to a webhook endpoint |
| List recent delivery logs for a webhook |
| List all available webhook event types |
| Get a sample webhook payload for a specific event type |
Tool | Description |
| List all requisitions for your account |
| Get detailed information about a specific requisition |
| List default and custom field definitions for requisitions |
| Create a new requisition (supports linked groups via head_count) |
| Update an existing requisition |
| Close a requisition |
Tool | Description |
| Search companies by name |
| List all available industries |
| Search locations by query |
| Search academic institutions by name |
| Search academic disciplines by name |
| List all available academic degrees |
Development
# Use correct Node version
nvm use
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Run tests
npm test
# Test with MCP Inspector
npx @modelcontextprotocol/inspector node build/index.jsConnecting locally
To test your local build with an AI client instead of the published package:
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"kula": {
"command": "node",
"args": ["/absolute/path/to/kula-mcp/build/index.js"],
"env": {
"KULA_API_KEY": "your_api_key_here"
}
}
}
}Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"kula": {
"command": "node",
"args": ["/absolute/path/to/kula-mcp/build/index.js"],
"env": {
"KULA_API_KEY": "your_api_key_here"
}
}
}
}claude mcp add kula -- node /absolute/path/to/kula-mcp/build/index.jsThen set KULA_API_KEY in your environment.
Note: The server uses STDIO transport, so there's no hot-reload. After rebuilding (
npm run buildor vianpm run dev), restart the MCP client to pick up changes.
License
MIT
Available Tools
84 toolscancel_interviewA
Cancel a scheduled interview. Calendar events are torn down and cancellation notifications dispatched asynchronously. Cannot cancel: already-cancelled interviews (err_interview_already_cancelled), or completed HackerRank interviews (err_cannot_cancel_completed_hackerrank).
Inputs: id (required).
check_interviewers_availabilityA
Compute free interview slots across the organizer + interviewers' calendars. Async — returns a poll_id immediately. Get the result two ways: (a) call get_interviewers_availability_result with the poll_id, or (b) subscribe to the interview.availability.computed webhook (recommended for production — avoids polling). Result expires 1 hour after computation.
Each returned slot carries interviewer_ids — the user IDs free at that range. For panel, every slot lists every interviewer in the request (a panel slot requires all of them to be free). For one_on_one, each slot lists the subset free at that range; pick one of those IDs when calling create_interview.
Inputs: organizer_id (required), interviewer_ids (required), start_time (required), duration_minutes (required), +3 more.
close_requisitionA
Close a requisition. Only requisitions in a closeable state can be closed.
Inputs: id (required), reason, apply_to_group.
create_application_noteB
Add a note to a specific application.
Inputs: application_id (required), body (required), notify_recruiter.
create_candidateA
Create a new candidate in Kula. At least one of email or linkedin_url (in social_urls) is required. Optionally link to a job pipeline via job_id and job_stage_id. Returns the created candidate object.
Inputs: first_name (required), last_name, email, phone_number, +9 more.
create_interviewA
Schedule an interview against an application. Calendar invites and conference URL are provisioned asynchronously — subscribe to the interview.event.created webhook to receive the fully-provisioned interview.
Typical workflow:
Plan-driven:
get_interview_plan→ pick astage_activity_id→check_interviewers_availability→create_interviewwithstage_activity_id(scorecard config inherits from the activity; passscorecard_template_idonly when stage_activity_id is NOT set).Ad-hoc:
list_valid_organizers(organizer_id) →list_applications(application_id) →check_interviewers_availability→create_interview.
Where to discover IDs:
application_id→list_applicationsorganizer_id→list_valid_organizers(filtered by job_id)interviewer_ids→list_users(any active user)office_id→list_offices(required when location=onsite)host_id→list_conference_hosts(required when location=zoom; must be in interviewer_ids)stage_activity_id→get_interview_planinterviewer_template_id/candidate_template_id→list_email_templatesscorecard_template_id→list_scorecard_templates
Constraints:
start_timemust be on a 15-minute boundary with zero seconds (e.g.09:00:00,09:15:00) and in the futureduration_minutesmust be a multiple of 15 (15..1440)kind: one_on_onerequires exactly one entry ininterviewer_ids
Inputs: organizer_id (required), application_id (required), start_time (required), duration_minutes (required), +15 more.
create_job_stageB
Create a new pipeline stage for a job.
Inputs: job_id (required), name (required), milestone_id, position, +1 more.
create_requisitionA
Create a new requisition. When head_count exceeds 1, creates a group of linked requisitions. Use list_requisition_fields to get available custom field IDs for additional_info.
Inputs: role_name (required), employment_type (required), requisition_type (required), department_id (required), +13 more.
create_userA
Invite a new user to the account. The user is created in the pending state and sent an invitation email. Requires email and first_name.
Inputs: email (required), first_name (required), role_id, last_name, +5 more.
create_webhookB
Create a new webhook subscription.
Inputs: url (required), name (required), subscribed_events (required), secret, +2 more.
deactivate_userA
Deactivate a user. The user can no longer sign in but their historical activity is preserved.
Inputs: id (required).
delete_webhookB
Delete a webhook.
Inputs: id (required).
disable_webhookA
Disable an active webhook.
Inputs: id (required).
enable_webhookA
Enable a disabled webhook.
Inputs: id (required).
find_companiesB
Search the global company catalog. Returned IDs map to current_company_ids on candidate search.
Inputs: query (required), page, limit.
find_currenciesA
List currencies. Returned IDs map to salary_currency_id on requisitions.
Inputs: page, limit.
find_degreesB
List academic degrees, optionally filtered by name. Useful for discovering valid degree options for candidate education records.
Inputs: query, page, limit.
find_disciplinesB
Search academic disciplines (fields of study).
Inputs: query (required), page, limit.
find_industriesB
List industries used to classify companies. Paginated; useful for discovering valid industry options.
Inputs: page, limit.
find_institutionsB
Search academic institutions. Returned IDs map to institute_ids on candidate search.
Inputs: query (required), page, limit.
find_locationsA
Search cities, states, and countries. The returned type discriminator (city|state|country) tells you which places_*_id field on candidate endpoints the id maps to. City results also include state_id and country_id (parent chain); State results include country_id; Country results have both as null.
Inputs: query (required), page, limit.
find_skillsA
Search the global skill catalog. Returned IDs map to skill_ids on candidate search.
Inputs: query (required), page, limit.
find_tagsA
Search candidate tags (account-scoped). Returned IDs map to tag_ids on candidate search.
Inputs: query (required), page, limit.
get_applicationA
Get details of a specific application. Only use when the user asks about a specific application.
Inputs: id (required).
get_candidateA
Retrieve full details of a specific candidate by ID, including all applications, tags, skills, and location. Use this when you already have the candidate ID. To find a candidate by name or attributes, use search_candidates first.
Inputs: id (required).
get_email_templateA
Get full details for a single email or calendar-invite template, including subject, body, and owner.
Inputs: id (required).
get_interviewA
Get full details for a single interview, including interviewers, candidate, conference URL, scorecard refs.
Inputs: id (required).
get_interviewers_availability_resultA
Poll for the result of a previous check_interviewers_availability call. Returns 200 with status=succeeded/failed when terminated, 202 with status=pending while running, 410 if expired (1-hour TTL after completion). Respect the Retry-After header — don't poll faster than every 5s. For production loads, prefer the interview.availability.computed webhook.
Each slot in the response includes interviewer_ids — the user IDs free at that slot. Use one of those IDs as interviewer_ids (and host_id for zoom) when calling create_interview.
Inputs: poll_id (required).
get_interview_planA
Read the interview plan configured on a job — stages with their pre-configured interview activities. Each activity's id is the stage_activity_id to pass to create_interview (which inherits the activity's scorecard config).
Inputs: job_id (required).
get_jobA
Retrieve full details of a specific job by ID, including description and interview stages. Use this when you already have the job ID. To find a job by title, use search_jobs first.
Inputs: id (required).
get_job_postA
Get details of a specific job post from the job board. Only use when the user asks about a specific job board listing.
Inputs: id (required).
get_requisitionB
Get detailed information about a specific requisition, including description and custom field values.
Inputs: id (required).
get_roleA
Retrieve a single role by ID. Response includes a permissions object mapping resource:action keys (e.g. users:manage, jobs:read) to booleans indicating whether the role grants each one.
Inputs: id (required).
get_scorecard_templateA
Get full details for a single scorecard template — questions, feedback/rating descriptions, and segmentation.
Inputs: id (required).
get_userA
Retrieve a single user by ID. Response includes a permissions array of resource:action keys granted by the user's role.
Inputs: id (required).
get_webhookB
Get details of a specific webhook.
Inputs: id (required).
get_webhook_sample_payloadB
Get a sample webhook payload for a specific event type.
Inputs: event_type (required).
list_application_interviewsA
List the interviews scheduled on a specific application. Same as list_interviews but scoped to one application (the application_id goes in the path, not as a filter). Cancelled interviews are included by default — use meeting_status=cancelled etc. to filter.
Inputs: application_id (required), page, limit, interviewer_ids, +13 more.
list_application_notesC
List notes on a specific application.
Inputs: application_id (required), page, limit, sort_by, +5 more.
list_applicationsA
List job applications. Only use when the user explicitly asks about applications.
Inputs: page, limit, job_id, status, +8 more.
list_candidatesA
List candidates with simple filters: email, date ranges, and sorting. Use this for browsing or filtering by exact email. For full-text search or filtering by skills, tags, location, job pipeline, or resume presence — use search_candidates instead.
Inputs: page, limit, email, sort_by, +5 more.
list_conference_hostsA
List users eligible to be the conference host_id (e.g., for Zoom — they have an active workspace seat). Used when scheduling video-conference interviews.
Inputs: provider (required), query, page, limit.
list_custom_fieldsA
List custom fields configured in the organization. The type parameter is required — specify job, candidate, requisition, or offer.
Inputs: type (required), page, limit, sort_by, +7 more.
list_degreesB
List all available academic degrees.
Inputs: no named parameters.
list_departmentsA
List all departments as a flat paginated list. Each record has a parent_id to reconstruct the hierarchy client-side.
Inputs: page, limit, sort_by, sort_order, +4 more.
list_email_templatesA
List email and calendar-invite templates configured for the account. Per-interview snapshots and system templates are excluded. Use this to discover interviewer_template_id and candidate_template_id for create_interview.
Inputs: page, limit, query, channel, +8 more.
list_industriesB
List all available industries.
Inputs: no named parameters.
list_interviewsA
List interviews for the account. Supports rich multi-value filters: by job, application, candidate, interviewer, organizer, recruiter, department, office, status, kind, location, AI note-taker flag, and start_time window. Cancelled interviews are included by default — use meeting_status=cancelled etc. to filter.
Inputs: page, limit, job_ids, application_ids, +18 more.
list_job_postsA
List published job posts on the job board. Only use when the user explicitly asks about job board listings.
Inputs: page, limit, department_ids, office_ids.
list_jobsA
List jobs with SQL-based filters and sorting. Use this for browsing jobs or filtering by status, department, office, or date ranges. For title search (partial match supported), use search_jobs instead.
Inputs: page, limit, department_ids, office_ids, +7 more.
list_job_stagesC
List all pipeline stages for a specific job.
Inputs: job_id (required), page, limit, sort_by, +5 more.
list_milestonesB
List all hiring milestones (pipeline stage groupings) in the organization.
Inputs: page, limit, sort_by, sort_order, +4 more.
list_officesB
List all offices in the organization.
Inputs: page, limit, sort_by, sort_order, +4 more.
list_rejection_reasonsB
List all rejection reasons configured in the organization.
Inputs: page, limit, sort_by, sort_order, +6 more.
list_requisition_fieldsA
List default and custom field definitions for requisitions. Hidden fields are excluded. Optionally filter by department or office.
Inputs: department_ids, office_ids.
list_requisitionsC
List all requisitions for your account, respecting permissions.
Inputs: page, limit, status, department_ids, +18 more.
list_rolesA
List roles available in the account. Use this to discover valid role_id values for create_user and update_user.
Inputs: page, limit, sort_by, sort_order, +4 more.
list_scorecard_submissionsA
List scorecards for a specific application. Each scorecard may be linked to an interview, assessment, or review — use the type filter to narrow by activity type.
Inputs: application_id (required), status, type, page, +7 more.
list_scorecard_templatesA
List scorecard templates configured for the account. Use this to discover scorecard_template_id values to pass to create_interview (only honored when stage_activity_id is NOT set — interview-plan activities own scorecard config).
Inputs: page, limit, query, department_ids, +8 more.
list_sourcesB
List all candidate sources in the organization.
Inputs: page, limit, enabled, sort_by, +5 more.
list_stage_activitiesB
List all activities (actions) configured for a specific job stage.
Inputs: job_id (required), stage_id (required), page, limit, +6 more.
list_usersB
List users in the organization. Defaults to active users; use the status filter to include pending, deactivated, or imported. Supports filtering by role, department, office, granted permissions, and a full-text query across name and email.
Inputs: page, limit, sort_by, sort_order, +10 more.
list_valid_organizersA
List users eligible to be the organizer_id when scheduling an interview for a job — they have a connected calendar (Google or Microsoft) and permission to manage candidates on the job.
Inputs: job_id (required), query, page, limit.
list_webhook_eventsB
List all available webhook event types you can subscribe to.
Inputs: no named parameters.
list_webhook_logsA
List recent delivery logs for a webhook, including status and response details for each attempt.
Inputs: id (required), page, limit.
list_webhooksB
List all configured webhooks.
Inputs: page, limit.
mark_candidate_no_showA
Mark the candidate as a no-show on an in_progress or ended interview. Cannot be marked when a scorecard has been submitted.
Inputs: id (required).
reactivate_userC
Reactivate a previously deactivated user.
Inputs: id (required).
rotate_webhook_secretB
Rotate the signing secret for a webhook.
Inputs: id (required).
search_candidatesA
Search candidates using Elasticsearch with rich filters and cursor-based pagination. Preferred over list_candidates when you need: full-text search (name, email, resume), filtering by skills, tags, sources, job pipeline, location, or resume presence. Pagination: pass cursor from the previous response meta.next_cursor to get the next page. IMPORTANT: if you change any filter or search parameter, omit cursor and start a new request — cursors are tied to a specific search context and will return wrong results if filters change.
Inputs: cursor, query, skill_ids, tag_ids, +13 more.
search_companiesB
Search companies by name. Useful for autocompleting company names.
Inputs: query (required).
search_disciplinesA
Search academic disciplines by name. Useful for autocompleting field of study.
Inputs: query (required).
search_institutionsA
Search academic institutions by name. Useful for autocompleting university or school names.
Inputs: query (required).
search_jobsA
Search jobs by title (partial match supported) with optional filters. Preferred over list_jobs when you need to find jobs by name. Results are sorted by relevance.
Inputs: query, department_ids, office_ids, status, +8 more.
search_locationsA
Search locations by query. Useful for autocompleting city or region names.
Inputs: query (required).
test_webhookA
Send a test payload to a webhook and wait for the delivery result. Polls until delivered or failed (30s timeout).
Inputs: id (required).
undo_candidate_no_showA
Reverse a candidate no-show. Allowed only when meeting_status is candidate_no_show.
Inputs: id (required).
update_application_noteB
Update an existing note on an application.
Inputs: application_id (required), id (required), body, notify_recruiter.
update_application_stageC
Update the stage of a specific application.
Inputs: id (required), stage_id (required), requisition_code.
update_candidateA
Update an existing candidate's profile. All fields are optional — only send the fields you want to change. Returns the updated candidate object.
Inputs: id (required), first_name, last_name, email, +8 more.
update_interviewA
Update an existing interview. All fields are optional — only the supplied fields are modified. Immutable fields (cannot be changed after creation): organizer_id, application_id, job_id, stage_id, candidate_id, stage_activity_id, scorecard_template_id. Cancelled interviews cannot be updated (returns 422 err_interview_cancelled).
Inputs: id (required), start_time, duration_minutes, timezone, +12 more.
update_requisitionA
Update an existing requisition. Cannot modify requisitions with closed, archived, or filled statuses. Pass all custom field values in additional_info — omitted fields will be cleared.
Inputs: id (required), role_name, employment_type, requisition_type, +15 more.
update_userA
Update an existing user. Only supplied fields are modified. Email and account status cannot be changed via this endpoint.
Inputs: id (required), first_name, last_name, job_title, +5 more.
update_webhookA
Update an existing webhook configuration. Only include fields you want to change.
Inputs: id (required), url, name, subscribed_events, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 84 tools
Each tool has a distinct, purpose-specific name and detailed description that clearly differentiates it from others. There is no overlap; even similar operations like 'list_candidates' vs 'search_candidates' are explained with different use cases.
All tool names follow a consistent verb_noun snake_case pattern (e.g., cancel_interview, create_candidate, get_job). No mixing of casing or irregular naming is observed.
84 tools is extremely high for an MCP server, far exceeding the typical 3-15 range. While the domain is broad, this count is excessive and likely to overwhelm agents and reduce coherence.
The tool set covers the full lifecycle of recruiting: candidates, applications, interviews, jobs, requisitions, users, webhooks, and reference data (skills, locations, etc.). CRUD operations are present for core entities, with additional utilities like searching and webhook management. No obvious gaps are apparent.
Maintenance
Related MCP Connectors
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
MCP server exposing klokin time-tracking operations (employees, time entries, stores) to AI clients.
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceThis MCP server provides hiring automation tools for recruitment processes. It enables users to generate job descriptions, score CVs, create interview questions, benchmark salaries, and draft offer letters through natural language interactions.16 npm31 PyPIMIT
- AlicenseAqualityCmaintenanceMCP server for Recruit CRM, enabling AI assistants to search candidates, view jobs, and manage recruiting workflows.53MIT
- AlicenseAqualityCmaintenanceMCP server connecting AI assistants to official France Travail APIs for real-time job offers, ROME code prediction, and hiring company search.780 npm1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Hunaras, an AI-native recruiting platform that enables candidates and employers to manage jobs, applications, assessments, and talent sourcing through natural language.14 npmMIT