Skip to content

JCARVIS 連携設計

スタックちゃんは JCARVIS物理インターフェース として位置づけられる。 Discord・Slack と並ぶ第3のインターフェースとして、Stack-chan を声・顔・物理通知の出力デバイスとして使う。

全体像

              ┌────────────────────────┐
              │       JCARVIS Brain     │
              │  (Claude Code (Fable 5 deep tier 選択 / Opus 4.8))│
              └────────────┬───────────┘
                  ┌────────┼────────┐
                  ▼        ▼        ▼
          ┌───────────┐ ┌──────┐ ┌──────────┐
          │   Slack   │ │Discord│ │ Stack-chan│  ← 本プロジェクト
          │ connector │ │ conn. │ │ connector │
          └───────────┘ └──────┘ └─────┬─────┘
                                       │ WSS / MCP

                               ┌────────────────┐
                               │ スタックちゃん本体│
                               │ (CoreS3+Module-LLM)│
                               └────────────────┘

役割分担

レイヤ担当
思考・判断JCARVIS Brain(タスク種別判定 → Claude/Gemma 振り分け)
音声・顔・物理出力スタックちゃん本体
テキストチャットSlack / Discord
タスク管理・メール・ニュースJCARVIS 側の Skill / MCP ツール

JCARVIS 側に既に「Smart Routing」「Skill レゴブロック」があるので、スタックちゃん プロジェクト独自の Backend Router は JCARVIS に委譲する形に統合できる。

