Salesforce CRM命令行工具

一个专为CRM数据操作和AI代理集成设计的JSON优先命令行工具,支持Salesforce REST API的102个命令。

  • by bcharleson
  • TypeScript
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 bcharleson/salesforce-crm-cli

使用说明

salesforce客户关系管理客户端

用于Salesforce REST API的JSON-第一个CLI和MCP服务器-专为人类和人工智能代理构建。

20个命令组中的102个命令。 每个命令都可以作为CLI子命令和MCP工具使用——定义一次,在任何地方注册。

npm install -g salesforce-crm-cli
salesforce --help

这是什么

Salesforce官方CLI(sf/sfdx)是一个用于部署Apex代码、管理组织和CI/CD的开发人员工具链。 这是不同的。

salesforce-crm-cli 是专门为 CRM数据操作和AI代理集成:

  • 通过SOQL/SOSL查询客户、联系人、潜在客户、机会
  • 创建、更新、删除任何Salesforce记录
  • 为大量数据操作运行批量API 2.0作业
  • 在单个API调用中执行复合请求和记录树
  • 运行匿名Apex并调用Apex REST端点
  • 将每个命令作为MCP工具公开给Claude、Cursor和其他AI代理

所有输出均为JSON格式。无旋转器、无提示、无噪音——针对管道和试剂消耗进行了优化。


快速开始

安装

npm install -g salesforce-crm-cli

验证

选项A——访问令牌(最快)

salesforce login \
  --access-token <your_token> \
  --instance-url https://yourorg.salesforce.com

选项B——OAuth用户名/密码流

salesforce login \
  --client-id <connected_app_consumer_key> \
  --username <you@yourorg.com> \
  --password <password+security_token>

选项C——环境变量

export SALESFORCE_ACCESS_TOKEN="your_token"
export SALESFORCE_INSTANCE_URL="https://yourorg.salesforce.com"
salesforce status

验证

salesforce status        # Show current auth info
salesforce limits get    # Check API limits for your org

验证安装和升级

安装或升级后确认CLI版本与npm匹配:

npm view salesforce-crm-cli version   # latest on npm
salesforce --version                  # should match
which salesforce                      # path to the active binary

部署说明: 如果使用自定义包装器脚本,请不要硬编码项目本地路径 node_modules/ 复制——这可能会让你在使用旧版本的同时 npm install -g 其他地方的更新。更喜欢全局二进制(which salesforce), npx salesforce-crm-cli,或动态解析:

node "$(npm root -g)/salesforce-crm-cli/dist/index.js" --version

要升级,请执行以下操作:

npm install -g salesforce-crm-cli@latest

认证

身份验证按优先级顺序解决:

优先级 方法 如何
1(最高) CLI标志 --access-token, --instance-url
2 环境变量 SALESFORCE_ACCESS_TOKEN + SALESFORCE_INSTANCE_URL (或 SF_ACCESS_TOKEN + SF_INSTANCE_URL)
3 存储的配置 ~/.salesforce-cli/config.json (由设定 salesforce login)

命令组

核心CRM对象

每个对象有7个命令: list, get, create, update, delete, search, describe

组 Salesforce对象 关键字段
accounts 账户 姓名、类型、行业、电话、网站、员工人数
contacts 联系人 名字、姓氏、电子邮件、电话、职务、账号
leads Lead 名字、姓氏、公司、电子邮件、状态、LeadSource
opportunities 机会 名称、阶段名称、金额、结束日期、帐户ID
cases 案例 主题、状态、优先级、来源、联系人ID、帐户ID
tasks 任务 主题、状态、优先级、活动日期、WhoId、WhatId
events 事件 主题、开始日期时间、结束日期时间、位置、WhoId
campaigns 活动 名称、类型、状态、开始日期、结束日期、预算成本
users user 用户名、姓名、电子邮件、保存、个人资料ID
# Examples
salesforce accounts list --limit 10 --pretty
salesforce contacts get 003xx000004TNEAAA4
salesforce leads create --first-name "Jane" --last-name "Doe" --company "Acme" --email "jane@acme.com"
salesforce opportunities update 006xx000001TNEAAA4 --stage "Closed Won" --amount "75000"
salesforce accounts describe --pretty

组织兼容性: 默认 list 和 search --where 字段避免使用特定于版本的列(例如。 AnnualRevenue 不在默认设置中——在某些专业版组织上不可用)。使用 --fields 请求特定栏目,或 describe 看看你的组织支持什么。 AnnualRevenue 仍可通过创建/更新 --annual-revenue 当你的组织拥有该字段时。

