◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Cowork
◈ Cowork/2026-04-29中級

Cowork mode の Artifacts で「毎朝開く1ページ」を設計する — MCP連携で生きたダッシュボードを作る方法

毎朝同じ問いをClaudeに投げていませんか。Cowork modeのArtifactsとMCP連携で、未対応メールやレビュー待ちPRの確認を1クリックに集約する生きたダッシュボードを設計します。MCP応答を先にプローブする理由、実装サンプル、つまずきやすい落とし穴3つ、育てる運用まで解説します。

cowork16artifactsmcp20dashboardautomation55

「昨日と同じ問いを、今日もまたClaudeに投げている」— そんな感覚に思い当たる方は多いのではないでしょうか。受信トレイの未対応メール件数、レビュー待ちのプルリクエスト、進行中のタスクの優先度。これらは毎日変わる情報なので、一度の回答では翌朝にはもう古くなっています。

Cowork mode の Artifacts は、この「同じ問いの繰り返し」を解消するために用意された機能です。チャットの一回答を、再オープン可能な専用ページに昇格させ、開くたびにMCP連携で最新データを取りに行かせる設計ができます。今回はこのArtifactsを「毎朝開く1ページ」として育てるための設計手順を、実例とともに整理してみました。

チャットの一回答と Artifacts の決定的な違い

通常のチャット応答は、その瞬間のスナップショットです。Slackで未読メッセージを集計してもらった3秒後に新しいメッセージが届けば、もうその回答は古いということになります。一方、Artifactsはコードと表示が永続化された独立ページであり、window.cowork.callMcpTool 経由で開くたびに最新データを取得できます。

私が実際に使い分けているのは次のような基準です。

  • 一回答で十分なケース: 概念の説明、過去データの分析、一度きりのまとめ
  • Artifacts にすべきケース: 翌日も翌々日も同じ問いを投げる予感があるもの、データが時間で変化するもの、複数のMCPの結果を1ページに集約したいもの

「またこれ聞きそうだな」と感じたら、それはArtifacts化のサインです。

設計を始める前にMCPの応答を必ず一度プローブする

Artifacts開発で最初につまずくのは、MCPツールの返り値の形が想像と違っていることです。Slack MCPの「メッセージ取得」が返すJSONの構造、Linear MCPの「タスク一覧」のフィールド名は、各サービスの公式APIとは微妙に異なる場合があります。

なので、Artifactsを書く前にチャットでそのMCPツールを最小ペイロードで一度実行し、生レスポンスを観察するのが鉄則です。

// プローブ後、観察した形に合わせてパーサーを書く
const response = await window.cowork.callMcpTool({
  server: "slack",
  tool: "search_messages",
  args: { query: "in:#alerts", limit: 10 }
});
 
// MCPラッパーがcontent[0].textにJSON文字列を入れている場合
const data = typeof response.content?.[0]?.text === "string"
  ? JSON.parse(response.content[0].text)
  : response;
 
// 公式APIなら data.messages だが、ラッパーで data.results に変わっていることもある
const items = data.results ?? data.messages ?? [];

ここで「とりあえず公式APIのドキュメント通りに書く」と、本番で空配列が返ってきて沈黙する事故を起こします。実際に私もLinear連携で半日溶かしました。

実装サンプル: 朝イチで開く「未対応の集約ページ」

ここでは Slack の未読アラートと Linear の自分宛タスクを1ページにまとめる例を示します。

<div id="root">
  <h2>今朝の未対応</h2>
  <section id="slack"><p>読み込み中…</p></section>
  <section id="linear"><p>読み込み中…</p></section>
</div>
<script>
async function loadSlack() {
  const r = await window.cowork.callMcpTool({
    server: "slack",
    tool: "search_messages",
    args: { query: "in:#alerts after:yesterday", limit: 20 }
  });
  const data = JSON.parse(r.content?.[0]?.text ?? "{}");
  const items = data.results ?? [];
  document.getElementById("slack").innerHTML = items.length
    ? `<h3>Slack #alerts (${items.length}件)</h3><ul>${
        items.map(m => `<li>${m.user}: ${m.text}</li>`).join("")
      }</ul>`
    : "<h3>Slack: クリーン ✅</h3>";
}
async function loadLinear() {
  const r = await window.cowork.callMcpTool({
    server: "linear",
    tool: "list_my_issues",
    args: { state: "open" }
  });
  const data = JSON.parse(r.content?.[0]?.text ?? "{}");
  const items = data.issues ?? [];
  document.getElementById("linear").innerHTML = `<h3>自分宛タスク</h3>${
    items.map(i => `<div>${i.priority} - ${i.title}</div>`).join("")
  }`;
}
Promise.all([loadSlack(), loadLinear()]).catch(e => {
  document.getElementById("root").insertAdjacentHTML(
    "beforeend",
    `<p style="color:#c00">読み込み失敗: ${e.message}</p>`
  );
});
</script>

