15分でわかる！AIエージェントでMCPを活用するメリット

# はじめに

こんにちは！KIYOラーニングで [スタディング](https://studying.jp/) の開発をしている @Kumacchiino です！
今回は、AIエージェント界隈で最近話題となっている **MCP（Model Context Protocol）** について、その**メリットやどんなことができるのか**をまとめてみました。AIアプリケーションのツールの使用方法や、AIエージェントと外部データ連携の方法で悩んだ経験がある方には、ぜひ参考になればと思います。

## この記事で得られること

- **MCPの基本理解**：MCPを使うことで、どんなメリットがあるのか全体像が掴める
- **具体的な効果**：AIエージェントやAIアプリケーションにMCPの仕組みを取り入れるとどう変わるのか、実例を交えて解説
- **実務での活用例**：実際の業務シーンでMCPがどのような場面で役立つのか、具体的なユースケース例がわかる

## MCP（Model Context Protocol）とは？

まず、そもそもMCPとは何なのでしょうか。
端的に言えば、MCPとは、**AIアプリケーションと外部ツールやデータソースとの連携を標準化するためのプロトコル（決まり事）** です。
ここでいう外部ツールやデータソースとは、以下のようなものです。

* 外部API（例：天気API、Google Calendar API、Slack APIなど）
* データベースやファイル（例：CSVファイル、Google Sheets、Notionなど）
* 処理モジュール（例：テキストの要約処理、翻訳処理、音声認識処理など）
* サードパーティツール（例：Zapier連携、外部CRMツール）
* エージェントが実行するプログラム的タスク（例：Webスクレイピング、レポート生成）

MCPは、Anthropic社が考案したプロトコルで、**ツールの実装や連携方法がバラバラになりがちな現状の課題を解消するため**に生まれました。  
[MCPの公式ドキュメント](https://modelcontextprotocol.io/introduction)では、以下のように定義されています。

> MCPは、アプリケーションがLLMにコンテキストを提供する方法を標準化するオープンプロトコルです。  
> MCPは、AIアプリケーション用のUSB-Cポートのようなものです。  
> USB-Cがデバイスをさまざまな周辺機器やアクセサリに接続するための標準化された方法を提供するのと同様に、  
> MCPはAIモデルを様々なデータソースやツールに接続するための標準化された方法を提供します。

つまり、MCPはAIアプリケーションに最適化された **LLMと各種ツール・データソースとの橋渡しをする共通インターフェース** です。
これにより、各ユーザーが必要なツールやデータを手軽に組み込めるだけでなく、開発者も一度の実装で幅広い連携が可能になります。

## MCPを利用したAIエージェント

ここからは、MCPを利用した場合と利用しない場合のAIエージェントの違いについて、図を使いながら解説します。

### ① MCPを使用しないAIエージェント

![MCP未使用図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3996812/65b023d2-9a00-41f2-9cbe-8ea3c548c868.png)

こちらは、MCPを使わずに各エージェントごとに独自のツール連携処理を実装したイメージ図です。  
各AIエージェントアプリケーションが、それぞれ異なる方法（LangGraphやCrewAIなどのフレームワーク）でツールを実装・呼び出すため、開発工数がかかり、なおかつコードが複雑になり保守性も低下してしまいます。
また、異なるプログラミング言語で実装されることもあり、統一の取れた管理が難しいという問題もあります。

### ❌ MCP非利用時の課題

1. **ツールの独自実装が必要になる**  
   - 各AIエージェントがAPI呼び出し、ファイル操作、認証処理などを個別に実装しなければならず、同じ処理が重複して実装される

2. **拡張や変更に弱い**  
   - 例えば「CSVツールをGoogle Sheetsに変更する」場合、各エージェントの実装を個別に修正する必要があり、手間がかかる

3. **保守性・テストが煩雑になる**  
   - 連携方法が統一されていないため、エラー発生時の調査やテストが大変で、開発コストが高くなる

4. **セキュリティの統一が難しい**  
   - 認証や認可の実装がツールごとにバラつくため、全体としてのセキュリティポリシーの維持が困難になる

5. **チーム開発が非効率になる**  
   - 開発者ごとに実装スタイルが異なるため、コードレビューや共同開発時に統一感がなく、理解に時間がかかってしまう

6. **モデルへのインターフェースが複雑になる**  
   - 各ツールごとに異なる使い方を統一するためのプロンプト設計が必要となり、手間がかかる

### ② MCPを利用したAIエージェント

一方、MCPを利用すると、AIエージェントはあたかも「モジュール」を差し込むように、各ツールへの連携が簡単に実現できます。

![MCP使用図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3996812/c7cb4c3d-e689-46e0-bc33-144b5ad1a7ce.png)

各ツールごとに専用のMCPサーバーを立ち上げ、エージェントが必要なツールを設定ファイルを通じて簡単に接続します。  
この仕組みにより、例えば**ツールの変更や追加もサーバー側で管理するだけで済むため、柔軟性が大幅に向上**します。

### ✅ MCPを利用するメリット

1. **ツール連携の標準化と再利用が可能**  
   - MCPを導入すると、各AIエージェントは共通の呼び出し仕様に従ってツールを利用できるため、コードの重複や実装のばらつきが解消され、効率的な開発が可能になる

2. **拡張や変更が容易になる**  
   - 新しいツールの追加や既存ツールの変更が、MCPサーバー側の設定のみで完結するため、AIエージェント側の改修がほとんど不要となる

3. **保守性とテスト性の向上**  
   - 一元化されたツール連携ロジックにより、変更箇所が明確になり、トラブルシューティングもしやすくなる

4. **セキュリティの統一管理が実現できる**  
   - 認証・認可処理をMCPサーバーに集約することで、全体としてのセキュリティ対策を一括で適用でき、抜け漏れを防ぐことができるようになる

5. **チーム開発が円滑に進む**  
   - 共通仕様に沿って実装されるため、複数人での開発でも共通理解が得やすく、コードの品質や可読性が向上する

6. **プロンプト設計がシンプルになる**  
   - 統一された形式でツール呼び出しが行えるので、プロンプトのテンプレート化や再利用がしやすくなる

### 📋 比較表

| 項目         | MCP利用時のメリット                                    | MCP非利用時のデメリット                         |
|--------------|---------------------------------------------------------|-------------------------------------------------|
| **実装**     | 共通の呼び出し仕様でツール連携が容易                   | 各ツールごとに独自実装が必要                    |
| **拡張性**   | ツールの追加・変更がサーバ側のみで完結                | エージェント側も随時修正が必要                  |
| **保守性**   | 修正箇所が明確でテストが容易                           | 実装が分散しており、バグ修正や調査が大変          |
| **セキュリティ** | 認証処理が統一され、セキュリティが強化される         | ツールごとに認証方法が異なり、リスクが高い        |
| **チーム開発**   | 共通仕様に沿った実装で協業がしやすい                | 実装ルールが統一されず、属人化しやすい           |

## MCPとAPIの違い

従来のAPIとMCPの主な違いについても触れておきます。  

### APIの場合

各ツールやデータソースごとに専用のAPIを設計し、エージェントと接続します。  
その結果、各APIの仕様に合わせたカスタムコードを書かなければならず、開発効率や保守性が低下するケースが少なくありません。

### MCPの場合

MCPは、AIエージェントと外部ツールやデータソースを統一された方法で接続するためのプロトコル（決まり事）です。  
一度MCPに対応すれば、複数のツールとの連携を容易に実現でき、コードの管理もシンプルになります。 

## MCPの具体的な利用方法

MCPに対応したアプリケーションは、色々あります。  
例えば、有名なIDEである [Cursor](https://www.cursor.com/ja) では、自作のMCPサーバーを利用する設定が可能です。  
Cursorの設定画面で **基本設定 > Cursor Settings > MCP** を選択し、設定ファイル `mcp.json` に以下のような内容を記述します。

```json
{
    "mcpServers": {
        "mysql": {
            "command": "uv",
            "args": [
                "--directory", 
                "/Users/Kumacchiino/Desktop/mcp/mysql_server",
                "run",
                "mysql_server.py"
            ]
        }
    }
}
```

この設定は、自作MCPサーバを使用できるようにするための設定で、この設定を記述することで、Cursorがコード補完などをする際に、プロダクトのデータが格納されているローカルのMySQLデータベースにアクセスして、その情報を参照して、適切なコード補完を提案してくれるようになります。
**JSONファイルに数行追記するだけで、必要なツールが簡単に利用可能**になります。

## 自作MCPサーバの構築方法について

MCPサーバ自体は、すでに多くの有用な実装がオープンソースとして公開されています。  
[MCPの公式リポジトリ](https://github.com/modelcontextprotocol/servers) では、さまざまなMCPサーバが確認できます。  
自分専用のMCPサーバーを作ることも可能です。詳しい作り方については、[ドキュメント](https://modelcontextprotocol.io/quickstart/server) を御覧ください。

私自身は、ローカルのMySQLデータベースを操作するツールをAIアプリケーションやAIエージェントで使いたいと思い、以下のようなMCPサーバーをPythonで構築しました。  
このコードをAIアプリケーションのMCP設定ファイルに記述すると、`@mcp.tool()` というアノテーションを付与した関数がツールとして認識され、AIが状況に応じて**自律的に**呼び出してくれるようになります。

以下は、私が作成したMCPサーバのコード例です。

```python:mysql_server.py
from typing import Any, List, Dict, Optional
import aiomysql
import os
from dotenv import load_dotenv
from mcp.server.fastmcp import FastMCP

# .envファイルを読み込む
load_dotenv()

# FastMCPサーバーの初期化
mcp = FastMCP("mysql_server")

# データベース接続情報を環境変数から取得
DB_CONFIG = {
    "host": os.getenv("DB_HOST", "localhost"),
    "port": int(os.getenv("DB_PORT", "3306")),
    "user": os.getenv("DB_USER", ""),
    "password": os.getenv("DB_PASSWORD", ""),
    "db": os.getenv("DB_NAME", ""),
    "charset": os.getenv("DB_CHARSET", "utf8mb4"),
    "cursorclass": aiomysql.DictCursor
}

# 接続プールを保持する変数
pool = None

async def get_pool():
    """MySQLコネクションプールを取得する"""
    global pool
    if pool is None:
        pool = await aiomysql.create_pool(**DB_CONFIG)
    return pool

@mcp.tool()
async def execute_query(query: str, params: Optional[List[Any]] = None) -> Dict[str, Any]:
    """SQLクエリを実行する

    Args:
        query: 実行するSQLクエリ
        params: クエリパラメータ（オプション）

    Returns:
        クエリ結果とメタデータを含む辞書
    """
    # DELETE操作を禁止
    if query.strip().upper().startswith('DELETE'):
        return {
            "success": False,
            "error": "削除操作は許可されていません"
        }
    pool = await get_pool()
    
    async with pool.acquire() as conn:
        async with conn.cursor() as cursor:
            try:
                # パラメータが提供されている場合はそれを使用
                if params:
                    await cursor.execute(query, params)
                else:
                    await cursor.execute(query)
                
                # SELECTクエリの場合は結果を取得
                if query.strip().upper().startswith('SELECT'):
                    results = await cursor.fetchall()
                    return {
                        "success": True,
                        "rowCount": len(results),
                        "results": results
                    }
                # INSERT, UPDATE等の場合
                else:
                    # 変更をコミット
                    await conn.commit()
                    return {
                        "success": True,
                        "affectedRows": cursor.rowcount,
                        "lastRowId": cursor.lastrowid
                    }
            except Exception as e:
                # エラーが発生した場合はロールバック
                await conn.rollback()
                return {
                    "success": False,
                    "error": str(e)
                }

@mcp.tool()
async def get_tables() -> Dict[str, Any]:
    """データベース内のテーブル一覧を取得する"""
    query = "SHOW TABLES"
    return await execute_query(query)

@mcp.tool()
async def describe_table(table_name: str) -> Dict[str, Any]:
    """指定したテーブルの構造を表示する

    Args:
        table_name: 表示するテーブル名
    """
    query = f"DESCRIBE {table_name}"
    return await execute_query(query)

@mcp.tool()
async def select_from_table(table_name: str, columns: str = "*", 
                           where_clause: str = "", 
                           limit: int = 100,
                           offset: int = 0) -> Dict[str, Any]:
    """テーブルからデータを取得する

    Args:
        table_name: 取得対象のテーブル名
        columns: 取得するカラム (デフォルト: "*")
        where_clause: WHERE句 (オプション)
        limit: 取得する最大行数 (デフォルト: 100)
        offset: 開始位置 (デフォルト: 0)
    """
    query = f"SELECT {columns} FROM {table_name}"
    
    if where_clause:
        query += f" WHERE {where_clause}"
    
    query += f" LIMIT {limit} OFFSET {offset}"
    
    return await execute_query(query)

@mcp.tool()
async def insert_into_table(table_name: str, data: Dict[str, Any]) -> Dict[str, Any]:
    """テーブルに新しい行を挿入する

    Args:
        table_name: 挿入先のテーブル名
        data: 挿入するデータ（カラム名: 値 の辞書）
    """
    columns = ", ".join(data.keys())
    placeholders = ", ".join(["%s"] * len(data))
    values = list(data.values())
    
    query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
    
    return await execute_query(query, values)

@mcp.tool()
async def update_table(table_name: str, 
                      data: Dict[str, Any], 
                      where_clause: str) -> Dict[str, Any]:
    """テーブル内の行を更新する

    Args:
        table_name: 更新対象のテーブル名
        data: 更新するデータ（カラム名: 値 の辞書）
        where_clause: 更新対象を絞り込むWHERE句
    """
    set_clause = ", ".join([f"{key} = %s" for key in data.keys()])
    values = list(data.values())
    
    query = f"UPDATE {table_name} SET {set_clause} WHERE {where_clause}"
    
    return await execute_query(query, values)

@mcp.tool()
async def execute_transaction(queries: List[Dict[str, Any]]) -> Dict[str, Any]:
    """複数のクエリをトランザクションとして実行する

    Args:
        queries: 実行するクエリのリスト。各クエリは {'query': 'SQLクエリ', 'params': [パラメータ]} の形式
    """
    # DELETE操作を含むトランザクションを禁止
    for query_data in queries:
        query = query_data.get('query', '')
        if query.strip().upper().startswith('DELETE'):
            return {
                "success": False,
                "error": "トランザクション内の削除操作は許可されていません"
            }
    pool = await get_pool()
    results = []
    
    async with pool.acquire() as conn:
        try:
            # 自動コミットを無効化
            await conn.begin()
            
            async with conn.cursor() as cursor:
                for query_data in queries:
                    query = query_data.get('query')
                    params = query_data.get('params')
                    
                    if params:
                        await cursor.execute(query, params)
                    else:
                        await cursor.execute(query)
                    
                    if query.strip().upper().startswith('SELECT'):
                        query_result = await cursor.fetchall()
                        results.append({
                            "success": True,
                            "rowCount": len(query_result),
                            "results": query_result
                        })
                    else:
                        results.append({
                            "success": True,
                            "affectedRows": cursor.rowcount,
                            "lastRowId": cursor.lastrowid
                        })
            
            # すべてのクエリが成功したらコミット
            await conn.commit()
            return {
                "success": True,
                "results": results
            }
        except Exception as e:
            # エラーが発生したらロールバック
            await conn.rollback()
            return {
                "success": False,
                "error": str(e),
                "completed_results": results
            }

if __name__ == "__main__":
    # サーバーの初期化と実行
    mcp.run(transport='stdio')

```

この自作のMCPサーバを使うことで、AIが必要に応じて、ローカルのデータベースからデータを参照・集計して、回答に含めることができるようになります。

## 業務におけるMCP活用のユースケース

MCPは、さまざまな業務シーンで柔軟に活用できます。特に社内業務の効率化に有用と感じました。
以下、具体例をいくつかご紹介します。

### 1. **営業支援システムとの連携**

- 営業担当者向けのAIエージェントにMCPサーバ経由でツールを組み込み、**自社のCRMシステムや販売データベース**と連携することで、  
    - **リアルタイム情報の提供**：商談前に顧客の最新の購買履歴や問い合わせ内容を即座に取得でき、最適な提案が可能に  
    - **自律的に効率的なフォローアップ**：過去のやり取りや契約状況を基に、適切なタイミングでのフォローアップが実現できる

### 2. **採用プロセス支援（人事部門）**

- 人事担当者向けのAIアプリケーションにMCPサーバを介して、**自社の応募者データベースや評価システムと連携**することで、  
    - **迅速な応募者評価**：応募者の履歴書や評価結果を統合的に分析し、適材適所の候補者をすぐにピックアップできる  
    - **面接準備の効率化**：過去の面接記録やフィードバック情報を参照して、面接官が効果的な質問や評価項目を用意できる

### 3. **プロジェクト管理ツールとの統合**

- AIアプリケーションにMCPの仕組みを使い、**自社のプロジェクト管理ツールと連携**させることで、  
    - **タスクの自動更新**：進行中のタスクの状況がリアルタイムに反映され、チーム全体で進捗管理がしやすくなる  
    - **リソースの最適化**：メンバーの稼働状況や負荷を分析し、最適なタスク割り当ての判断材料が得られる

上記はほんの一例ですが、業務上のさまざまな課題に対して、MCPを活用することで効率的かつ柔軟な連携が可能になると思います。

## まとめ

MCPは、業務におけるツール連携を標準化することで、開発効率の向上や保守性・セキュリティの統一管理に大きく寄与する仕組みです。  
私自身も、今後MCPの仕組みを活用したAIアプリケーションの開発に取り組み、日々の業務や社会全体に貢献できるプロダクトを作っていきたいと考えています。  
ぜひ、皆さんも自身の現場でMCPの導入を検討してみてください！

---

スタディングでは、AIを活用し、利用者が効率的に新たな知識を習得できるよう、日々サービス向上に努めています。  
ご興味のある方は、ぜひ下記のリンクをご覧ください。  
最後までお読みいただき、ありがとうございました！

----

## KIYOラーニング株式会社について
当社のビジョンは『世界一「学びやすく、分かりやすく、続けやすい」学習手段を提供する』ことです。革新的な教育サービスを作り成長させていく事で、オンライン教育分野でナンバーワンの存在となり、世界に展開していくことを目指しています。

https://kiyo-learning.com/

### プロダクト

* [スタディング](https://studying.jp/)：「学びやすく・わかりやすく・続けやすい」オンライン資格対策講座
* [スタディングキャリア](https://career.studying.jp/)：資格取得者の仕事探しやキャリア形成を支援する転職サービス
* [AirCourse](https://aircourse.com/)：受け放題の動画研修がついたeラーニングシステム（LMS）

### KIYOラーニング株式会社では一緒に働く仲間を募集しています

https://www.wantedly.com/companies/kiyo-learning/projects

https://herp.careers/v1/kiyolearning