查询和搜索

# SOQL
salesforce query run --soql "SELECT Id, Name, Amount FROM Opportunity WHERE StageName = 'Prospecting'"
salesforce query explain --soql "SELECT Id FROM Lead WHERE CreatedDate = TODAY"
salesforce query more --url "/services/data/v62.0/query/01gxx000000..."

# SOSL
salesforce search run --sosl "FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name)"
salesforce search suggest --text "Acme" --sobject Account

通用对象操作

使用任何SObject类型,包括自定义对象(CustomObject__c):

salesforce sobjects list                                    # All SObject types in org
salesforce sobjects describe CustomObject__c               # Full metadata + field list
salesforce sobjects get CustomObject__c a00xx000000001AAA  # Get by record ID
salesforce sobjects create CustomObject__c --data '{"Name":"Test","Custom_Field__c":"value"}'
salesforce sobjects update CustomObject__c a00xx000000001AAA --data '{"Custom_Field__c":"updated"}'
salesforce sobjects delete CustomObject__c a00xx000000001AAA
salesforce sobjects upsert CustomObject__c --external-field "External_Id__c" --external-value "EXT-001" --data '{"Name":"Test"}'

散装API 2.0

对于海量数据操作(200+条记录):

# Create an ingest job
salesforce bulk ingest-create --sobject Account --operation insert

# Upload CSV (inline or from file)
salesforce bulk ingest-upload --job-id 7500x000000xxxxAAA \
  --csv "Name,Industry\nAcme Corp,Technology\nGlobex Inc,Finance"

salesforce bulk ingest-upload --job-id 7500x000000xxxxAAA \
  --csv-file ./accounts.csv

# Process the job
salesforce bulk ingest-close --job-id 7500x000000xxxxAAA

# Monitor
salesforce bulk ingest-status --job-id 7500x000000xxxxAAA
salesforce bulk ingest-results --job-id 7500x000000xxxxAAA --type successful

# Bulk query
salesforce bulk query-create --soql "SELECT Id, Name FROM Account"
salesforce bulk query-status --job-id 7500x000000xxxxAAA
salesforce bulk query-results --job-id 7500x000000xxxxAAA

复合API

单个HTTP请求中有多个API调用:

# Composite — supports cross-request references
salesforce composite run --requests '[
  {"method":"POST","url":"/services/data/v62.0/sobjects/Account","referenceId":"newAccount","body":{"Name":"Acme Corp"}},
  {"method":"POST","url":"/services/data/v62.0/sobjects/Contact","referenceId":"newContact","body":{"LastName":"Smith","AccountId":"@{newAccount.id}"}}
]'

# Batch — independent requests
salesforce composite batch --requests '[
  {"method":"GET","url":"/services/data/v62.0/sobjects/Account/001xx000003GYQ"},
  {"method":"GET","url":"/services/data/v62.0/sobjects/Contact/003xx000004TNE"}
]'

# Tree — parent + children in one call
salesforce composite tree --sobject Account --records '[
  {"attributes":{"type":"Account"},"Name":"Parent Corp","Contacts":{"records":[
    {"attributes":{"type":"Contact"},"LastName":"Smith"}
  ]}}
]'

# Collections — up to 200 records in one call
salesforce composite collection --method create --records '[
  {"attributes":{"type":"Lead"},"LastName":"Jones","Company":"ACME"},
  {"attributes":{"type":"Lead"},"LastName":"Brown","Company":"Globex"}
]'

报告和仪表板

salesforce reports list --pretty
salesforce reports get 00Oxx0000001AAAAAA          # metadata / describe
salesforce reports run 00Oxx0000001AAAAAA --pretty   # no --filters needed
salesforce reports run 00Oxx0000001AAAAAA \
  --filters '[{"column":"ACCOUNT_NAME","operator":"contains","value":"Acme"}]'
salesforce reports dashboards-list
salesforce reports dashboards-get 01Zxx0000001AAAAAA

注: reports run 没有 --filters 使用GET请求并使用其保存的元数据运行报告。通过 --filters 当您需要运行时过滤器覆盖时。

顶点

版本要求: apex execute, apex test-run,以及相关的Apex工具需要一个启用了Apex的Salesforce组织(开发人员、企业、无限等)。专业版组织回归 “此组织未启用Apex编译” --这是一个组织限制,而不是CLI错误。

