Эта статья поможет вам построить простой, но функциональный сервер MCP, который интегрируется с Salesforce, позволяя настольному столу Claude напрямую запросить и взаимодействовать с вашими данными Salesforce.

Что мы собираемся построить

Мы создадим MCP-сервер на основе Node.js, который позволяет Claude:

  • Перечислите все подключенные организации Salesforce из вашего CLI Salesforce
  • Выполнить запросы SOQL через подсказки естественного языка
  • Получить и отображать данные Salesforce в разговорном формате

Полный код для этого проекта доступен наGitHubПолем

Как это выглядит:

a short demo

Что такое MCP

MCP - это протокол, разработанный Anpropic, который позволяет моделям ИИ расширять свои возможности, получая доступ к внешним системам. В нашем случае это позволяет Claude взаимодействовать с организациями Salesforce, выполнять запросы и обработать данные - на протяжении простого разговора.

Давайте построим это!

Предварительные условия

Прежде чем приступить к статье, убедитесь, что на вашем компьютере установлены следующие инструменты:

  • Клод для настольного компьютера
  • Node.js
  • Salesforce CLI

Кроме того, предполагается, что у вас есть базовый опыт работы с LLM, такими как Chatgpt, Gemini, Claude и т. Д.

Настройка проекта

Создайте папку для проекта в любом месте вашего компьютера. Давайте назваем это, например,SF-MCP-серверПолем Откройте папку в коде VS.

В коде VS открыть терминал и инициировать новый проект NPM, выполнив следующую команду:

npm init -y

Установите требуемые зависимости:

npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript

Создайте новую папку с названиемSRCВнутри корня папки проекта, которая являетсяSF-CMP-серверодин.

Создайте новый файл внутриSRCпапка называетсяindex.ts, это должно быть на этом пути./src/index.tsПолем

Создайте новый файл с названиемtsconfig.jsonВнутри корня папки проекта и заполнить ее этим кодом:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

ЕстьPackage.jsonФайл в корне папки проекта, отрегулируйте его контент, чтобы убедиться, что он содержит следующий код:

{
  "type": "module",
  "bin": {
    "sf-mcp-server": "./build/index.js"
  },
  "scripts": {
    "build": "tsc && chmod 755 build/index.js"
  },
  "files": ["build"]
}

Полный код этого файла доступен вРепозиторий GitHubПолем

К концу этой части ваша папка проекта должна иметь следующую структуру:

.
├── node_modules
├── src/
│   └── index.ts
├── package-lock.json
├── package.json
└── tsconfig.json

Кодирующая часть

Давайте начнем с импорта пакетов, которые мы собираемся использовать, и настроить сервер. Добавить следующий код в верхнюю часть.src/index.tsфайл:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Importing exec from node:child_process to execute shell commands
import { exec } from "node:child_process"; 

const server = new McpServer({
    name: "sf-mcp-server",
    version: "1.0.0",
    capabilities: {
        tools: {},
    },
});

Теперь давайте добавим код для извлечения подключенных к организациям Salesforce Orgs. Лучше создать подключенное приложение и настроить поток аутентификации, если вы планируете работать с одной организацией, но мы будем использовать подключенные организации из CLI Salesforce для простоты.

Запуститьsf org listкомандованиеВ вашем терминале и проверьте, есть ли у вас какие -либо подключенные организации. Если нет, торазрешатьОрга, которую вы можете использовать дальше.

Этот код сообщает серверу MCP, что у вас есть инструмент, который может выполнитьsf org list --jsonкомандовать в оболочке и передать результат Клоду, чтобы он мог понять, какие организации вы аутентифицировали. Добавьте этот код ниже в.src/index.tsфайл:

const listConnectedSalesforceOrgs = async () => {
    return new Promise((resolve, reject) => {
        exec("sf org list --json", (error, stdout, stderr) => {
            if (error) {
                return reject(error);
            }
            if (stderr) {
                return reject(new Error(stderr));
            }
            try {
                const result = JSON.parse(stdout);
                resolve(result);
            } catch (parseError) {
                reject(parseError);
            }
        });
    });
};

server.tool("list_connected_salesforce_orgs", {}, async () => {
    const orgList = await listConnectedSalesforceOrgs();
    return {
        content: [
            {
                type: "text",
                text: JSON.stringify(orgList, null, 2),
            },
        ],
    };
});

Большой! Следующим шагом является добавление кода для выполнения запросов SOQL в одну из подключенных организаций.

Этот код принимает схему ввода из подсказки, которую вы отправляете в ClaudtargetOrgилиfieldsзапросить и отправлять эту информациюexecuteSoqlQueryфункция, которая выполняеткоманда SF для запросов с использованием запроса SOQLПолем После того, как более поздняя функция завершится выполнение, ее результат отправляется в Клод, который анализирует результат и реагирует на вас довольно довольно.

Теперь добавьте этот код после ранее добавленного:

