Copper MCP server for AI agents

Live

API KEY

CRM

CRM & Sales

Copper gives your agent CRM operations in each user's Copper account: search and update leads, people, companies, and opportunities, log activities, manage tasks and projects, and convert leads.

  • Per-user credentials: each call uses the actual user's API key, 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.
Copper
agent · Acme Q3
Run
Which opportunities in the Sales pipeline close this month?
S
copper_opportunities_search
119ms
Sales agent
5 opportunities in the Sales pipeline close this month, worth $184,000 in total. The largest is Northwind Renewal at $62,000.
Sources: Copper opportunities, 5 records
copper
5 opportunities
18:29
Message Claude...

Tools your sales agent reaches for on Copper, scoped per user.

CALL ANY TOOL
69 tools for CRM in Copper: search, create, and update leads, people, companies, and opportunities, log activities, manage tasks and projects, and link related records.
copper_account_get
Get account
Get details of the Copper account the API key belongs to. Returns the account id, name, primary timezone and settings such as whether leads and team permissions are enabled. Use it to check the connection or read account settings. Use copper_current_user_get for the API user.
Parameters
Name
Type
Required
Description
—
No parameters required
copper_activities_search
Search activities
copper_activity_create
Create activity
copper_activity_delete
Delete activity
copper_activity_types_list
List activity types
copper_activity_update
Update activity
copper_company_get
Get company
copper_connect_field_link_create
Create connect field link
copper_connect_field_link_delete
Delete connect field link
copper_contact_types_list
List contact types
copper_custom_activity_type_get
Get custom activity type
copper_customer_sources_list
List customer sources
copper_field_layout_get
Get field layout
copper_lead_convert
Convert lead
copper_lead_delete
Delete lead
copper_lead_get
Get lead
copper_lead_statuses_list
List lead statuses
copper_lead_update
Update lead
copper_lead_upsert
Upsert lead
copper_leads_search
Search leads
copper_people_search
Search people
copper_person_create
Create person
copper_person_delete
Delete person
copper_person_get
Get person
copper_person_update
Update person
copper_pipeline_stages_in_pipeline_list
List pipeline stages in pipeline
copper_project_get
Get project
copper_related_item_add
Add related item
copper_related_item_remove
Remove related item
copper_related_items_by_type_list
List related items by type

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

// Copper tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["copper"], toolNames: [
    "copper_opportunities_search",
    "copper_opportunity_update",
    "copper_activity_create"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Move Northwind Renewal to Negotiation and log today's call" }] });
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: ["copper"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Move Northwind Renewal to Negotiation and log today's call" }],
  tools,
});

// Execute the tool call with the user's vaulted Copper API key
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: ["copper"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Move Northwind Renewal to Negotiation and log today's call" }],
  tools,
});

// Tool call runs with the user's vaulted Copper API key
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: ["copper"] }, pageSize: 100,
});

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

await agent.run("Move Northwind Renewal to Negotiation and log today's call");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Copper tool. Click to copy, paste into your agent, done.
Pipeline
Copy the prompt
Copied
List open opportunities in the Sales pipeline closing this month.
Copy the prompt
Copied
Move the Northwind Renewal opportunity to Negotiation.
Copy the prompt
Copied
Create an opportunity for Acme Corp worth $40,000.
Leads and contacts
Copy the prompt
Copied
Find the person with the email jane@northwind.com.
Copy the prompt
Copied
Convert the lead Priya Shah into a person with a new opportunity.
Copy the prompt
Copied
Create a lead for Sam Ortiz from the webinar.
Activity and tasks
Copy the prompt
Copied
Log a call note on Acme Corp from today's check-in.
Copy the prompt
Copied
Create a follow-up task for the Northwind Renewal due Friday.
Copy the prompt
Copied
Show the last 10 activities on Northwind.
SEE HOW AUTH WORKS
Each user connects their own Copper API key once, and Scalekit sends it with every call. Keys stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Copper
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
Copper
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
Copper
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
Copper
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 CRM and sales connectors.
GTM and RevOps Teams
CRM AI agent
Reads the Granola transcript after every call, extracts next steps and updates the HubSpot record, drafts the follow-up in Gmail, and confirms in Slack, all on the rep's own delegated OAuth.
GTM and RevOps Teams
Deal intelligence agent
Pulls recent Gong calls, scores deal risk with an LLM, cross-references the record in Attio, and DMs each owner their at-risk deals in Slack. Every read is scoped to that rep's own access.
GTM and RevOps Teams
Sales call prep agent
Reads tomorrow's calls from Google Calendar, mines past Granola notes and Attio history for context, and delivers each rep a prep brief in Slack, scoped to the calls that rep actually owns.
Test other agents
See the same per-user auth pattern across other CRM and sales connectors.
GTM
CRM AI agent
Turn each Granola call transcript into a HubSpot record update, a drafted Gmail follow-up, and a Slack recap.
SALES
Deal intelligence agent
Score Gong call risk with an LLM, cross-reference the Attio record, and DM each owner their at-risk deals in Slack.
SALES
Sales call prep agent
Read tomorrow's calls from Google Calendar, mine Granola notes and Attio history, and deliver each rep a prep brief in Slack.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Copper API key looks fine in a demo. In production every record change 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 key
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Copper 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 Copper as the user or through a shared key?
As the user. Each user connects their own Copper API key once, and Scalekit sends it with every call. Audit logs attribute every record change and logged activity to that user, not a shared service account.
Where is the Copper API key stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. To rotate it, the user reconnects with a new API key. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Copper?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example search and logging tools without copper_company_delete or copper_opportunity_delete, which permanently delete records. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Copper 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.
Can the agent work with custom fields in Copper?
Yes. copper_custom_field_definitions_list returns the custom field definitions in the account, and copper_field_layout_get shows which standard and custom fields appear on each record type. copper_lead_upsert can match a lead by name, email, or a custom field.
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"": {
""copper"": {
""url"": ""https://mcp.scalekit.com/copper"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.copper]
url = ""https://mcp.scalekit.com/copper""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""copper"": {
""url"": ""https://mcp.scalekit.com/copper"",
""type"": ""http""
}
}
}