# Execute anonymous Apex
salesforce apex execute --code "System.debug('Hello World');"

# Call custom Apex REST endpoint
salesforce apex rest --path "/MyEndpoint/action" --method POST --body '{"key":"value"}'

# Run tests
salesforce apex test-run --class-ids "01pxx000000001AAA,01pxx000000002AAA"
salesforce apex test-results --run-id 707xx0000000001AAA

限制和元数据

salesforce limits get --pretty         # API limits and current usage
salesforce limits versions             # All supported API versions
salesforce limits resources            # All available REST resources

输出标志

所有命令都输出JSON。通过以下方式控制格式:

标志 描述
--pretty 漂亮的带缩进的JSON打印
--quiet 抑制输出(仅退出代码)
--fields <fields> 选择特定字段(逗号分隔)
--output <format> json (默认)或 pretty

全局选项

每个命令都可用:

标志 描述
--access-token <token> 覆盖已存储的访问令牌
--instance-url <url> 覆盖存储的实例URL
--api-version <version> API版本(默认: v62.0)
--pretty 漂亮的打印JSON输出
--quiet 抑制所有输出
--fields <fields> 选择特定的响应字段

MCP服务器设置

使用 salesforce-crm-cli 作为MCP服务器,为AI代理(Claude、Cursor等)提供Salesforce的直接访问权限。

克劳德桌面版

添加 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "salesforce": {
      "command": "npx",
      "args": ["salesforce-crm-cli", "mcp"],
      "env": {
        "SALESFORCE_ACCESS_TOKEN": "your-token-here",
        "SALESFORCE_INSTANCE_URL": "https://yourorg.salesforce.com"
      }
    }
  }
}

光标/VS代码

添加 .cursor/mcp.json 或 .vscode/mcp.json 在您的项目中:

{
  "mcpServers": {
    "salesforce": {
      "command": "npx",
      "args": ["salesforce-crm-cli", "mcp"],
      "env": {
        "SALESFORCE_ACCESS_TOKEN": "your-token-here",
        "SALESFORCE_INSTANCE_URL": "https://yourorg.salesforce.com"
      }
    }
  }
}

使用全局安装

如果全局安装(npm install -g salesforce-crm-cli):

{
  "mcpServers": {
    "salesforce": {
      "command": "salesforce",
      "args": ["mcp"],
      "env": {
        "SALESFORCE_ACCESS_TOKEN": "your-token-here",
        "SALESFORCE_INSTANCE_URL": "https://yourorg.salesforce.com"
      }
    }
  }
}

一旦连接,所有102个命令都可以作为MCP工具使用。代理可以查询帐户、创建潜在客户、运行SOQL、触发Apex等,所有这些都可以对每个输入进行完整的类型验证。


常见工作流

查找帐户及其所有联系人

# Search by name
salesforce accounts search --where "Name LIKE '%Acme%'"

# Get all contacts for that account
salesforce contacts list --where "AccountId = '001xx000003GYQIAA4'"

通向机会管道

# Create a lead
salesforce leads create --first-name "Jane" --last-name "Doe" \
  --company "Acme Corp" --email "jane@acme.com" --source "Web"

# Convert by creating opportunity
salesforce opportunities create --name "Acme Corp — Enterprise" \
  --stage "Prospecting" --close-date "2026-06-30" \
  --amount "75000" --account-id "001xx000003GYQIAA4"

# Create a follow-up task
salesforce tasks create --subject "Discovery call with Jane" \
  --due-date "2026-04-01" --priority "High" \
  --what-id "<opportunity_id>"

从CSV批量导入联系人

salesforce bulk ingest-create --sobject Contact --operation insert
salesforce bulk ingest-upload --job-id <JOB_ID> \
  --csv "FirstName,LastName,Email,AccountId\nJane,Doe,jane@acme.com,001xx000003GYQ\nJohn,Smith,john@globex.com,001xx000003GYR"
salesforce bulk ingest-close --job-id <JOB_ID>
salesforce bulk ingest-status --job-id <JOB_ID>

复杂SOQL分析

# Opportunities by stage with totals
salesforce query run --soql \
  "SELECT StageName, COUNT(Id) Total, SUM(Amount) TotalAmount \
   FROM Opportunity \
   WHERE CloseDate = THIS_QUARTER \
   GROUP BY StageName \
   ORDER BY SUM(Amount) DESC" --pretty

