Lever MCP server for AI agents

Live

OAUTH 2.0

RECRUITING

Productivity

Lever gives your agent recruiting operations in your ATS: track opportunities through pipeline stages, schedule interview panels and collect feedback, manage job postings and requisitions, and keep candidate notes and tags current.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Lever
agent · Acme Q3
Run
Which opportunities for the Account Executive posting are in the Onsite stage?
S
lever_opportunities_list
117ms
Recruiting agent
7 opportunities are in the Onsite stage for Account Executive. 3 of them came in through referrals.
Sources: Lever opportunities, 1 posting
lever
7 opportunities
18:29
Message Claude...

Tools your recruiting agent reaches for on Lever, scoped per user.

CALL ANY TOOL
77 tools for recruiting in Lever: opportunities, stages, tags, sources, notes, interview panels, feedback, offers, postings, requisitions, and resumes.
lever_applications_deleted_list
List applications deleted
List applications deleted from the Lever account within a time window of at most 30 days. Returns a page of deleted applications with id, deletedAt, opportunityId and postingId. Use this to sync application deletions. Use lever_opportunity_get with expand applications for live applications.
Parameters
Name
Type
Required
Description
deleted_at_end
integer
Required
End of the deletion window (exclusive). The window may not exceed 30 days. Unix timestamp in milliseconds. Example: 1407460069499
deleted_at_start
integer
Required
Start of the deletion window (inclusive). The window may not exceed 30 days. Unix timestamp in milliseconds. Example: 1407460069499
limit
integer
Optional
Maximum number of results to return per page, between 1 and 100. Lever defaults to its own page size when omitted. Example: 50
offset
string
Optional
Pagination cursor. Pass the next value returned by the previous page of this list to fetch the following page. Omit for the first page. Example: 0.1414895548650.a6070140-33db-407c-91f5-2760e15c8e94
lever_archive_reason_get
Get archive reason
lever_contact_update
Update contact
lever_disposition_stages_list
List disposition stages
lever_diversity_survey_get
Get diversity survey
lever_feedback_create
Create feedback
lever_feedback_delete
Delete feedback
lever_file_get
Get file
lever_files_list
List files
lever_interview_get
Get interview
lever_interview_update
Update interview
lever_interviews_list
List interviews
lever_note_create
Create note
lever_note_delete
Delete note
lever_opportunities_deleted_list
List opportunities deleted
lever_opportunity_archive
Archive opportunity
lever_opportunity_links_add
Add opportunity links
lever_opportunity_links_remove
Remove opportunity links
lever_opportunity_unarchive
Opportunity unarchive
lever_panel_get
Get panel
lever_panel_update
Update panel
lever_panels_list
List panels
lever_posting_create
Create posting
lever_posting_get
Get posting
lever_postings_deleted_list
List postings deleted
lever_referrals_list
List referrals
lever_requisition_field_get
Get requisition field
lever_requisitions_list
List requisitions
lever_resume_get
Get resume
lever_stages_list
List stages

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Lever tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["lever"], toolNames: [
    "lever_opportunities_list",
    "lever_feedback_list",
    "lever_opportunity_stage_update"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Move Onsite opportunities for the Account Executive posting with completed feedback to the Offer stage" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["lever"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Move Onsite opportunities for the Account Executive posting with completed feedback to the Offer stage" }],
  tools,
});

// Execute the tool call with the user's vaulted Lever OAuth token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["lever"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Move Onsite opportunities for the Account Executive posting with completed feedback to the Offer stage" }],
  tools,
});

// Tool call runs with the user's vaulted Lever OAuth token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["lever"] }, pageSize: 100,
});

const agent = new Agent({
  name: "recruiting_agent",
  model: "gemini-2.5-pro",
  instruction: "Lever tools scoped to this user",
  tools,
});

await agent.run("Move Onsite opportunities for the Account Executive posting with completed feedback to the Offer stage");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Lever tool. Click to copy, paste into your agent, done.
Pipeline
Copy the prompt
Copied
List opportunities tagged Senior in the Phone Screen stage.
Copy the prompt
Copied
Move Jordan Lee's opportunity to the Onsite stage.
Copy the prompt
Copied
Archive the opportunity for sam@example.com with the reason Withdrew.
Interviews and feedback
Copy the prompt
Copied
Show the interview panels scheduled for Priya Shah.
Copy the prompt
Copied
List the feedback submitted for Chen Wei's onsite.
Copy the prompt
Copied
Add a note to Maria Lopez's profile: strong system design, check references.
Postings
Copy the prompt
Copied
List published postings in the Engineering department.
Copy the prompt
Copied
Create a draft posting for a Product Marketing Manager in London.
Copy the prompt
Copied
Show open requisitions and their headcount.
SEE HOW AUTH WORKS
Each user signs in to Lever once, and Scalekit stores and refreshes their tokens. Tokens stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Lever
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Lever
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Lever
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Lever
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other recruiting and HR connectors.
People Ops and HR teams
Offer letter routing agent
Drafts the offer in PandaDoc, blocks on the hiring manager's approval in Slack, then emails the candidate their e-signature link. Every call runs as the recruiter who triggered it, never a shared HR bot.
Support and Ops Teams
Meeting prep
Pulls agenda, participant context, and open action items before every meeting.
Test other agents
See the same per-user auth pattern across other recruiting and HR connectors.
PEOPLE OPS
Offer letter routing agent
Draft the offer in PandaDoc, gate it on hiring manager approval in Slack, then email the candidate their signature link.
OPS
Meeting prep agent
Assemble the agenda, HubSpot attendee history, and open action items from Gmail before every meeting on the calendar.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Lever token looks fine in a demo. In production every stage move and archive looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Lever today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Lever as the user or through a shared service account?
As the user. Each user signs in to Lever once, and Scalekit stores and refreshes their tokens. Stage moves, notes, and feedback the agent records are attributed to that user in your audit trail, not a shared service account.
Where is the Lever OAuth token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Lever?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example the pipeline read tools and lever_note_create without lever_feedback_delete or lever_file_delete, which remove interview feedback and files from an opportunity. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Lever access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
What does Lever mean by an opportunity?
An opportunity is one candidacy: a person moving through your pipeline. A contact can have several opportunities, and lever_contact_get returns the contact record shared across them. Most pipeline tools, such as lever_opportunity_stage_update and lever_notes_list, act on one opportunity.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""lever"": {
""url"": ""https://mcp.scalekit.com/lever"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.lever]
url = ""https://mcp.scalekit.com/lever""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""lever"": {
""url"": ""https://mcp.scalekit.com/lever"",
""type"": ""http""
}
}
}