業務SaaS MCP連携ガイド — ConnectorなしでClaudeに繋ぐ自作手順
公式ConnectorもMCPサーバーも無い業務SaaSは、REST APIを自作MCPサーバーでラップしてClaudeに繋ぎます。認証設計からInspectorでの検証、配布までの手順です。
Connectorが無い業務SaaSをMCPで繋ぐ方法
業務で日常的に使うSaaSの多くはWeb APIだけを公開し、公式のMCPサーバーやConnectorディレクトリへの掲載を持ちません。freeeやkintoneのようにベンダー自身がMCPサーバーを配布している例は、まだ一部にとどまります。公式の連携が無いSaaSをClaudeから直接操作するには、そのREST APIをMCPサーバーでラップし、claude mcp addかカスタムConnectorとして登録する経路が現実的です。
本記事はこの「既存REST APIをMCPサーバー化する」作業に絞ります。MCPのプロトコル自体の仕組みやtool・resource・promptの定義構文はMCPサーバー自作ガイドに譲り、本記事では業務SaaS特有の認証設計とエラー処理を中心に扱います。
前提: 対象SaaSのAPI仕様を確認する
着手前に、対象SaaSの開発者向けドキュメントで次の3点を確認します。認証方式(APIキー・OAuth2のクライアントクレデンシャル・OAuth2の認可コード)、レート制限の有無と上限、そしてAPIキー発行に管理者権限が必要かどうかです。多くの国内業務SaaSは管理画面から発行するAPIキーをヘッダーに付ける方式か、OAuth2のクライアントクレデンシャル方式のどちらかを採用しています。認可コード方式(ユーザーごとのログインを伴う方式)を採用しているSaaSは、MCPサーバー側でもOAuthフローの実装が必要になり難度が上がります。
手順1: 呼び出す操作を絞り込む
業務SaaSのAPIは数十から数百のエンドポイントを持つことがありますが、全部をツール化する必要はありません。実際にClaudeに任せたい作業から逆算し、最初は3〜5個の操作に絞ります。典型的には「一覧取得」「詳細取得」「新規作成」の3種類があれば、日常的な問い合わせと定型作業の大半をカバーできます。エンドポイントを絞ることは、後述するツール出力のトークン消費を抑える意味でも有効です。
手順2: 認証ヘッダーをMCPサーバー内に隠す
APIキーをClaude側の設定ファイルに直接書かず、MCPサーバーの環境変数として渡し、サーバー内部でリクエストヘッダーに組み込む設計にします。TypeScript SDKでの最小構成は次の形です。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const API_BASE = "https://api.example-saas.jp/v1";
const API_KEY = process.env.SAAS_API_KEY;
const server = new McpServer({ name: "saas-connector", version: "0.1.0" });
server.registerTool(
"list-requests",
{
title: "申請一覧の取得",
description: "指定した期間の申請データを一覧取得する",
inputSchema: {
from: z.string().describe("開始日(YYYY-MM-DD)"),
to: z.string().describe("終了日(YYYY-MM-DD)"),
},
},
async ({ from, to }) => {
const res = await fetch(`${API_BASE}/requests?from=${from}&to=${to}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
if (!res.ok) {
return {
content: [{ type: "text", text: `APIエラー: ${res.status} ${await res.text()}` }],
isError: true,
};
}
const data = await res.json();
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
},
);
await server.connect(new StdioServerTransport());APIキーはコードに埋め込まず、claude mcp add時の--envか.mcp.jsonの${VAR}展開で渡します。エラー時は例外を投げて落とすのではなく、isError: trueのツール結果として返すと、Claudeがエラー内容を読んで次の対応を判断できます。
手順3: ページネーションとレート制限に対応する
業務SaaSのAPIは1回のリクエストで返す件数に上限があり、超えると次ページ取得用のカーソルやトークンが返る設計が一般的です。ツール側で全ページを自動で辿って結合すると便利ですが、件数が多いAPIではツール出力がClaude Codeの既定の警告閾値(約10,000トークン)を超えて警告が出ます。取得件数に上限を設ける、必要な列だけに絞って返す、集計はサーバー側で済ませてから返す、のいずれかで出力量を抑えます。
レート制限(429エラー)を返すAPIでは、単純な再試行ではなくRetry-Afterヘッダーを尊重した待機を入れます。実装しないまま連続でツールを呼ばせると、正常なリクエストまで拒否され続ける事態になります。
手順4: Inspectorで検証して登録する
実装したサーバーは、Claude Codeにつなぐ前にMCP Inspectorで動作確認します。
npx @modelcontextprotocol/inspector npx tsx src/server.tsInspectorのToolsタブから実際の期間を入れてlist-requestsを呼び、APIキーが正しくヘッダーに載っているか、エラー時の応答が期待通りかを確認します。問題なければClaude Codeに登録します。
claude mcp add --env SAAS_API_KEY=your-key --transport stdio saas-connector \
-- npx tsx /absolute/path/to/saas-connector/src/server.tsチームで使わないローカル専用サーバーであれば、これで完了です。Claude.aiのチャットや他のプロジェクトからも使いたい場合は、HTTPトランスポートに書き換えてリモートで動かし、claude.aiの「Customize」→「Connectors」からカスタムConnectorとして追加する経路もあります。追加手順はClaude Connectorsとはにまとめています。
手順5: チームに配布する
--scope projectで登録すると、設定はリポジトリ直下の.mcp.jsonに書き込まれます。これをコミットして共有すれば、クローンした全員が同じサーバー定義を使えます。APIキーは.mcp.jsonに直書きせず、${SAAS_API_KEY}のような環境変数展開にしておき、各自のローカル環境変数として設定してもらう運用にします。.mcp.jsonはプロジェクトを開いた初回に承認ダイアログが出るため、未承認のまま勝手に接続されることはありません。
手順6: ツールに渡す権限を必要最小限に絞る
APIキーやOAuthのクライアントには、たいてい複数のスコープ(読み取り・書き込み・削除など)を選べます。MCPサーバーに発行するキーは、実装したツールが実際に使う範囲だけに絞り込みます。一覧取得と詳細取得しかツール化していないのに、書き込み・削除まで含む広いスコープのキーを使うと、Claudeが誤って(あるいはプロンプトインジェクションの結果として)意図しない操作を実行するリスクが上がります。
削除や送信のような取り返しのつかない操作をツール化する場合は、実行前に確認を挟む設計も検討します。MCPサーバー側でツールの説明文に「破壊的な操作である」旨を明記しておくと、Claudeも実行前に一呼吸置いた判断をしやすくなります。社内API呼び出しの許可リスト設計は、Hooksでコマンド実行を制限する考え方と共通する部分が多く、Hooks実例カタログのコマンド検証レシピが参考になります。
自作するか、既製の連携で足りるか
すべてのSaaS連携を自作MCPサーバーで解決する必要はありません。判断の軸は「会話の中でデータを参照・分析したいか」「決まったトリガーで機械的に処理を流したいか」です。SalesforceやHubSpot、monday.comのような営業系SaaSは、自作MCPを組む前にベンダー提供の接続経路が既にあることが多く、Claude営業連携ガイドで接続経路とプラン条件を先に確認しておくと無駄な実装を避けられます。
| やりたいこと | 向いている手段 |
|---|---|
| Claudeとの会話の中でSaaSのデータを参照・分析したい | 向いている手段自作MCPサーバー |
| SaaS間でデータを定期的に転記・同期したい | 向いている手段Zapier・Makeのような自動化ツール |
| 対応済みの操作をノーコードで組みたい | 向いている手段Zapier・MakeのMCP対応機能 |
| APIに無い独自ロジックを挟みたい | 向いている手段自作MCPサーバー |
ZapierやMakeを挟む選択肢との具体的な使い分けはZapier MCP使い分けガイドで扱っています。すでに自社がZapierやMakeを契約しているなら、まずそちらのMCP対応で足りないかを確認してから自作に進むと、開発と保守のコストを避けられます。
よくあるつまずき
OAuthトークンの期限切れで急に失敗する
クライアントクレデンシャル方式のトークンには有効期限があります。起動時に一度取得したトークンをそのまま使い続けるサーバーは、数時間後に401エラーで失敗し始めます。トークンの有効期限を見てリフレッシュする処理を、最初から組み込んでおきます。
--の区切りを忘れてコマンドが渡らない
claude mcp addでサーバー起動コマンドを指定する際、オプションと起動コマンドの間に--を挟み忘れると、起動コマンドの引数がすべてclaude mcp add自身のオプションとして解釈され、登録に失敗したり意図しないサーバーが起動したりします。手順4の例のように-- npx tsx ...の形で区切りを明示します。
--envを付け忘れて401になる
claude mcp add実行時に--env SAAS_API_KEY=your-keyを指定し忘れると、サーバー内部でprocess.env.SAAS_API_KEYがundefinedのまま起動し、APIへのリクエストは認証ヘッダーが空の状態で送られます。結果として全ツール呼び出しが401エラーで失敗します。エラーメッセージだけを見るとAPIキー自体が無効に見えるため、まず環境変数が渡っているかを疑います。
.mcp.jsonの承認ダイアログを見落とす
--scope projectで登録したサーバーは、プロジェクトを開いた初回に承認ダイアログが出ます。ここで見落として拒否したままにすると、.mcp.jsonにサーバー定義は存在するのにツールが一覧に出てこない状態になり、設定ミスと勘違いしやすくなります。ツールが見えない場合は、まず承認状態を確認します。
stdioの標準出力を汚してプロトコルが壊れる
stdioトランスポートはMCPのメッセージを標準出力でやり取りするため、console.logによるデバッグ出力がそのまま標準出力に混ざるとメッセージが壊れ、Claude Code側で接続エラーになります。デバッグ出力は標準エラー出力(console.error)に書くようにします。
よくある質問
対象のSaaSに既製のMCPサーバーが無いか、どう確認しますか
まずAnthropicのConnectorディレクトリと、npmやGitHubで「SaaS名MCP」を検索します。freeeやkintoneのように、ベンダー自身が公式MCPサーバーを配布しているケースもあるため、自作より先に確認する価値があります。
APIキーをチームで安全に共有するには
.mcp.jsonにAPIキーを直書きせず、${VAR}形式の環境変数展開を使います。各自のローカル環境変数やシークレット管理ツールにキーを置き、リポジトリにはプレースホルダーだけが残る状態にします。
stdioとHTTPはどちらを選べばいいですか
自分一人がClaude Codeから使うだけならstdioが最短です。複数人での共有やclaude.aiからの利用も想定するなら、HTTPトランスポートで実装してリモートサーバーとして公開し、カスタムConnectorとして登録します。stdioからHTTPへの移行は、トランスポート層の差し替えだけで済み、ツール定義そのものを書き直す必要はありません。まずstdioで動くものを作り、必要になった時点でHTTP化する順序が無理のない進め方です。
複数の業務SaaSを1つのMCPサーバーにまとめてもいいですか
技術的には可能ですが、推奨はしません。SaaSごとに認証方式やレート制限が異なるため、1つのサーバーに詰め込むとエラー処理が複雑になり、片方のSaaSの障害がもう片方への接続にも影響しかねません。SaaSごとに独立したサーバーとして分け、Claude側で複数登録して使う構成のほうが、障害の切り分けも保守も楽になります。
まとめ
公式ConnectorもMCPサーバーも無い業務SaaSは、REST APIを自分でMCPサーバーとしてラップすれば、Claudeの会話の中から直接操作できるようになります。認証ヘッダーをサーバー内に隠す、ページネーションとレート制限に対応する、Inspectorで検証してから登録する、という順序を踏めば、業務SaaSごとに数十行から百数十行程度の実装で足ります。ただし定期的な転記や同期のような「決まった処理を機械的に流す」用途まで自作でまかなう必要は無く、ZapierやMakeのMCP対応で足りるかを先に見極めるのが、開発コストを抑える近道です。