CommanderEngine — Gemma4 司令官 (2026-07-14, JCARVIS#324/#328)

デバイス経由 (source=stackchan) の応答は ローカル常駐 Gemma4 (E4B, ollama) が最初に受ける:

質問 → Gemma4 が1コールで {"difficulty":"easy|hard","text":"…"} を生成 (ウォーム TTFB 0.3〜1.7s)
  ├─ easy: text をそのまま SSE 送出 — Agent SDK 不使用 (課金ゼロ)・1〜2秒で発話開始
  └─ hard: text = Donack人格フィラー「調べて、分かったら声でお伝えしますね」を即送出
           → Agent SDK (Claude) が JCARVIS 内のプライベート情報 (予定/メール/タスク) で正式推論
           → 完了後 `push.js speak` (bridge MCP `stackchan.speak`) で 100字以内の話し言葉を音声プッシュ
  • 背景: Agent SDK コールドスタート ≈5〜11s/リクエストが体感遅延の支配項だった (JCARVIS#321 実測)
  • フェイルセーフ: Gemma 5s タイムアウト / ollama 停止時は分類スキップで Agent SDK 直行
  • デバイス発の対話は往復とも音声で完結 (#donack への本回答投稿はしない。読み上げ失敗時のみ代替投稿)
  • チャット経路 (discord/channels) は従来どおり ClaudeEngine 直 (挙動不変)

接続点(MCP / WSS)

状態 (2026-06-10): 下記はすべて実装済み・E2E 疎通確認済み (#86)。 JCARVIS 側 connectors/stackchan/server.js (HTTP/SSE, JCARVIS #114) と connectors/stackchan/bridge-client.js + scripts/donack/push.js (能動 push, JCARVIS #115) が存在する。

ポートマップ

ポートプロセス用途
7780stackchan-bridge (WSS)本体 ⇔ bridge。Tailscale Funnel で /stackchan/ws として公開
8787stackchan-bridge (MCP HTTP)JCARVIS → stackchan.* ツール呼び出し
8181JCARVIS connectors/stackchan/server.jsbridge → JCARVIS Brain (HTTP POST + SSE)
8788JCARVIS 管理用 WSS (stack-chan-backend)管理画面・デバッグ用に温存 (JCARVIS #112 で 8787→8788 退避)

起動手順(Mac 側)

bash
# JCARVIS :8181 (Claude サブスクモード)
cd AIEO_JCARVIS
AGENT_PROFILE=donack DONACK_ENGINE=claude node connectors/stackchan/server.js
# 注意: DONACK_ENGINE 未指定だと EchoEngine (テスト用) になる。
# 注意: ユーザーデフォルトモデルが alias (例 "fable") だと SDK が解釈できないことがある。
#       その場合 ANTHROPIC_MODEL=claude-haiku-4-5-20251001 等で明示する(音声経路は低レイテンシ優先)。

# bridge :7780 (#72 構成: 発話は firmware on-device melotts)
cd aieo-stack-chan/mac-studio/bridge
TTS_ENGINE=none DEFAULT_BACKEND=jcarvis npm run start

# Funnel 公開
bash ../scripts/tailscale-funnel-setup.sh

配信ポリシー(JCARVIS #125/#130)

JCARVIS は source フラグで配信方式を切り替える。bridge が送る source: 'stackchan'delivery_policy.sources.stackchan.tts: true に該当し、文境界チャンクで SSE 配信される (受信側の逐次発話対応は #87)。

JCARVIS の connectors/stackchan/ を窓口として:

スタックちゃん本体
      │ WSS (Tailscale Funnel)

[Mac Studio / stackchan-bridge]
      │ HTTP or stdio MCP

[JCARVIS Brain]
      │ Skill / Provider Routing

Claude / Gemma 4 / その他

必要な実装

1. Mac Studio 側 stackchan-bridge(本プロジェクト)

  • WSS サーバー(本体からの接続を受ける、Tailscale Funnel で公開)
  • 受信した agent.run を JCARVIS に投げる
  • ストリーミング応答を WSS で本体に返す
  • 同時に Backend Router 抽象を維持し、JCARVIS が落ちていれば Claude/Codex/Local に直接フォールバック

2. JCARVIS 側 connectors/stackchan/(先方リポに追加が必要)

connector.yaml 例:

yaml
name: stackchan
type: physical
interface: http
endpoint: http://localhost:8181/agent
capabilities:
  - voice_input    # スタックちゃんから声で受け取る
  - voice_output   # TTS でスタックちゃんから返す
  - face_display   # Donack キャラ表情で状態表現
  - led_notify     # LED で通知
  - ir_control     # 家電操作
description: "M5Stack スタックちゃん物理インターフェース"

mcp-servers.json 例:

json
{
  "mcpServers": {
    "stackchan": {
      "url": "http://localhost:8787/mcp",
      "tools": [
        "stackchan.speak",
        "stackchan.set_expression",
        "stackchan.notify",
        "stackchan.ir_send",
        "stackchan.get_presence"
      ]
    }
  }
}

3. Backend Router の挙動

スタックちゃん側 Backend Router (#24) は以下を順に試す:

  1. payload.backend が指定されていればそれ
  2. JCARVIS が起動中 → JCARVIS にすべて委譲
  3. JCARVIS 不在時 → 直接 Claude / Codex / Local LLM

これにより、JCARVIS が使えれば JCARVIS のスマートルーティングを享受できるし、JCARVIS が止まっていてもスタックちゃん単体で動作する。

連携 MCP ツール仕様(JCARVIS → スタックちゃん)

JCARVIS の Skill から呼べるよう、Mac Studio 側で MCP サーバーを立てる。

Tool引数動作
stackchan.speak{ text, expression? }スタックちゃんに TTS で発話させる。内部配送は agent.delta+agent.done(会話応答と同一タイプ・#148。firmware は notify を発話処理しないため)。デバイス発 run 進行中は発話が連結され得る
stackchan.set_expression{ expression: idle|listening|thinking|talking|happy|sad|sleeping }表情切替
stackchan.notify{ kind, summary, speak?, led? }LED・キャラ・TTS で通知
stackchan.ir_send{ device, action }Unit IR で家電操作
stackchan.get_presence{}TMOS PIR の在席状態を返す
stackchan.get_status{}動作モード・接続状況を返す

連携 MCP ツール仕様(スタックちゃん → JCARVIS)

スタックちゃんから JCARVIS の機能を呼ぶ:

Tool引数動作
jcarvis.ask{ prompt, context? }自然言語の依頼を JCARVIS Brain に投げる
jcarvis.tasks{ filter? }タスク一覧取得(GitLab連携)
jcarvis.calendar{ range }予定取得
jcarvis.translate{ text, target }翻訳(Gemma 4 local)
jcarvis.summarize{ text }要約

JCARVIS は既に Skill レゴブロックを持っているので、これらは JCARVIS 側の既存 Skill を MCP 経由で叩く形になる。

Slack / Discord との一貫性

ユーザーが Slack で「テレビ消して」と書くのと、スタックちゃんに「テレビ消して」と話しかけるのは、JCARVIS から見て同じ意図 として扱える。

JCARVIS の Skill Registry に 発話元コネクタを引数として渡す ことで、応答の戻り先を切り替えられる:

yaml
# JCARVIS skill 呼び出し例
skill: ir-control
args:
  device: tv
  action: off
connector: stackchan    # スタックちゃんからの呼び出し → 音声+表情で返す
                        # slack なら #channel に返す
                        # discord なら DM に返す

デプロイ順序

JCARVIS と本プロジェクトの開発を交互に進める必要があるので、最初はスタンドアロンで動かしてから繋ぐ:

  1. スタックちゃん本体スタンドアロン — Module-LLM だけで雑談、Mac Studio 不要
  2. Mac Studio + Backend Router 直結 — Claude/Codex/Local を直接呼ぶ
  3. JCARVIS bridge を入れて切替 — Backend Router が JCARVIS にも投げ分け可能に
  4. JCARVIS 側に stackchan connector を実装 — 双方向 MCP 連携完成
  5. Slack/Discord と同等の一級コネクタ化 — JCARVIS のダッシュボードからスタックちゃんに発話指示できる

関連リソース

最終更新:

aieo-product / stack-chan project