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キーに置き換えてください。 - 初回実行時にはブラウザでの認証が求められるため、ターミナル上で操作してください。
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クイックスタートガイド
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なライブラリを検討するのが良いでしょう。