このページを毎朝1クリックで開けば、その瞬間のSlackとLinearの状態が手元に揃います。

つまずきやすい落とし穴3つ

実装中によく遭遇する問題と、その対処を共有しておきます。

1. MCPがコネクトされていない状態で開いた時の挙動

ユーザーがあとからアカウントを切り替えるとMCPが切断状態になり、callMcpTool がエラーを返します。私は必ずページ全体を try/catch で囲み、エラー時は「再接続が必要です」と表示する設計にしています。空白画面が出ると「壊れた」と感じてしまうので、明示的なフォールバックが大事です。

2. データ取得が遅いと「壊れたページ」に見える

複数のMCPを並列で叩くと、遅い方に引きずられて全体表示が遅くなります。Promise.all ではなく、各セクションが個別に「読み込み中→結果」に切り替わるように Promise.allSettled で並行ロードするほうがユーザー体験が良くなります。

3. ブラウザストレージは絶対に使えない

localStorage や sessionStorage はArtifactsの実行環境でサポートされていません。状態を保持したい場合はメモリ上の変数で十分なケースがほとんどですが、もしどうしても永続化が必要なら、その状態自体をMCP側(連携サービスのカスタムフィールドやNotionページなど)に保存する設計に切り替えます。

Artifactsを「育てる」運用パターン

一度作ったArtifactsは、使いながら少しずつ改良していくのが現実的です。私が運用しているリズムはこうです。

最初の1日は最小機能だけで開きます。Slackの未読件数だけ、Linearのタスク一覧だけ、というように1セクションから始めます。2〜3日使ってみて「ここに優先度フィルタがあれば便利だ」と感じた時点でClaudeに「このArtifactsに優先度フィルタを追加して」と頼み、update_artifact で差分更新します。

完成形を最初から作ろうとすると、MCPの応答形式の確認ができていない箇所で詰まります。動くものを最小で作り、毎日の利用で見えてきた改善点だけを足していくほうが、結果的に早く実用ダッシュボードに育ちます。

Cowork スケジュールタスクの設計ガイド と組み合わせると、夜間にデータをLinearやNotionへ集約しておき、朝はArtifactsを開くだけで全体が見えるという二段構えの運用も可能になります。

全体を振り返って — 今日の小さな一歩

Artifactsを使い始める最も簡単な入り口は、「いま現在チャットで返してもらっている定期的な質問」を1つ選び、それをArtifactsに昇格させることです。完璧な設計を考える前に、最も繰り返し聞いている問いを1つだけ取り上げて、最小機能のArtifactsにしてみてください。

5分でできる小さなページが、明日からの確認業務を確実に短縮してくれます。

Artifactsは「Claudeに問い続ける関係」から「Claudeと作ったページに毎朝向き合う関係」への転換点だと感じています。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◈ Cowork2026-08-23
コネクタが使えない朝に、待つのか人に返すのかを分ける三つの状態
無人実行でコネクタに届かないとき、原因は起動途中・未認証・恒久欠落の三つに分かれます。それぞれ正しい対処が正反対になる理由と、待機予算を切り分ける判定器の実装をまとめました。
◈ Cowork2026-05-04
Cowork スケジュールタスクが黙って止まる理由と、自動で立ち直る仕組みの作り方
Coworkのスケジュールタスクが黙って止まる原因を、実測した終了コードとエラー文で切り分けます。safe.directory が失敗を遅らせる仕組み、書ける場所を先に決めるプリフライト、理由コード付きログまで扱います。
◈ Cowork2026-10-08
毎回読ませる指示ファイルを半分にした夜、削る前に3つの引き出しへ分けました
指示ファイルが長くなるほど、書いたはずの決まりごとが守られなくなります。毎回読ませる分を半分にするため、残す・移す・捨てるの3つに分けた基準と、見出しごとの大きさを測る小さなスクリプトをまとめます。