0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘録】MCPの概念を知るためのハンズオン

Last updated at Posted at 2025-08-08

MCPを理解するために、Geminiに簡単なハンズオンを考えてもらい、実施しました。
以下は実施内容をGeminiに記事にしてもらったものです。備忘録として残します。

【MCP入門】GeminiとPythonで作る!サーバーレスなGoogleカレンダー自動登録ツール

はじめに

皆さんは、日々大量のメールやチャットから「〇月〇日〇時にMTG」といった予定を一つひとつカレンダーに登録していませんか?この作業、AIで自動化できるとしたらどうでしょう。

本記事では、 MCP(Model Context Protocol) という考え方を使って、自然言語の指示からGoogleカレンダーに予定を自動登録する仕組みを構築します。プログラミング初心者の方でも、AIがプログラムを制御する仕組みを直感的に理解できるよう、順を追って解説します。

記事を読み終える頃には、GeminiとPythonを使って、あなた専用の自動カレンダー登録ツールが完成しているはずです。

1. MCP(Model Context Protocol)とは?

「AIを介して自然言語をプログラムが理解できるコマンドに変換し、実行する仕組み」 を指します。

役割 目的 今回のツールでの役割
ユーザー 「カレンダーに予定を登録して」と指示する コマンドラインからPythonスクリプトを実行するあなた
AI
(Gemini)
指示を解析し、プログラムが扱えるJSON形式のコマンドに変換する 予定の情報(タイトル、日時)をJSONとして抽出する「通訳者」
プログラム
(Python)
JSONコマンドを受け取り、APIを叩くなどの具体的な処理を実行する GoogleカレンダーAPIを呼び出し、予定を登録する「実行者」

この3つの役割分担を理解することが、MCPの核心です。

2. 事前準備

ハンズオンを始める前に、以下のツールと環境を準備しましょう。

  • Python 3.8以上: 公式サイトからインストールしてください。
  • Gemini APIキー: Google AI Studioで無料で取得できます。
  • Google Cloud Project:
    • Google Cloud Consoleでプロジェクトを作成します。
    • Google Calendar APIを有効化します。
    • OAuth同意画面を設定し、「外部」ユーザーとしてご自身のメールアドレスをテストユーザーに登録します。
    • 「認証情報」から OAuthクライアントID(デスクトップアプリ) を作成し、JSONファイルを credentials.json として保存します。

3. 実装 - プロンプト設計とPythonコード

準備ができたら、いよいよコードを書いていきます。

3.1. プロンプトの設計

Geminiに、カレンダー登録に必要な情報をJSON形式で出力させるためのプロンプトを設計します。これがMCPにおける「コマンド」の定義です。

プロンプト
あなたは優秀なタスク管理アシスタントです。ユーザーからの指示を分析し、Googleカレンダーへの予定登録が必要な場合はJSON形式で回答してください。

**フォーマット:**
```json
{
  "command": "add",
  "task": "[予定のタイトル]",
  "when": "[開始日時: yyyy/mm/dd HH:MM形式]"
}

日付や時間情報がない場合は、"when"をnullにしてください。
ユーザーの指示: {}

3.2. Pythonスクリプト

以下のコードを automated_calendar_mcp.py として保存します。このスクリプトは、コマンドライン引数をGeminiに渡し、その応答をもとにカレンダー登録までを自動で行います。

  • YOUR_API_KEYの部分を、ご自身のGemini APIキーに置き換えてください。
  • 初回実行時にはブラウザでの認証が求められるため、ターミナル上で操作してください。
automated_calendar_mcp.py
import datetime
import os
import json
import argparse
import google.generativeai as genai

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

# ==========================================
# グローバル設定
# ==========================================
SCOPES = ['https://www.googleapis.com/auth/calendar']

GEMINI_PROMPT_TEMPLATE = """
あなたは優秀なタスク管理アシスタントです。ユーザーからの指示を分析し、Googleカレンダーへの予定登録が必要な場合はJSON形式で回答してください。

**フォーマット:**
```json
{{
  "command": "add",
  "task": "[予定のタイトル]",
  "when": "[開始日時: yyyy/mm/dd HH:MM形式]"
}}
日付や時間情報がない場合は、"when"をnullにしてください。

