さよなら、スクレイピングコード。可愛い犬AIが自律的にPCを操作するデスクトップマスコットの作り方【AIエージェント× MCP】

### はじめに
デスクトップ上で機能する[犬AIエージェント](https://github.com/hiratsukaaa682/desktop-mascot-ai-agent.git)を作りました。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4119940/62014ff6-9f1a-4dbf-a262-4ec4ce4d4f31.gif)

「ミスタードーナツの期間限定商品を調べて、商品情報をCSVファイルに保存しておいて」

こんな風に話しかけるだけで、デスクトップ上の可愛い柴犬AIがブラウザを立ち上げ、情報を集め、構造化されたデータとしてファイルに保存してくれる。そんな未来がもう現実になっています。

この記事では、面倒なスクレイピングのコード記述からあなたを解放する、デスクトップマスコット型AIエージェントの作り方を解説します。

生成AIモデルのAPIと、AIに手足を与える技術「MCP」を組み合わせることで、AIは単なるチャットボットから、あなたのPCを自律的に操作する真の「エージェント」へと進化します。

この記事を読み終える頃には、あなただけの可愛いAIエージェントがデスクトップを駆け回っていることでしょう！

### このAIエージェントでできること

この犬AIエージェントは、自然言語で指示するだけで以下のようなタスクを自律的にこなします。

  * **Webからの情報収集と保存:**
      * 「〇〇社の最新ニュースを3つ調べて、`news.txt`に要約して保存して」
  * **複数サイトをまたいだ情報収集:**
      * 「東京と大阪の今日の天気を調べて、比較した結果を教えて」
  * **Web上の構造化データの取得とCSV保存:**
      * 「日経平均株価の推移がわかるページを探して、直近5日間の日付、始値、高値、安値、終値を`nikkei_stock.csv`にまとめて保存して」

### 技術スタックの紹介

このAIエージェントは、以下の技術の組み合わせで実現されています。

  * **`PyQt6` & `qasync`**
      * Pythonでデスクトップアプリを作るための定番ライブラリ`PyQt6`で、マスコットの見た目やチャットUIを構築します。AIの非同期処理とUIイベントをスムーズに連携させるために`qasync`も利用します。
  * **`Gemini 2.0` & `LangGraph`**
      * AIの核となるLLMには、Googleのモデル`Gemini 2.0`を使用します。そして、単にAIと会話するだけでなく、「ブラウザを操作→結果を分析→ファイルに保存」といった複雑な処理フローを`LangGraph`で構築します。
  * **`MCP (Model Context Protocol)`**
      * この記事のキーテクノロジーです。MCPは、AIが外部ツールを安全かつ標準化された方法で操作するための「プロトコル（お約束事）」です。今回は2つのMCPサーバーを利用します。
          * **Playwright MCP:** AIがブラウザを操作できるようにします。
          * **Filesystem MCP:** AIがPC上のファイルを読み書きできるようにします。

### 環境構築（さっそく作ってみよう！）

それでは、犬AIをあなたのPCに迎える準備をしましょう。

#### Step 1: プロジェクトの準備とライブラリのインストール

まず、Githubからリポジトリをクローンし、作業フォルダに移動します。

```bash
git clone https://github.com/hiratsukaaa682/desktop-mascot-ai-agent.git
cd desktop-mascot-ai-agent
```

次に、依存関係をインストールします。
```
pip install -r requirements.txt
```

続いて、Node.jsがインストールされていることを確認してください。（MCPサーバーを`npm`コマンドでインストール、`npx`コマンドで実行するために必要です）。
インストールされていることが確認できたらMCP Serverを使えるようにしましょう。

```bash
# Playwright MCP
# 何も表示されなければOKです。
npx @playwright/mcp@latest

# Filesystem MCP
npm install -g @modelcontextprotocol/server-filesystem
```

#### Step 2: Google APIキーの取得

1.  [Google AI Studio](https://aistudio.google.com/app/apikey)にアクセスします。
2.  「Create API key」をクリックして、新しいAPIキーを生成します。
3.  生成されたAPIキーをコピーします。
4.  プロジェクトフォルダの`.env`という名前のファイルに以下のようにキーを貼り付けます。

<!-- end list -->

```text:.env
GOOGLE_APIKEY="ここに取得したAPIキーを貼り付け"
```

#### Step 3: MCPの設定

AIに「手足」を与えるための設定です。以下の内容で`mcp_config.json`ファイルを作成します。

```json:mcp_config.json
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest"
      ],
      "transport": "stdio"
    },
    "file-system": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/path/test"
      ],
      "transport": "stdio"
    }
  }
}
```

**⚠️重要:** `file-system`の`args`の最後にあるパスは、**AIがファイルを読み書きすることを許可するフォルダの絶対パス**です。**必ずご自身の環境のパスに書き換えてください。**

書き換えたパスのフォルダ（この例では`test`フォルダ）を、PC上に実際に作成しておいてください。

#### Step 4: キャラクター画像の準備

お好きなGIF画像をダウンロードし、`shiba_hie.gif`という名前でプロジェクトフォルダに保存してください。これで準備は完了です！
なお、クローンしたリポジトリには[素材工場](https://sozaikoujou.com/)さんから入手した`shiba_hie.gif`があります。

### コードの解説

メインのプログラム`mascot_ai_agent.py`の重要なポイントを解説します。GUIのコードは省略し、AIエージェントの核となる部分に焦点を当てます。

#### Point 1: AIバックエンドの非同期初期化 (`init_ai_backend`)

`PyQt`のUIを動かしながら、時間のかかるAIの初期化をバックグラウンドで行います。`@asyncSlot`デコレータが`PyQt`と`asyncio`の橋渡しをしてくれます。ここでMCPクライアントを立ち上げ、ブラウザ操作やファイル操作といった「ツール」を準備し、LLMに連携させます。

```python:mascot_ai_agent.py (抜粋)
@asyncSlot()
async def init_ai_backend(self):
    self.update_bubble("AIを準備中...")
    try:
        model = ChatGoogleGenerativeAI(...)

        # mcp_config.jsonを読み込み
        with open("mcp_config.json", "r") as f:
            mcp_config = json.load(f)

        # MCPクライアント経由でツール（ブラウザ操作、ファイル操作）を準備
        mcp_client = MultiServerMCPClient(mcp_config["mcpServers"])
        tools = await mcp_client.get_tools()

        # ... (プロンプトとモデルの準備)

        # Geminiモデルにツールを連携させる
        model_with_tools = prompt | model.bind_tools(tools)

        # LangGraphでエージェントの処理フローを定義
        self.graph = create_lang_graph(tools, model_with_tools)
        
        self.update_bubble("準備完了！話しかけてください。")
        self.input_field.setEnabled(True)

    except Exception as e:
        # ... (エラー処理)
```

#### Point 2: AIへの指示書（プロンプト）

`SystemMessage`で、AIエージェントの役割、振る舞い、制約を詳細に定義します。ここの書き方次第でエージェントの性能が大きく変わります。今回はCSV保存にも対応できるよう、その旨を追記しているのがポイントです。

```python:mascot_ai_agent.py (抜粋)
message_prompt = [
    SystemMessage(content="""
あなたは役にたつAIアシスタントです。日本語で回答し、考えた過程を結論より前に出力してください。
あなたは、「PlayWrite」というブラウザを操作するtoolと「Filesystem」というローカル環境のファイル操作をするtoolを利用することができます。適切に利用してユーザからの質問に回答してください。
ツールを利用する場合は、必ずツールから得られた情報のみを利用して回答してください。「Filesystem」を使ってファイルを保存するときのパスは/Users/yourname/path/test配下です。
CSV形式での保存を指示された場合は、カンマ区切りのテキストデータとしてファイルに書き込んでください。

まず、ユーザの質問からツールをどういう意図で何回利用しないといけないのかを判断し、必要なら複数回toolを利用して情報収集をしたのち、すべての情報が取得できたら、その情報を元に返答してください。
    """),
    MessagesPlaceholder("messages"),
]
```

#### Point 3: ユーザー入力を受けてAIを動かす (`handle_user_input`と`process_with_ai`)

ユーザーがEnterキーを押すと`handle_user_input`が呼ばれます。UIを「考え中...」に更新し、`process_with_ai`内でLangGraphに組まれたエージェント(`self.graph`)を非同期で実行(`ainvoke`)します。これにより、ツール使用を含む一連の自律的な思考と行動が開始されます。

```python:mascot_ai_agent.py (抜粋)
@asyncSlot()
async def handle_user_input(self):
    user_text = self.input_field.text()
    if not user_text or self.ai_processing:
        return
    
    # ...（UI処理）...
    try:
        # LangGraphを非同期で実行し、応答を待つ
        ai_response = await self.process_with_ai(user_text)
        self.update_bubble(f"AI: {ai_response}")
    # ...（エラー処理・UI更新）...

async def process_with_ai(self, user_text):
    if not self.graph:
        return "AIがまだ準備できていません。"

    try:
        input_query = [HumanMessage(content=user_text)]
        # LangGraphのainvokeメソッドでエージェントを実行
        response = await self.graph.ainvoke(
            {"messages": input_query}, 
            config
        )
        return response["messages"][-1].content
    # ... (エラー処理)
```

### 実行！犬AIとの対話

すべての準備が整いました。以下のコマンドでマスコットを起動しましょう。

```bash
python mascot_ai_agent.py
```

デスクトップに犬AIが表示されたら成功です！
「AIを準備中...」という表示が「準備完了！」に変わったら、早速話しかけてみましょう。

**【試してみる指示の例】**

  * `今日のIT系ニュースを3つ探して、タイトルとURLをnews.mdに書き出して`
  * `langchain-mcp-adaptersのPyPIページを開いて、現在の最新バージョンを教えて`
  * `Yahooファイナンスから日経平均のページを探して、今日の始値と終値を調べてnikkei.csvに保存して`

### カスタマイズと今後の展望

#### キャラクターの変更

`shiba_hie.gif`を別のGIFファイルに差し替えるだけで、簡単にキャラクターを変更できます。あなたのお気に入りのキャラクターをデスクトップに住まわせましょう。

#### AIの性格を変える

`mascot_ai_agent.py`内の`SystemMessage`の内容を書き換えることで、AIの口調や性格をカスタマイズできます。「語尾は『〜ワン』にしてください」といった指示も有効です。

#### より高機能なMCPとツールの可能性

mcp_config.jsonのmcpServersに他のMCPサーバーを追加することで、AIができることをさらに拡張することができます。試してみたいMCPサーバーがあれば追加してみてください。あなただけのAIエージェントを作ることができます。

### おわりに

この記事では、Gemini API、LangGraph、そしてMCPという最先端の技術を組み合わせて、自律的にPCを操作するデスクトップマスコットAIエージェントを作成する方法をご紹介しました。

MCPの登場により、AIエージェント開発は「頭脳」を作るだけでなく、その「手足」をどう標準化し、連携させていくかという新しいフェーズに入ったと言えるでしょう。

このプログラムはまだデモ段階ですが、あなたのアイデア次第で、カレンダーと連携してスケジュールを管理したり、メールをチェックしたりと、さらに有能なアシスタントに進化させられるはずです。

ぜひ、あなただけの最強のAIエージェントを育ててみてください！

### 参考・利用させていただいたサイト
- [【Playwright MCP】を利用したエージェントを【LangGraph】で構築する](https://zenn.dev/asap/articles/59b8dd06d44754)
- [素材工場](https://sozaikoujou.com/)