🏃‍♂️

「Tableau MCP」をリモートMCPとしてCloud Runにデプロイしてみた

に公開

どうも。カスタマーサクセスマネージャーの玉井です。

Tableauユーザーの間で、そりゃもうめちゃくちゃ話題になっている公式のTableau MCPサーバーですが、実はDocker版も提供されています。ということで、これをコンテナマネージドサービス[1]のCloud Runにデプロイして、実際に使えるかどうか試してみたいと思います。

やってみた

環境

  • MacBook Pro
    • Apple M1 Pro
    • macOS 15.6.1
  • gcloud(関係あるものだけ記載)
    • Google Cloud SDK 534.0.0
    • cloud-run-proxy 0.5.0
  • Docker 28.1.1
  • Tableau Cloud
    • 米国西部Pod
  • Cursor 1.5.9
    • MCPクライアントとして使用
    • 使用LLMはgpt-5

前提

  • 手元でパッと検証するのが目的なので、それ前提で進めます。
    • セキュリティにあまりよくない手順もあるかもしれません。
  • 今回使用したGoogle Cloud環境ですが、大人の事情でセキュリティがすごく厳しいので、ちょっと変な設定をしています。
    • ちゃんとした環境で使用する場合、もっとちゃんとした[2]設定の方が良いと思っています(後述)。
  • 今回はGoogle Cloudのすべての操作をコマンドで行います。
    • 各種APIはすでに有効化されている前提です。
  • MCPとTableau Cloudとの接続は「接続済みアプリ」を使用します。
    • 接続済みアプリは既に設定済。
  • デプロイしたMCPへのアクセスはCloud Runプロキシ[3]を使用します(後述)。
  • MCPクライアントはCursorを使います。

Google Cloud環境周りの設定

シェル変数[4]を設定する

今回はその場で変数を持ちます。

export PROJECT_ID="<Google CloudプロジェクトID>"
export REGION="asia-northeast1"
export SERVICE_NAME="tableau-mcp"
export AR_REPO_NAME="tableau-mcp-repo"

Artifact Registryリポジトリを作成する

今回はArtifact Registryにコンテナイメージを入れて、そこからデプロイしたいので、まずはリポジトリを作成します。

gcloud artifacts repositories create ${AR_REPO_NAME} \
  --repository-format=docker \
  --location=${REGION} \
  --project=${PROJECT_ID}

Dockerの認証設定をする

Google Cloudの認証情報(gcloudコマンドでログインしているユーザーアカウント)を使ってDockerの認証情報を自動的に設定してくれるように、この設定をしておきます。

gcloud auth configure-docker ${REGION}-docker.pkg.dev --project=${PROJECT_ID}

Tableau MCPのビルド→デプロイ

コンテナイメージをビルドする

それでは、手元でTableau MCPのイメージをビルドっていきます。ちなみに、私の環境では、Apple Siliconのせいなのか、--platform linux/amd64を付けないとエラーになりました。

docker build --platform linux/amd64 -t ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${SERVICE_NAME}:latest .

コンテナイメージをプッシュする

ビルドったイメージをプッシュります。

docker push ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${SERVICE_NAME}:latest

Cloud Runにデプロイ

いよいよ、Cloud Runへデプロイしてみます。このデプロイ時に、Tableau MCPの設定(≒接続するTableau CloudかTableau Serverの情報)もします。今回は一番雑な方法である「コマンドにずらずら値を記述する」というセキュアもクソもない方法でやります。

gcloud run deploy ${SERVICE_NAME} \
  --image=${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${SERVICE_NAME}:latest \
  --region=${REGION} \
  --platform=managed \
  --ingress=all \
  --no-allow-unauthenticated \
  --set-env-vars="TRANSPORT=http,SERVER=<TABLEAU_SERVER_URL>,AUTH=direct-trust,JWT_SUB_CLAIM=<TABLEAU_USERNAME>,CONNECTED_APP_CLIENT_ID=<CONNECTED_APP_CLIENT_ID>,CONNECTED_APP_SECRET_ID=<CONNECTED_APP_SECRET_ID>,CONNECTED_APP_SECRET_VALUE=<CONNECTED_APP_SECRET_VALUE>,SITE_NAME=<TABLEAU_SITE_NAME>"

--set-env-varsで設定している値が、接続するTableau Cloudの情報となります。

環境変数名 説明 設定例
TRANSPORT MCPサーバーの通信プロトコル。Cloud RunでHTTPサーバーとして動作させるため http を指定します。 http
SERVER 接続先のTableau CloudまたはTableau ServerのURL。 https://10az.online.tableau.com/
AUTH Tableauへの認証方式。接続済アプリを利用する場合は direct-trust を指定します。 direct-trust
JWT_SUB_CLAIM 認証に利用するJWTのsub(Subject)クレーム。通常、Tableauのユーザー名を指定します。 user@example.com
CONNECTED_APP_CLIENT_ID Tableauサイトで作成したConnected AppのクライアントID。 386370e7-626c-4914-98f7-6b6c2a88ef52
CONNECTED_APP_SECRET_ID Connected AppのシークレットID。 38fea7f9-55d9-42ae-a8a1-897ac3156363
CONNECTED_APP_SECRET_VALUE Connected Appのシークレット値。 rs3VfNJXTvpCAtjfWLPrOaYM10RLaGRYxxd0zboD2xM=
SITE_NAME 接続先のTableauサイト名。Defaultサイトの場合は不要です。 yoursitename

コンテナ側の設定ですが、--ingressallにしています。これについては後述します。

これまた、一応、マネコンでも確認してみます。


デプロイしたTableau MCPへの接続

今回はgcloud run services proxyを使用してMCPに接続したいと思います。

上記のドキュメントに書いてある通りなのですが、これを使うと、ローカルホスト上でサーバーを実行し、Cloud Runへのリクエストをプロキシ処理するのですが、その際、認証情報が自動的に付与されるため、この機能を使用してIAM認証で保護された状態でテストできます。

そして、これまた上記ドキュメントに書いてありますが、このプロキシは--ingressinternalの状態では使えないため、今回allとしてデプロイしています。

プロキシを起動する

というわけで、プロキシを起動します。MCPを使用中の間、このコマンドは実行しっぱなしにしておく必要があります(別窓推奨)。

gcloud run services proxy ${SERVICE_NAME} --region=${REGION} --port=8080

Cursorの設定

前述した通り、今回はMCPクライアントとしてCursorを使ってみたいと思います。mcp.jsonに以下のように記述します。

mcp.json
{
  "mcpServers": {
    "tb": {
      "type": "streamable-http",
      "url": "http://localhost:8080/tableau-mcp"
    }
  }
}

サーバーの名称をtbにしている理由ですが、どうもCursor側の仕様(?)として、「名前とツールの名称合わせて60字以上だとうまく動作しない(Warningが出てくる)」というのがあるっぽく、当初はtableau-mcp-proxyとかにしていたのですが、これだと結構長くなるため、激短くしてみました。

Tableau MCPに色々と聞いてみる

以前試してみたときより、できることが多くなっているので、改めていろいろ聞いてみました。基本的にかなり雑なプロンプトでやってみた、という前提で見てみて下さい。

まず、どんなデータソースがあるのか聞いてみます。

聞き方が雑すぎたので、まずは「一般的なTableauが対応しているデータソース」を教えてくれました(違う、そうじゃない)。

…が、その後、ちゃんと私のTableau Cloudの情報を返してくれました。

ただ、ちょっと情報が少ないため、それを指摘してみました。そんな謝らんでも…。

データカタログ的な使い方を試してみました。一見ちゃんと返してくれてるようですが、よく読むと推測でしかなかった…。

以前にはなかった機能として、Vizの画像を表示できるらしいので、やってみました。お〜。

ちなみに、画像を表示した後、その流れでデータに対する質問をすると、画像に引っ張られます(画像の表示範囲内だけのデータで計算しようとする)。

改めて指示すると、ちゃんと計算しますが、まさかの不正解。

間違いを指摘して、再計算させたところ、やっと正解しました。

使用するクライアントやLLMで結果はいくらでも変わりそうなので、一概に言えませんが、ちょっと前より精度がアレになったかも…?

注意事項など(課題)

Tableau側のユーザー認証

現在のTableau MCPは、PATであれ接続済アプリであれ、「MCPが使用するTableau Cloud(またはServer)のユーザー」は1人固定となっています。ですので、リモートMCPとして使う場合、色々な人が「代表1人のユーザーの権限」を使ってTableauにアクセスすることになります。ちょっとデータガバナンス的にアレかと思います。

できれば、動的というか、「MCPを使う人が持っているTableauユーザー」の権限でMCPを使用できるようになればとても良くなるのになあ、と思いました(それこそ行レベルセキュリティとかも効いたりするので)。

Cloud Run側のセキュリティ

今回はプロキシでの簡易接続での検証しかやってませんが、本番利用を想定するなら、ロードバランサーを置いて、IAP (Identity-Aware Proxy) でアクセス制御を行う等の方法を検討する必要があると思います。

感想

とりあえず、コンテナのマネージドサービスで動くことが確認できてよかったです。
私は面倒だったのでやりませんでしたが、Tableau Serverでも使えますので、ぜひトライしてみてください。

おまけ

ZennにAIレビューなるものがあったのでやってみました。



うるせーーーーーーーー!!!!!!!!!!!(とても便利な機能でした)

脚注
  1. こういう呼称で合っているのか自信無し。 ↩︎

  2. 語彙力がヤバい ↩︎

  3. これまた呼称があっているか不明 ↩︎

  4. シェル変数と環境変数の違いを分かっていないので厳密にはどっちなのか不明 ↩︎

Discussion