🚀 Tesla MCP Server
Tessie API を介してテスラ車両を制御するための、ストリーミング可能なHTTP MCPサーバーです。
作者: overment
⚠️ 重要提示
このサーバーをMCPクライアントに接続することは、あなた自身の責任で行ってください。言語モデルは誤りを犯したり、指示を誤解したり、意図しないアクションを実行する可能性があります。特に、車の解錠、トランクの開放、ナビゲーション先の送信などのアクションについては、実行前に必ずコマンドを確認してください。
HTTPレイヤーは開発時の利便性を目的として設計されており、本番環境でのセキュリティを保証するものではありません。リモートでデプロイする場合は、適切なトークン検証、安全な保存、TLS終端、厳格なCORS/オリジンチェック、レート制限、および監査ログの設定など、セキュリティ対策を強化してください。
🚀 クイックスタート
このリポジトリは、以下の2つの方法で動作します。
- ローカルワークフロー用の Node/Honoサーバー として
- リモートインタラクション用の Cloudflare Worker として
✨ 主な機能
- ✅ 状態 — バッテリー、航続距離、位置、クライメート、ドア、充電状態
- ✅ コマンド — 施錠/解錠、クライメート制御、トランクの開閉、セントリーモード、ナビゲーション
- ✅ 位置認識 — コンテキスト認識型インタラクションのためのGPS座標
- ✅ デュアルランタイム — Node.js/BunまたはCloudflare Workers
設計原則
- LLMフレンドリー:1対1のAPIミラーではなく、2つの統一されたツール
- ウォッチ対応:位置コンテキストを持つAIエージェント向けに設計
- セキュア:Tessie APIキーはシークレットとして保存され、クライアントは個別のベアラートークンを使用
- 明確なフィードバック:詳細なコマンド結果と車両状態
📦 インストール
前提条件: Bun、Tessieアカウント。
実行方法 (いずれか1つを選択)
- ローカル開発 — ベアラートークン認証による標準セットアップ
- Cloudflare Worker (wrangler dev) — ローカルでのWorkerテスト
- Cloudflare Worker (deploy) — リモート本番環境
1. ローカル開発 — クイックスタート
-
Tessieの資格情報を取得します。
- developer.tessie.com にアクセスします。
- Developer Settings → Generate Access Token に移動します。
- アクセストークンをコピーします。
- 車両のVINをメモします。
-
環境を設定します。
cd tesla-mcp
bun install
cp .env.example .env
.env を編集します。
PORT=3000
AUTH_ENABLED=true
AUTH_STRATEGY=bearer
# Generate with: openssl rand -hex 32
BEARER_TOKEN=your-random-auth-token
# Tessie credentials
TESSIE_ACCESS_TOKEN=your-tessie-access-token
TESSIE_VIN=your-vehicle-vin
- 実行します。
bun dev
Claude Desktop / Cursor:
{
"mcpServers": {
"tesla": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3000/mcp", "--transport", "http-only"],
"env": { "NO_PROXY": "127.0.0.1,localhost" }
}
}
}
2. Cloudflare Worker (ローカル開発)
bun x wrangler dev --local | cat
ローカルのシークレット用に .dev.vars を作成します。
BEARER_TOKEN=your_random_auth_token
TESSIE_ACCESS_TOKEN=your_tessie_token
TESSIE_VIN=your_vehicle_vin
エンドポイント: http://127.0.0.1:8787/mcp
3. Cloudflare Worker (デプロイ)
- セッションストレージ用のKV名前空間を作成します。
bun x wrangler kv:namespace create TOKENS
出力には以下のような内容が表示されます。
Add the following to your wrangler.toml:
[[kv_namespaces]]
binding = "TOKENS"
id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
wrangler.toml をKV名前空間IDで更新します。
[[kv_namespaces]]
binding = "TOKENS"
id = "your-kv-namespace-id-from-step-1"
- シークレットを設定します。
openssl rand -hex 32
bun x wrangler secret put BEARER_TOKEN
bun x wrangler secret put TESSIE_ACCESS_TOKEN
bun x wrangler secret put TESSIE_VIN
- デプロイします。
bun x wrangler deploy
エンドポイント: https://<worker-name>.<account>.workers.dev/mcp
💻 使用例
クライアント設定
Aliceアプリ
以下の設定でMCPサーバーとして追加します。
- URL:
https://your-worker.workers.dev/mcp
- タイプ:
streamable-http
- ヘッダー:
Authorization: Bearer <your-BEARER_TOKEN>
Claude Desktop / Cursor (ローカルサーバー)
{
"mcpServers": {
"tesla": {
"command": "npx",
"args": ["mcp-remote", "http://127.0.0.1:3000/mcp", "--transport", "http-only"],
"env": { "NO_PROXY": "127.0.0.1,localhost" }
}
}
}
Claude Desktop / Cursor (Cloudflare Worker)
{
"mcpServers": {
"tesla": {
"command": "npx",
"args": ["mcp-remote", "https://your-worker.workers.dev/mcp", "--transport", "http-only"]
}
}
}
MCPインスペクター (クイックテスト)
bunx @modelcontextprotocol/inspector
ツール
tesla_state
テスラ車両の現在の状態を取得します。
{}
{
display_name: string;
battery_level: number;
battery_range_km: number;
charging: {
state: string;
minutes_remaining: number | null;
charge_limit: number;
};
location: {
latitude: number;
longitude: number;
heading: number;
speed: number | null;
};
locked: boolean;
sentry_mode: boolean;
climate: {
is_on: boolean;
inside_temp: number;
outside_temp: number;
target_temp: number;
is_defrosting: boolean;
};
doors: {
front_left: boolean;
front_right: boolean;
rear_left: boolean;
rear_right: boolean;
frunk: boolean;
trunk: boolean;
charge_port: boolean;
};
state: "online" | "asleep" | "offline";
odometer_km: number;
last_updated: string;
}
tesla_command
テスラ車両にコマンドを実行します。
{
command: "lock" | "unlock" | "start_climate" | "stop_climate" |
"set_temperature" | "start_defrost" | "stop_defrost" |
"open_frunk" | "open_trunk" | "open_charge_port" |
"close_charge_port" | "enable_sentry" | "disable_sentry" |
"flash" | "honk" | "share";
temperature?: number;
destination?: string;
locale?: string;
}
{
success: boolean;
command: string;
message: string;
}
コマンドリファレンス:
| コマンド |
説明 |
パラメータ |
lock |
車両を施錠する |
— |
unlock |
車両を解錠する |
— |
start_climate |
クライメート制御を開始する |
— |
stop_climate |
クライメート制御を停止する |
— |
set_temperature |
車内温度を設定する |
temperature (15-28°C) |
start_defrost |
最大デフロストをオンにする |
— |
stop_defrost |
デフロストをオフにする |
— |
open_frunk |
フロントトランクを開く |
— |
open_trunk |
リアトランクを開閉する |
— |
open_charge_port |
充電口のドアを開く |
— |
close_charge_port |
充電口のドアを閉じる |
— |
enable_sentry |
セントリーモードを有効にする |
— |
disable_sentry |
セントリーモードを無効にする |
— |
flash |
ライトを点滅させる |
— |
honk |
ホーンを鳴らす |
— |
share |
ナビゲーションに目的地を送信する |
destination, locale? |
具体的な使用例
1. 車両の状態を取得する
{
"name": "tesla_state",
"arguments": {}
}
2. 車を施錠する
{
"name": "tesla_command",
"arguments": {
"command": "lock"
}
}
3. 温度を22°Cに設定する
{
"name": "tesla_command",
"arguments": {
"command": "set_temperature",
"temperature": 22
}
}
4. 出発前にクライメートを開始する
{
"name": "tesla_command",
"arguments": {
"command": "start_climate"
}
}
5. 目的地にナビゲートする
{
"name": "tesla_command",
"arguments": {
"command": "share",
"destination": "Golden Gate Bridge, San Francisco"
}
}
📚 ドキュメント
認証フロー
┌─────────────────────────────────────────────────────────────────┐
│ クライアント (Alice App, Claude Desktop) │
│ │ │
│ │ Authorization: Bearer <BEARER_TOKEN> │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Cloudflare Worker / Node.js Server │ │
│ │ │ │
│ │ 1. BEARER_TOKEN を検証する (クライアント認証) │ │
│ │ 2. TESSIE_ACCESS_TOKEN を使用する (内部APIキー) │ │
│ │ │ │
│ │ env.TESSIE_ACCESS_TOKEN ──┐ │ │
│ │ env.TESSIE_VIN ───────────┼──► TessieClient │ │
│ │ │ │ │ │
│ │ │ ▼ │ │
│ │ │ api.tessie.com │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
要点:
BEARER_TOKEN: あなたが生成するランダムなトークン — クライアントをMCPサーバーに認証するために使用
TESSIE_ACCESS_TOKEN: あなたのTessie APIキー — サーバー内部で使用
- クライアントはあなたのTessie資格情報を決して見ることはありません。
HTTPエンドポイント
| エンドポイント |
メソッド |
目的 |
/mcp |
POST |
MCP JSON-RPC 2.0 |
/health |
GET |
ヘルスチェック |
開発
bun dev
bun run typecheck
bun run lint
bun run build
bun start
アーキテクチャ
src/
├── shared/
│ └── tools/
│ ├── tesla-state.ts # 車両の状態を取得する
│ └── tesla-command.ts # コマンドを実行する
├── services/
│ └── tessie.service.ts # Tessie APIクライアント
├── schemas/
│ ├── commands.ts # コマンド定義
│ ├── outputs.ts # ツール出力スキーマ
│ └── tessie.ts # Tessie APIレスポンススキーマ
├── config/
│ └── metadata.ts # サーバーとツールの説明
├── index.ts # Node.jsエントリーポイント
└── worker.ts # Workersエントリーポイント
環境変数
Node.js (.env)
| 変数 |
必須 |
説明 |
TESSIE_ACCESS_TOKEN |
✓ |
Tessie APIアクセストークン |
TESSIE_VIN |
✓ |
テスラ車両のVIN |
BEARER_TOKEN |
✓ |
MCPクライアント用の認証トークン |
PORT |
|
サーバーのポート (デフォルト: 3000) |
HOST |
|
サーバーのホスト (デフォルト: 127.0.0.1) |
AUTH_ENABLED |
|
認証を有効にする (デフォルト: true) |
AUTH_STRATEGY |
|
bearer (デフォルト) |
Cloudflare Workers (wrangler.toml + シークレット)
wrangler.tomlの変数:
AUTH_ENABLED = "true"
AUTH_STRATEGY = "bearer"
シークレット ( wrangler secret put で設定):
BEARER_TOKEN — クライアント用のランダムな認証トークン
TESSIE_ACCESS_TOKEN — Tessie APIアクセストークン
TESSIE_VIN — あなたの車両のVIN
KV名前空間:
[[kv_namespaces]]
binding = "TOKENS"
id = "your-kv-namespace-id"
トラブルシューティング
| 問題 |
解決策 |
| 401 Unauthorized |
BEARER_TOKEN が設定されていること、およびクライアントが Authorization: Bearer <token> を送信していることを確認してください。 |
| "TESSIE_ACCESS_TOKEN not configured" |
シークレットを設定してください: wrangler secret put TESSIE_ACCESS_TOKEN |
| "TESSIE_VIN not configured" |
シークレットを設定してください: wrangler secret put TESSIE_VIN |
| "Tessie API error" |
TESSIE_ACCESS_TOKEN が developer.tessie.com で有効であることを確認してください。 |
| 車両が見つからない |
TESSIE_VIN が正しいことを確認してください (17文字)。 |
| 車両がオフライン |
車両がディープスリープ中の可能性があります。コマンドを実行すると起動します (約30秒かかります)。 |
| コマンドがタイムアウトする |
Tessieは車両の起動を最大90秒待機します。再度試してください。 |
| KV名前空間エラー |
wrangler kv:namespace create TOKENS を実行し、wrangler.toml を更新してください。 |
| "ReadableStream is not defined" |
Node.jsのバージョンが古い可能性があります (18以上が必要)。新しいバージョンのNodeのフルパスを使用してください。 |
| "spawn bunx ENOENT" |
Claude Desktopが bunx を見つけられない場合があります。代わりに npx を使用してください。 |
デバッグ
MCPインスペクターでテストします。
bunx @modelcontextprotocol/inspector
Workerのログを確認します。
wrangler tail
📄 ライセンス
MIT