Salesforce Hosted MCP ServersにカスタムMCPサーバーを追加してみた

Salesforce Hosted MCP ServersにカスタムMCPサーバーを追加してみた

Salesforce Hosted MCP Serversの権限スコープをもっと限定的にしたいと思い、カスタムMCPサーバーを作成・設定してClaudeから安全に操作する方法を検証してみました。
2026.06.15

Salesforce Hosted MCP Serversの各サーバーは権限のスコープが汎用的に設定されますが、AIツールによる操作をもっと限定的にしたいと思い、Build Custom MCP Serversを参照してカスタムMCPサーバーを追加してみました。

検証環境

  • macOS Tahoe バージョン 26.5
  • Claude for Mac バージョン 1.12603.1
  • Salesforce Developer Edition

事前設定

権限セット、外部クライアントアプリケーションは前回設定したものをそのまま使います。

追加するカスタムMCPサーバーの機能

今回は下記の機能を持つカスタムMCPサーバーを作成します。

  • 入力は 商談ID(必須)・メモ本文(必須)・件名・活動日・連絡先ID の5つ。
  • 商談に紐づく完了済みの活動 (ToDo / Task) を1件作成し、メモ本文を説明欄に転記する。

実装方法

カスタムMCPサーバーはフロー、Apex Invocable Actions、AuraEnabled Apex Methods、Apex REST Methodsなど様々な方法で実装ができますが、今回はApex Invocable Actionsで実装します。

Apex Invocable Actions

@InvocableMethod付きでApexクラスを作成します。
@InvocableMethod / @InvocableVariableのlabelとdescriptionはそのままMCPツールの名前・説明としてAIツールに渡るため、適切な名前と説明を記載するようにします。
また、MCPツールとして公開できるのはglobalメソッドのInvocable Actionだけになります。
下記は実際に作成したApexクラスです。

/**
 * 商談メモ(議事録)を、指定した商談に紐づく完了済みの活動(ToDo / Task)として記録するInvocable Action。
 * カスタムMCPサーバーのツールとして公開して利用する。
 */
global with sharing class LogOpportunityMeetingNote {

    global class Request {
        @InvocableVariable(label='商談ID' description='メモを紐付ける商談(Opportunity)のレコードID' required=true)
        global Id opportunityId;

        @InvocableVariable(label='メモ本文' description='活動として記録する議事録・商談メモの本文' required=true)
        global String notes;

        @InvocableVariable(label='件名' description='活動の件名。未指定の場合は「商談メモ」を使用')
        global String subject;

        @InvocableVariable(label='活動日' description='活動の日付。未指定の場合は本日')
        global Date activityDate;

        @InvocableVariable(label='関連連絡先ID' description='メモに紐付ける担当者(Contact)のレコードID(任意)')
        global Id contactId;
    }

    global class Result {
        @InvocableVariable(label='作成された活動ID' description='登録された活動(Task)のレコードID')
        global Id taskId;
    }

    @InvocableMethod(
        label='商談メモを活動として記録'
        description='議事録・商談メモを、指定した商談に紐づく完了済みの活動(ToDo)として記録します。'
    )
    global static List<Result> logMeetingNotes(List<Request> requests) {
        // 組織のロケール("完了"/"Completed" 等)に依存しないよう、
        // クローズ扱いの状況(Status)を動的に取得する。
        String completedStatus;
        for (TaskStatus ts : [
            SELECT MasterLabel, IsClosed, IsDefault
            FROM TaskStatus
            WHERE IsClosed = true
            ORDER BY IsDefault DESC, SortOrder ASC
        ]) {
            completedStatus = ts.MasterLabel;
            break;
        }

        List<Task> tasks = new List<Task>();
        for (Request req : requests) {
            tasks.add(new Task(
                WhatId       = req.opportunityId,
                WhoId        = req.contactId,
                Subject      = String.isBlank(req.subject) ? '商談メモ' : req.subject,
                Description  = req.notes,
                ActivityDate = (req.activityDate == null) ? Date.today() : req.activityDate,
                Status       = completedStatus
            ));
        }
        insert tasks;

        List<Result> results = new List<Result>();
        for (Task t : tasks) {
            Result r = new Result();
            r.taskId = t.Id;
            results.add(r);
        }
        return results;
    }
}