const executeSoqlQuery = async (
    targetOrg: string,
    sObject: string,
    fields: string,
    where?: string,
    orderBy?: string,
    limit?: number
) => {
    let query = `SELECT ${fields} FROM ${sObject}`;

    if (where) query += " WHERE " + where;
    if (limit) query += " LIMIT " + limit;
    if (orderBy) query += " ORDER BY " + orderBy;

    const sfCommand = `sf data query --target-org ${targetOrg} --query "${query}" --json`;

    return new Promise((resolve, reject) => {
        exec(sfCommand, (error, stdout, stderr) => {
            if (error) {
                return reject(error);
            }
            if (stderr) {
                return reject(new Error(stderr));
            }
            try {
                const result = JSON.parse(stdout);
                resolve(result.result.records || []);
            } catch (parseError) {
                reject(parseError);
            }
        });
    });
};

server.tool(
    "query_records",
    "Execute a SOQL query in Salesforce Org",
    {
        input: z.object({
            targetOrg: z
                .string()
                .describe("Target Salesforce Org to execute the query against"),
            sObject: z.string().describe("Salesforce SObject to query from"),
            fields: z
                .string()
                .describe("Comma-separated list of fields to retrieve"),
            where: z
                .string()
                .optional()
                .describe("Optional WHERE clause for the query"),
            orderBy: z
                .string()
                .optional()
                .describe("Optional ORDER BY clause for the query"),
            limit: z
                .number()
                .optional()
                .describe("Optional limit for the number of records returned"),
        }),
    },
    async ({ input }) => {
        const { targetOrg, sObject, fields, where, orderBy, limit } = input;
        const result = await executeSoqlQuery(
            targetOrg,
            sObject,
            fields,
            where,
            orderBy,
            limit
        );

        return {
            content: [
                {
                    type: "text",
                    text: JSON.stringify(result, null, 2),
                },
            ],
        };
    }
);

Мы закончили с кодом для базовой функциональности этого MCP -сервера, теперь давайте добавим код для инициализации сервера и настройки соединения. Добавить этот код в конце.src/index.tsфайл:

async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
    console.error("Salesforce MCP Server running on stdio");
}

main().catch((error) => {
    console.error("Fatal error in main():", error);
    process.exit(1);
});

Целый.src/index.tsФайл должен выглядеть какэтотПолем

Убедиться, что это работает

Давайте начнем тестировать сервер MCP, создав наш проект, это важный шаг, не пропускайте его. Астроитьпапка будет создана внутриSF-CMP-сервер, вдольсindex.jsФайл, который будет использоваться MCP Server. Выполнить следующую команду в вашем терминале, чтобы выполнить сборку:

npm run build

Теперь, Claude для настольного приложения должно быть настроено для работы с MCP, которое будет использоваться в качестве клиента. На вашем компьютере перейдите по пути, на котором находится файл конфигурации Claude. Создайте его, если его нет.

Для MacOS/Linux:

~/Library/Application Support/Claude/claude_desktop_config.json

Для Windows:

C:\Users\YOUR_USERNAME\AppData\Roaming\Claude\claude_desktop_config.json

Открытьclaude_desktop_config.jsonФайл в коде VS и добавьте следующий код, чтобы отобразить сервер MCP в пользовательском интерфейсе приложения для настольного приложения:

{
  "mcpServers": {
    "sf-mcp-server": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/PARENT/FOLDER/sf-mcp-server/build/index.js"]
    }
  }
}

Сохраните файл и перезапустите Claude для настольного приложения. Вы должны увидетьSF-MCP-серверВ пользовательском интерфейсе инструментов в приложении:

Попробуйте написать запрос, чтобы получить подключенные организации, например:

list connected orgs

Вы должны увидеть аналогичный результат:

Скопируйте псевдоним Org или имя пользователя и напишите следующую подсказку, чтобы фактически запросить записи, например:

query 5 account names and websites from the ORG_YOU_COPIED org

Тогда вы увидите что -то вроде этого:

Заключение

Поздравляю! Вы успешно создали сервер MCP, который подключает Claude Desktop с Salesforce. Теперь вы можете запросить данные о продажах, используя естественный язык, делая исследование данных более интуитивно понятным и эффективным.

Что мы достигли

  • Построил сервер MCP Node.js с TypeScript
  • Реализованные инструменты для перечисления орг в Salesforce и выполнения запросов SOQL
  • Настроенный рабочий стол Claude для использования пользовательского сервера
  • Протестировал интеграцию с реальными запросами

Следующие шаги

В то время как в этом уроке использовался CLI Salesforce для простоты, вы можете разблокировать полную мощность Salesforce, внедрив надлежащую аутентификацию с подключенными приложениями и непосредственно с использованием API Salesforce. Этот подход позволяет:

  • Протоки аутентификации OAuth 2.0
  • Прямой отдых, мыло и объемный API
  • Потоковая передача в реальном времени с событиями платформы
  • Metadata API для управления конфигурацией
  • Полные операции CRUD и сложная бизнес -логика

Навыки, которые вы изучили здесь, применяются к интеграции Claude с любой системой или API. Будь то создание внутренних инструментов или автоматизация рабочих процессов, MCP предоставляет прочную основу для создания опыта, способствующего AI.

Полный код для этого проекта доступен наGitHubПолем