ユーザーの指示: {}
"""

# ==========================================
# Googleカレンダー連携関数
# ==========================================
def create_calendar_event(summary, start_time, end_time):
    """Googleカレンダーに予定を登録する関数"""
    creds = None

    # token.jsonが存在する場合、保存されている認証情報を使用
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)

    # 認証情報が無効、または存在しない場合、認証フローを実行
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
            
        # 次回のため、認証情報をjsonで保存
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    
    service = build('calendar', 'v3', credentials=creds)

    # カレンダーに登録する情報をセット
    event = {
        'summary': summary,
        'start': {
            'dateTime': start_time.isoformat(),
            'timeZone': 'Asia/Tokyo',
        },
        'end': {
            'dateTime': end_time.isoformat(),
            'timeZone': 'Asia/Tokyo',
        },
    }

    # カレンダー登録処理
    event = service.events().insert(calendarId='primary', body=event).execute()
    
    print(f'予定が作成されました: {event.get("htmlLink")}')

def process_gemini_response(json_data):
    """GeminiのJSONを処理し、カレンダー登録を実行する (MCPの核心)"""
    try:
        # jsonデータを取得し変数に割り当て
        data = json.loads(json_data)
        command = data.get('command')
        task = data.get('task')
        when = data.get('when')
        
        print(f"GeminiのJSONを解析: command='{command}', task='{task}', when='{when}'")

        # 追加コマンド処理
        if command == 'add':
            if task and when:
                # 日付をdatetime型に変換
                start_time = datetime.datetime.strptime(when, '%Y/%m/%d %H:%M')
                # 終了時は1時間後として設定
                end_time = start_time + datetime.timedelta(hours=1)
                
                print(f'カレンダー登録を実行します: "{task}"{when} に登録')
                
                # カレンダー登録処理実行
                create_calendar_event(task, start_time, end_time)
            else:
                print('エラー: タスクと期限の情報が不足しています。')
        else:
            print(f'エラー: 不明なコマンドです。command={command}')
        
    except json.JSONDecodeError:
        print('エラー: 無効なJSONデータです。')
    except Exception as e :
        print(f'エラーが発生しました: {e}')
# ==========================================
# Gemini連携関数
# ==========================================
def get_gemini_response(user_prompt):
    """ユーザーの指示をGeminiに送り、JSONレスポンスを返す"""
    
    # YOUR_API_KEYは自身で取得したAPIキーを記述
    genai.configure(api_key="YOUR_API_KEY")
    
    model = genai.GenerativeModel('gemini-1.5-flash')

    # プロンプトにユーザーからの指示を挿入
    full_prompt = GEMINI_PROMPT_TEMPLATE.format(user_prompt)
    print(f'Geminiへリクエストを送信します...')

    # Geminiへリクエスト送信
    response = model.generate_content(full_prompt)
    
    try:
        # JSO形式のデータを取得
        json_start = response.text.find('```json') + 7
        json_end = response.text.rfind('```')
        json_data = response.text[json_start:json_end].strip()
        print(f'Geminiからのレスポンスを受信: \n{json_data}\n')
        return json_data
        
    except Exception as e:
        print(f"レスポンスの解析に失敗しました: {e}")
        return None
# ==========================================
# メイン処理
# ==========================================
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="GeminiでGoogleカレンダーに予定を自動登録します。")
    parser.add_argument("prompt", help="予定を自然言語で記述してください。例: '明日10時に企画書作成'")
    args = parser.parse_args()
    
    json_response = get_gemini_response(args.prompt)
    
    if json_response:
        process_gemini_response(json_response)
    else:
        print('プログラムを終了します。')

4. 実行と動作確認

ターミナルを開き、以下のコマンドを実行します。

python3 automated_calendar_mcp.py "2025年8月9日10時にミーティングの予定を入れて"

実行結果

初回実行時にはブラウザが開き、Googleアカウントでの認証が求められます。認証後、ターミナルには以下のような出力が表示されるはずです。

ログ
Geminiへリクエストを送信します...
Geminiからのレスポンスを受信:
{
  "command": "add",
  "task": "ミーティング",
  "when": "2025/08/09 10:00"
}

GeminiのJSONを解析: command='add', task='ミーティング', when='2025/08/09 10:00'
カレンダー登録を実行します: "ミーティング" を 2025/08/09 10:00 に登録
予定が作成されました: https://www.google.com/calendar/event?eid=...

ブラウザでGoogleカレンダーを開き、指定した日時に予定が登録されていることを確認しましょう。

おわりに

これで、GeminiとPythonを使ったサーバーレスな自動カレンダー登録ツールが完成しました。今回のハンズオンで得られたMCPの概念は、以下のような様々な応用が可能です。

  • SlackやDiscordの会話ログから予定を抽出し、自動で登録する。
  • 特定のメールを解析し、期日をタスク管理ツールに登録する。

「自然言語をコマンドにする」という考え方は、今後のAI開発において非常に重要なスキルとなります。この小さな一歩が、あなたの開発の可能性を大きく広げることを願っています。

補足

以下はGeminiと会話しながら出てきた補足です。ハンズオン自体には大きく関連しませんが残しておきます。

Geminiクイックスタートガイド

Gemini APIを取得後テストするためのの検証用コード。以下のURLから詳細を確認できます。
APIクイックスタートガイド

sample.py
from google import genai
from google.genai import types

client = genai.Client()

response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Explain how AI works in a few words",
    config=types.GenerateContentConfig(
        thinking_config=types.ThinkingConfig(thinking_budget=0) # Disables thinking
    ),
)
print(response.text)

Gemini APIのPythonライブラリについて

今回使った google.generativeai 以外にも、Gemini APIを呼び出すためのライブラリはいくつか存在します。主なものとして、 google.genai があります。それぞれの違いと、どんな場合にどちらを使うべきかについて簡単に解説します。

ライブラリ google.generativeai
(Generative AI SDK)
google.genai
(Google AI Client Libraries)
特徴 シンプルで直感的なライブラリ。 低レベルで、APIを詳細に制御できるライブラリ。
使いやすさ 非常に使いやすく、学習コストが低い。 学習コストはやや高いが、柔軟性が高い。
主な用途
  • 迅速なプロトタイプ開発
  • シンプルなアプリケーション
  • 非同期処理を多用するケース
  • 細かいパラメータ調整が必要な場合
  • 複数のモデルを厳密に管理したい場合

※低レベル1

結論:どちらを使うべきか?

今回のカレンダー登録ツールの様に、 シンプルなユースケースや、プロトタイプ開発では google.generativeai が最適 です。直感的なコードで素早く実装できるため、本質であるプロンプト設計に集中できます。

一方、APIのリクエストやレスポンスの細かい挙動を調整したい、あるいはGoogleの他のAIサービスと連携するような複雑なシステムを構築する場合は、より低レベルな制御が可能な google.genai が選択肢になります。

両方のライブラリは、どちらが「古い」というわけではなく、それぞれ異なる開発のニーズに応えるためのツールです。まずは使いやすい google.generativeai で開発を始め、必要に応じてより低レベル1なライブラリを検討するのが良いでしょう。

  1. 低レベル(Low-Level) とはコンピュータが理解しやすい、より機械的なレベル。メモリ管理やデータ構造の扱いを直接制御できるため、柔軟性が高く、パフォーマンスを最大限に引き出せます。しかし、記述が複雑になりがちです。(例: アセンブリ言語、C言語)
    逆に 高レベル(High-Level) とは 人間が理解しやすい、より抽象的なレベル。ライブラリやフレームワークが、複雑な処理を内部で隠蔽してくれるため、簡単に記述できます。ただし、その分、細かな制御は難しくなります。(例: Python, JavaScript) 2

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?