# Accounts with 5+ contacts
salesforce query run --soql \
  "SELECT Account.Name, COUNT(Id) ContactCount \
   FROM Contact \
   GROUP BY Account.Name \
   HAVING COUNT(Id) >= 5 \
   ORDER BY COUNT(Id) DESC \
   LIMIT 20"

描述自定义对象

salesforce sobjects describe MyCustomObject__c --pretty
# Returns all fields, types, picklist values, relationships, and metadata

建筑

src/
├── index.ts              # CLI entry point (Commander.js)
├── mcp.ts                # MCP server entry point
├── core/
│   ├── types.ts          # CommandDefinition — single source of truth
│   ├── client.ts         # HTTP client (retry, rate-limit, timeout)
│   ├── auth.ts           # Token + instance URL resolution
│   ├── config.ts         # ~/.salesforce-cli/config.json
│   ├── errors.ts         # Error hierarchy
│   ├── handler.ts        # Command → HTTP executor
│   └── output.ts         # JSON output formatting
├── factories/
│   └── sobject.ts        # Generates 7 commands per SObject type
├── commands/             # 20 command groups
│   ├── accounts/
│   ├── contacts/
│   ├── leads/
│   └── ...
└── mcp/
    └── server.ts         # Registers all commands as MCP tools

关键设计原则: 每个命令都被定义为 CommandDefinition 并自动注册为CLI子命令和MCP工具。添加命令组需要在中创建一个文件和一行 commands/index.ts.


添加自定义SObject命令

创建 src/commands/your-object/index.ts:

import { createSObjectCommands } from '../../factories/sobject.js';

export const allYourObjectCommands = createSObjectCommands({
  objectType: 'YourObject__c',
  group: 'your-object',
  singular: 'your object',
  defaultFields: ['Id', 'Name', 'CreatedDate'],
  writeProperties: [
    { field: 'Name', flags: '-n, --name <name>', description: 'Name', required: true },
    { field: 'Custom_Field__c', flags: '--custom-field <value>', description: 'Custom field' },
  ],
});

然后添加到 src/commands/index.ts:

import { allYourObjectCommands } from './your-object/index.js';
// ...
export const allCommands: CommandDefinition[] = [
  ...allYourObjectCommands,
  // rest of commands
];

这给了你 list, get, create, update, delete, search,以及 describe 自动为您的对象。


发展

git clone https://github.com/bcharleson/salesforce-crm-cli
cd salesforce-crm-cli
npm install

# Run in dev mode
npm run dev -- accounts list --pretty

# Type check
npm run typecheck

# Build
npm run build

# Test
npm test

SOQL快速参考

-- Basic
SELECT Id, Name FROM Account WHERE Industry = 'Technology' LIMIT 10

-- Date literals (no quotes needed)
SELECT Id FROM Lead WHERE CreatedDate = TODAY
SELECT Id FROM Opportunity WHERE CloseDate = THIS_QUARTER
SELECT Id FROM Task WHERE ActivityDate = LAST_N_DAYS:7

-- Relationships (dot notation)
SELECT Account.Name, LastName, Email FROM Contact WHERE Account.Industry = 'Finance'

-- Aggregates
SELECT StageName, COUNT(Id), SUM(Amount) FROM Opportunity GROUP BY StageName

-- Subqueries
SELECT Name, (SELECT LastName, Email FROM Contacts) FROM Account WHERE AnnualRevenue > 1000000

-- IN / NOT IN
SELECT Id FROM Contact WHERE AccountId IN (SELECT Id FROM Account WHERE Industry = 'Tech')

技术栈

  • TypeScript (ESM,严格模式)
  • 指挥官js 14 --CLI框架
  • 佐德3 --所有命令的输入验证
  • @模型上下文协议/sdk --MCP服务器
  • tsup --建造, TSX --dev, 测试 --测试
  • 节点18+

更新日志

0.1.4

  • 修复: accounts list 和 accounts search --where --已删除 AnnualRevenue 来自默认列表字段(并非所有组织版本都提供)
  • 修复: reports run 没有 --filters --使用GET而不是空正文的POST
  • 添加: 通过刷新令牌+连接的应用程序凭据提供令牌刷新支持
  • 添加: 主控程序 salesforce_login, salesforce_logout,以及 salesforce_status 诊断工具
  • 添加: bulk ingest-upload --csv-file <path> 用于基于文件的CSV上传

许可证

麻省理工学院-- 布兰登·查尔森