Salesloft

Live

OAUTH 2.0

SALES ENGAGEMENT

CRM & Sales

Cadence steps, prospect lists, call outcomes, and email activity your sales agent needs to execute and log live in Salesloft. Salesloft gives your sales engagement agent per-user OAuth access, no shared service account, no credential sprawl.

  • Acts as the user: Every cadence action and logged activity runs under the authorizing rep's Salesloft identity.
  • Credentials stay vaulted: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: User permissions enforced. 90-day audit trail on every prospect interaction.
Salesloft
agent · Acme Q3
Run
Which prospects in my enterprise cadence are overdue for step 4 and have not replied to any touchpoint?
S
salesloft_cadence_prospects_get
178ms
Sales agent
9 prospects overdue on step 4 with zero replies. Top: Joanna Chen (VP Eng, Meridian — opened 3 emails), Mark Osei (Director IT, Techflow — 7 days overdue).
Sources: Salesloft cadence data, activity history
salesloft
9
18:29
Message Claude...

Tools your sales agent reaches for on Salesloft, scoped per rep.

CALL ANY TOOL
OAuth-scoped per rep. Every cadence action and call log attributed to the authorizing sales rep.
salesloft_cadence_prospects_get
Get cadence prospects
List prospects enrolled in a cadence with their current step, due date, and full activity history filtered to the authorizing rep's assignments.
Parameters
Name
Type
Required
Description
cadence_id
string
Optional
Salesloft cadence ID (omit to list all assigned cadences)
step
integer
Optional
Filter by cadence step number
overdue_only
boolean
Optional
Return only overdue prospects
salesloft_activities_list
List activities
salesloft_cadence_step_execute
Execute cadence step
salesloft_prospects_search
Search prospects
salesloft_calls_log
Log call
Build your Agent
Drop the toolkit in, point it at the authorized rep, and your agent can query cadences and log activities from the first run.
import { ScalekitClient } from "@scalekit-sdk/node";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { z } from "zod";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["outreachmcp"], toolNames: ["outreach_prospects_search", "outreach_sequences_list", "outreach_tasks_get"] },
pageSize: 100,
});

const lcTools = tools.map((t) => new DynamicStructuredTool({
name: t.tool.definition.name,
description: t.tool.definition.description,
schema: z.object({}).passthrough(),
func: async (args) => {
const { data } = await sk.tools.executeTool({
toolName: t.tool.definition.name,
identifier: "user_123",
params: args,
});
return JSON.stringify(data);
},
}));

const agent = createReactAgent({ llm, tools: lcTools });
import { ScalekitClient } from "@scalekit-sdk/node";
import OpenAI from "openai";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["outreachmcp"], toolNames: ["outreach_prospects_search", "outreach_sequences_list", "outreach_tasks_get"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
type: "function",
function: {
name: t.tool.definition.name,
description: t.tool.definition.description,
parameters: t.tool.definition.input_schema,
},
}));

const resp = await openai.responses.create({
model: "gpt-4o", input: prompt, tools: llmTools,
});
import { ScalekitClient } from "@scalekit-sdk/node";
import Anthropic from "@anthropic-ai/sdk";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["outreachmcp"], toolNames: ["outreach_prospects_search", "outreach_sequences_list", "outreach_tasks_get"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
name: t.tool.definition.name,
description: t.tool.definition.description,
input_schema: t.tool.definition.input_schema,
}));

const msg = await anthropic.messages.create({
model: "claude-sonnet-4-6", max_tokens: 1024,
tools: llmTools,
messages: [{ role: "user", content: prompt }],
});
import { Agent } from "@google/adk/agents";
import {
MCPToolset, StreamableHTTPConnectionParams,
} from "@google/adk/tools/mcp";

const toolset = new MCPToolset({
connectionParams: new StreamableHTTPConnectionParams({
url: "https://mcp.scalekit.com/outreachmcp",
headers: { Authorization: `Bearer ${userScopedToken}` },
}),
});

const agent = new Agent({
name: "agent", model: "gemini-2.0-flash",
tools: await toolset.getTools(),
});
Try these prompts
Paste any prompt into your sales agent to start querying cadences and logging activities in Salesloft.
Search & recall
Copy the prompt
Copied
List all prospects currently in the [cadence name] cadence.
Copy the prompt
Copied
Show all email activities from the last 7 days and their reply rates.
Copy the prompt
Copied
Find all prospects at [company] and their current cadence step.
Action & enroll
Copy the prompt
Copied
Enroll [prospect name] in the [cadence name] cadence starting from step 1.
Copy the prompt
Copied
Log a call activity for [prospect name] with outcome: [outcome].
Copy the prompt
Copied
Create a new person record for [name] at [company] and enroll in [cadence].
SEE HOW AUTH WORKS
Reps authorize Salesloft once. Their OAuth token stays vaulted, every cadence action runs under their identity, and every step is logged.
1
Authorize
Your user connects
Salesloft
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
Salesloft
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
Salesloft
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
Salesloft
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
Same per-user auth pattern across other sales engagement and CRM connectors.
No items found.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
One vault for every sales engagement tool. Salesloft today, Outreach and Apollo tomorrow.
01.
Shared tokens break per-user analytics
A shared token looks fine in a demo. In production every call looks like a service account. Scalekit resolves the real user credential so attribution, audit, and scope stay accurate.
// shared token
 audit → bot_service_account
 user_filter → broken

 // scalekit
 audit → user_abc
 scope → enforced ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Salesloft today. Others 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 Salesloft as the rep or a shared service account?
As the rep. Each sales rep authorizes once via OAuth and Scalekit resolves their credential at request time. Logged calls and emails appear under that rep's Salesloft identity, not a bot account, critical for accurate activity attribution and manager visibility.
Where is the Salesloft OAuth token stored?
In Scalekit's AES-256 vault, namespaced per tenant. Refresh is automatic. Revocation is a single dashboard action. Tokens never appear in prompts, logs, or LLM completions.
Can I prevent the agent from sending emails or making calls autonomously?
Yes. Use listScopedTools to allow cadence step queries and prospect lookup without granting execution permissions. You control exactly which actions the agent can take, reads can be enabled without writes per user.
What happens when a rep revokes Salesloft access?
The connection is invalidated on the next tool call for that rep. Subsequent requests fail closed. Other reps in the team remain unaffected. The event is logged for audit.
Can the agent combine Salesloft with Salesforce or HubSpot in one workflow?
Yes. A single agent can query Salesloft for cadence status and sync results back to Salesforce or HubSpot in the same workflow. Each connector resolves under the same rep identity with its own vaulted credential.
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"": {
""salesloft"": {
""url"": ""https://mcp.scalekit.com/salesloft"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.salesloft]
url = ""https://mcp.scalekit.com/salesloft""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""salesloft"": {
""url"": ""https://mcp.scalekit.com/salesloft"",
""type"": ""http""
}
}
}