Как построить Node.js MCP-сервер для интеграции Claude-Salesforce

Как построить Node.js MCP-сервер для интеграции Claude-Salesforce

18 июня 2025 г.

Эта статья поможет вам построить простой, но функциональный сервер 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Полем


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE