作ったダッシュボードを人に見せたら、数字が先週のままだった。アーティファクトは公開した時点のスナップショットなので当然なのだが、毎回作り直すのも面倒で放置していた。2026年7月17日の更新で、この部分が変わった。同時に、共有できる範囲も変わった。
閲覧されるたびにデータを取りに行く
claude.ai に公開したアーティファクトが、MCP コネクタを呼び出してライブデータを取得できるようになった。ページのロード時に取得し、インターバル指定かページ内の操作で再取得する。取得したレスポンスは閲覧者のブラウザにキャッシュされ、次に開いたときはキャッシュを描いてから新しいデータで更新する。
従来のアーティファクトは CSP によって fetch も XHR も WebSocket も全面的に遮断されていて、外部からデータを取る経路がゼロだった。今回追加されたのは、その CSP の唯一の例外として「ページが claude.ai にコネクタ呼び出しを委譲する」経路だ。ページ自身が通信するのではなく、claude.ai が代わりに呼ぶ。
対象になるのは claude.ai アカウントに接続したコネクタだけだ。.mcp.json に書いたローカルの MCP サーバーは、ページを組み立てる最中のデータ供給には使えるが、公開後のページからは呼べない。
必要なバージョンは Claude Code v2.1.209 以降。それ以前で公開したものは従来どおりスナップショットになる。
細かい点だが、v2.1.207 から v2.1.212 の changelog に、アーティファクト関連の項目が1つも立っていない。週次ダイジェストと専用ドキュメントには載っているのに changelog には出てこない。changelog だけを追っている人は、この機能に気づけない。
誰の資格情報で動くのか
ここの設計が面白い。呼び出しは閲覧者自身のコネクタを通る。
同じダッシュボードを2人が開くと、それぞれのアカウントの権限に応じて中身が変わる。公式ドキュメントは「ページは誰の資格情報も見ない」と明記していて、型定義側にも「呼び出しは閲覧者の資格情報で実行され、あなたのコードがトークンを見ることはない」と書かれている。
最初のコネクタ呼び出しの前に、claude.ai が閲覧者に許可を求める。拒否した人や、そのコネクタを接続していない人には、ライブ部分が欠けた状態でページ自体は表示される。拒否はそのページロードの間だけ有効で、リロードすると再度聞かれる。
副作用のあるアクションも同じ仕組みで動く。メッセージ投稿や Issue 更新をボタンにでき、押した人のアカウントで実行される。
作者が閲覧者のデータを見られるかという疑問に対して、ドキュメント上の答えは No だ。呼び出しは閲覧者のアカウントと閲覧者のブラウザ内で完結し、作者側には返らない。ただし作者はページに任意の JavaScript を書ける立場なので、取得したデータをページ内でどう扱うかは作者のコード次第になる。ドキュメントはこの点に明示的に触れていない。外部送信は CSP で塞がれているものの、頭には置いておきたい。
なお承認ダイアログに具体的に何が表示されるかは、一次ソースに記載がない。文言もスクリーンショットも公開されていなかった。
ライブになった代わりに、配れなくなった
ここが本題だ。
コネクタを呼ぶアーティファクトは、どのプランでもパブリックリンクで共有できない。
Team と Enterprise は「非公開」か「組織内共有」を選べる。Pro と Max は公開リンクが唯一の共有手段なので、コネクタを使った時点で本人限定になる。
個人開発者にとっての意味は、はっきりしている。これは自分専用の動くダッシュボードだ。顧客に URL を渡して見てもらう用途には使えない。
この記事も、動くデモへのリンクを置けない。読者に試してもらうには、再現できるプロンプトとスクリーンショットを示すしかない。制約そのものが、この機能の性格を表している。
管理側のトグルも2系統ある。機能そのものの ON/OFF が Settings の Claude Code の Capabilities にあり、コネクタ呼び出しの可否が Settings の Capabilities にある「Enable artifact connectors」で決まる。後者は claude.ai の会話から作ったアーティファクトも同じトグルが支配する。Team と Enterprise ではパブリック共有が既定で OFF になっていて、Owner が External sharing で解禁する形だ。
実際に書くコード
公開ドキュメントには JavaScript のサンプルが載っていない。公式の例は自然言語のプロンプトだけだ。
Build a dashboard artifact of our open pull requests that pulls the live
list through my GitHub connector when the page loads.
実際の API 契約は、Claude Code に同梱されているスキルの型定義ファイルが正準になっている。関数は用途で分かれていて、表示用が watchTool、アクション用が callTool。補助として、閲覧者が実際に接続しているコネクタを調べる listTools() と、書き込み後にキャッシュを落とす invalidate() がある。
// 可用性の確認はメンバーチェックで行う(呼び出して探るのは不可)
if (window.claude?.mcp) {
const stop = window.claude.mcp.watchTool(
"GitHub", // コネクタの「表示名」
"list_pull_requests",
{ owner: "acme", repo: "web", state: "open" },
(ev) => {
if (ev.type === "data") {
render(ev.result.payload);
// 「最終更新」は cache.storedAt から取る
if (ev.result.cache) showStale(ev.result.cache.storedAt);
} else {
// エラーは code で分岐する。message の文言で分岐しない
switch (ev.error.code) {
case "server_not_connected":
fallback("claude.ai の Settings → Connectors で GitHub を接続してください");
break;
case "needs_reauth":
fallback("GitHub の再認証が必要です");
break;
case "server_unavailable":
keepLastGoodData();
break;
default:
fallback("データを取得できませんでした");
}
}
},
{ refetchInterval: 60000 }
);
}
型定義に明記されているアンチパターンがある。全部のエラーを1つの汎用バナーに潰すことだ。server_not_connected と needs_reauth は、何度リトライしても成功しない。閲覧者が接続を追加するか再認証するという行動を取らないと解決しないからだ。何をすればいいかを個別に出す必要がある。
定義されているエラーコードは17種類ある。上の3つに加えて、ポリシーで止められた blocked_by_policy、宣言外のツールを呼んだ not_in_manifest、閲覧者が同じ表示名のコネクタを複数持っている selection_required あたりは実際に出うる。選択を促すプロンプトは、アーティファクトのバージョンごとに最大1回しか出ない。
書き込み側はこうなる。
try {
const res = await window.claude.mcp.callTool("GitHub", "create_issue_comment",
{ owner: "acme", repo: "web", issue_number: 42, body: "LGTM" });
await window.claude.mcp.invalidate("GitHub", "list_pull_requests");
} catch (e) {
if (e.code === "tool_error") showError(e.message);
}
リトライは retryable: true が付いたものだけ、しかも読み取りのみ。server_unavailable や upstream_error は書き込みでは結果が不明で、既に実行されている可能性がある。ここを機械的にリトライすると二重投稿になる。
watchTool は読み取り専用と決まっていて、readOnlyHint: false のツールを渡すと reject される。表示とアクションの境界が型で守られている。
先に知っておきたい上限
- 1ビューあたり
watchToolの登録は64件まで refetchIntervalは約30秒がフロア。ページ非表示の間は停止し、復帰時に追いつくstaleTimeの上限は5分、gcTimeは既定5分・上限24時間- 応答予算は約130秒、レンダリング後のページは16MiB 以下
- 単一の自己完結ページのみ。
.html/.htm/.mdに限られ、相対リンクは使えない - バックエンドは持てない。独自 API は叩けない
- Anthropic API 経由のみ。Bedrock や Google Agent Platform、Microsoft Foundry では使えない
- CMEK・HIPAA・ゼロデータ保持が有効な組織では利用不可
呼び出し回数の数値クォータは公開されていない。rate_limited というエラーコードは定義されているが、現在は発火せず予約状態になっている。
組織のポリシーでツール単位の都度承認を要求する approval_required は、アーティファクトでは未サポートだ。該当するツールを使う場合は、劣化表示にするしかない。
手元で試すなら
公式の例は GitHub コネクタだが、接続していなければ試せない。筆者の claude.ai に繋がっているのは Gmail と Google カレンダーと Google ドライブの3つなので、試すならこちらになる。
読み取り専用で副作用がなく、watchTool と refetchInterval の挙動を見るには十分だ。カレンダーで今日の予定ボード、ドライブで最近更新されたファイル一覧あたりが素直だと思う。
この機能の性格を一番わかりやすく示せるのは、同じページを2つのアカウントで開いて中身が違うことを見せる実演だろう。作者が用意したのは器だけで、中身は開いた人のものになる。
EVE Online の統合ダッシュボードを作ったとき、市場・資産・戦闘・採掘・スキルを1画面に集めるのに OAuth のトークン自動リフレッシュまで自前で書いた。あの手間の大部分が、この仕組みでは要らない。認証は claude.ai 側が持っているからだ。代わりに、配れないという制約が付く。
筆者ならこう使う
AI の出力は読んでから受け取ることにしている。層の境界をまたぐコードを丸呑みすると後で必ず崩れるからだ。今回のように「認証は閲覧者側」「呼び出しは委譲」という境界が入る仕組みは、生成されたコードをそのまま信じずに、エラーコードの分岐だけは自分で確認したい。
用途としては、自分だけが見る運用ダッシュボードに向いていると考えている。配布を前提にした資料には使えない。この線引きさえ間違えなければ、認証まわりを書かずに動くものが手に入るのは大きい。
MCP を使った開発についてはOAuth認証つきダッシュボードを自作した記事でも扱っている。まずは自分が claude.ai にどのコネクタを繋いでいるか、Settings から確認してみてほしい。