カスタムMCPサーバーの追加

設定 -> インテグレーション -> API カタログ -> MCP サーバー から 「Add MCP Server」をクリックし、「Salesforce MCP サーバーを作成」をクリックします。
Add MCP Server > Salesforce MCP サーバーを作成
「表示ラベル」、「名前」、「説明」を入力し、「作成」をクリックします。
カスタムMCPサーバー作成
なお、「名前」に入力した値はサーバーURL末尾に使用されます。

カスタムMCPサーバーが追加されました。
次に「サーバーアセットを追加」から「ツールを追加」をクリックします。
サーバーアセットを追加 > ツールを追加

ツールを追加する画面が表示されるので、左のリストビューから「Apex アクション」をクリックします。
リストビュー > Apex アクション

作成したApex アクションである「商談メモを活動として記録」が表示されるので、選択して右上の「+ ツールを追加」をクリックします。
Apexアクションを選択 > ツールを追加

表示が追加済みに変わったことを確認し右下の「保存」をクリックします。
追加済みに変わったことを確認 > 保存

カスタムMCPサーバーのツールタブを表示すると、追加したツールが表示されています。
ツールタブ

有効化をクリックします。カスタムMCPサーバーが有効化されサーバー状況が稼働中になったことを確認します。
カスタムMCPサーバーを有効化する

カスタムMCPサーバーの有効化が完了したら、サーバーURLを控えておきます。
サーバーURL: https://api.salesforce.com/platform/mcp/v1/custom/SfOpportunityNotes
サーバーURL

Claude / claude.aiでの設定

カスタムコネクタを追加する

カスタマイズ > コネクタ > + をクリックし、「•••カスタムコネクタを追加」を選択します。
下記項目を入力し、「追加」をクリックします。

  • 名前:
    • SfOpportunityNotes(※日本語の名前だとツールがうまく実行されなかったため英語にしておくのが無難そうです)
  • リモートMCPサーバーURL:
    • https://api.salesforce.com/platform/mcp/v1/custom/SfOpportunityNotes(上で控えたURLを入力します)
  • OAuth ClientID (任意):
    • 外部クライアントアプリケーションのコンシューマー鍵を入力します
      カスタムコネクタを追加

Salesforceと接続する

カスタムコネクタを追加した時点ではSalesforceと接続されていないので、「連携/連携させる」をクリックします。
連携/連携させる

ブラウザのSalesforceのログイン画面に遷移するのでログインすると、カスタムコネクタが使用できる状態になりました。
連携されたカスタムコネクタ

動作確認

サンプルの議事録として下記の内容のテキストファイルを用意します。

ミーティング実施日: 2026/05/31
タイトル: Hosted MCP ServersにカスタムMCPサーバーを追加してみた件
内容: 検証用にHosted MCP ServersにカスタムMCPサーバーを追加して色々とゴニョゴニョしてみたよ

チャットから議事録のテキストファイルを添付し、下記プロンプトを実行します。

カスタムコネクタのSfOpportunityNotesを使ってSalesforceのレコードID: 006fj000009riFRAAYの商談に議事録を追加してください

実行結果です。登録に成功したようです。
実行結果

Salesforceの画面からも登録されていることが確認できました。
議事録ファイルの中身から期日、件名、コメントも登録されています。  
スクリーンショット 2026-06-15 17.10.26

まとめ

Salesforce Hosted MCP ServersにカスタムMCPサーバーを追加し、Claudeから安全に操作を実行する方法を検証しました。
今回Claudeに行わせた「商談への活動記録」という操作自体は、標準の sobject-all や sobject-mutations でも実行可能です。しかし、これらの標準サーバーはオブジェクトごとに操作を制限できないため、意図しないオブジェクトに対してAIツールが予期せぬ操作を行ってしまう(AIインシデント)リスクがあります。
カスタムMCPサーバーであれば、Apex Invocable Actionsなどで「何ができるか」を明示的に定義できるため、AIツールに与える権限を必要最小限に絞り込むことができます。AIツールを業務で安全に活用していくうえで、こうしたスコープの限定は重要な選択肢になりそうです。


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

この記事をシェアする

関連記事