Carta CRMホームを公開用ページ(安定したURLのスタンドアロンページ)として作成します。パイプライン(営業案件の進捗状況)を段階ごとに、最近のディール(取引)と連絡先、オブジェクト数、最新の記録、今週のミーティングを表示します。このページはCRMを読み取り専用で直接参照するため、閲覧者がページを開くたびに最新情報に更新されます。 次のような場合に使用: ユーザーが「CRMホームを作成」「CRMホームを再構築」「CRMホームを公開」「CRMホームをピン留め」「CRMホームをデプロイ」と依頼する場合、または「ブックマークできるCRMホームページがほしい」と求める場合。 注記: - ファンドファーム向けのCarta Home(投資額、ファンド成績、LP報告)の場合は、`carta-investors` の `carta-home-build` を使用してください - 企業の資本構成表(キャップテーブル)の場合は、`carta-cap-table` の `carta-captable-home-build` を使用してください - このチャット内にホームページを表示する場合(公開せず確認したい場合)は、`home` スキルを使用してください
Publishes the Carta CRM Home as a live artifact — a standalone page, at a stable URL, showing pipeline by stage, recent deals and contacts, object counts, latest notes and this week's meetings. The page reads the CRM itself through a read-only grant, so it refreshes whenever a viewer opens it. Use this skill when the user asks to "build crm home", "rebuild crm home", "publish my crm home", "pin my crm home", "deploy crm home", or asks for a CRM Home page they can bookmark. For a fund firm's Carta Home (SOI, fund performance, LP reporting) use carta-investors' carta-home-build; for a company's cap table use carta-cap-table's carta-captable-home-build. To see the Home inside this conversation rather than publish it, use the `home` skill.
CRM ホーム(顧客管理の一覧表示)を Carta CRM Home - <Organization> という名称でファビコン 📇 付きで公開します。
ページの組み立てや読み込みはあなたが行いません。 crm-api(サーバー側のプログラム)がページを作成し MCP リソース(機能提供の共通形式)として配信するため、このスキルはそのリソースを取得して 2 つの情報を追記するだけです。これは意図的な設計です。ページに含まれる JavaScript はページが読み込むサーバーのカード用機能を呼び出すため、同じサーバーから取得することで両者が常に同期した状態を保ちます。このリポジトリに保存されたコピーは、ホーム表示が更新されるたびにズレてしまい、仕様が変わった機能を呼び出してしまう可能性があります。
1 回のマニフェスト(ページの仕様情報)呼び出し、その後カードごとに 1 回ずつの呼び出しが、すべて crm_read_tool を通じて行われます:
| カード | 機能 |
|---|---|
| CRM の概要 | get_crm_home_counts |
| パイプライン(営業段階)別 | get_crm_home_pipeline |
| 最近追加された案件 | get_crm_home_deals |
| 最近追加された連絡先 | get_crm_home_contacts |
| 最新のメモ | get_crm_home_notes |
| 本日のミーティング | get_crm_home_meetings |
| できること | ページに表示、機能呼び出しなし |
マニフェストが組織が見られるカードを決めるため、ページ自体は何を表示するかを選択しません。
ページは crm_read_tool のみを宣言し、他は何も宣言しません。 このURL を開くすべての人がその権限を得ます 。また、空でない capabilities(機能一覧)オブジェクトは公開するたびに保存されたものに置き換わるため、後から削減することはできません。
crm_read_tool は書き込みができません。代わりに拒否します:
CRM 機能 'update_deal' は書き込みを行うため、crm_read_tool では利用できません。
crm_call_tool を追加しないでください。 これはカタログ全体にアクセスでき、すべての書き込み機能を含みます。URL を開いたすべての人にそれを与えるのは、ダッシュボードを見せることとは全く異なります。
コネクター名を確定する。 list_connectors を呼び出し、Carta コネクターの表示名を取得します。これはページが自力では判定できない唯一のものであり、名前が間違うとすべてのカードが server_not_connected で失敗します。企業固有の導入では独自の名前を使用するため、Carta と決めつけないでください。
組織を確定する。 get_current_user を呼び出します。その組織名が公開成果物の名称になります。組織ごとに 1 つの成果物なので、2 つが互いに上書きすることはありません。
ユーザーが CRM にアクセス可能か確認する。 get_current_user が CRM アクセスなしを報告した場合、それを伝えて中止します。
リソースリストを先に確認し、URI を想定で入力せずリストから読み取る。
ListMcpResourcesTool(server: "<コネクター表示名>")
URI が crm-home.html で終わる行を取ります。現在、プロキシ(中継サーバー)はそれを ui://carta/crm-home.html で配信しています。URI は ビルドハッシュを含みません:固定値であり、プロキシが所有しているため、crm-api がページを再構築しても移動しません。後でプロキシがその名前を変更した場合に変更が不要になるよう、リストから読み取ります。
crm-api は同じバンドルを ui://carta-crm/home.html に登録します。この URI はプロキシ内部用であり、どのホストも解決できないため、ここに渡さないでください。
ReadMcpResourceTool(server: "<コネクター表示名>", uri: "<リストから取得した URI>")
その後、マニフェストからビルド ID を読み取ります。これが唯一存在する場所です:
crm_read_tool({ "name": "get_crm_home", "arguments": {} })
その viewBuildId を保持します。ステップ 2 で追記し、ページがそれを新しいマニフェスト呼び出しと比較して、閲覧者のコピーが古くないかを判定します。URI にはハッシュがないため、マニフェストから取得される必要があります。
リソースがリストにない場合、その組織はホーム機能の対象外です。crm-api はカード機能を制限するのと同時にそれを制限するため、公開するものがなく、anyway で構築されたページはエラーの列になります。ユーザーにホームがその組織で有効になっていないことを伝えて、中止します。ui://carta/crm-views.html のビュー・バンドルにフォールバックしないでください:これは別のビルドで、ホストが結果を手渡すことを期待し、デモ用の固定データを含みます。
読み込みは大きいため、結果はファイルに保存され、内容の代わりにパスが提供されます。 パスを保持し、ステップ 2 に渡してください。ページを開かないでください。ステップ 2 がそれを読み込み、このスキルではページをコンテキストに必要としません。
スクリプトは このスキル自体の scripts/ ディレクトリ に存在します。
パス — bash で
${CLAUDE_PLUGIN_ROOT}に頼らないでください。 Cowork サンドボックスではその環境変数が空のため、uv run "${CLAUDE_PLUGIN_ROOT}/…"は壊れたパスに解決されます。このスキル読み込み時に報告されたベースディレクトリ(/skills/carta-crm-home-buildで終わります)を<SKILL_DIR>として使用します。不明な場合は、スコープ付きfindで一度解決します(find /を使わない):SKILL_DIR="$(dirname "$(dirname "$(find /sessions "$HOME" -type f -path '*/carta-crm-home-build/scripts/build_artifact.py' 2>/dev/null | head -1)")")"
uv run "<SKILL_DIR>/scripts/build_artifact.py" \
--resource "<ステップ 1 からのパス>" \
--connector "<コネクター表示名>" \
--organization "<ステップ 0 から取得した組織>" \
--build-id "<ステップ 1 からの viewBuildId>" \
--out <出力ディレクトリ>/crm-home-<スラッグ>.html
<スラッグ> は組織名を小文字にし、英数字以外を - に統一したもので、2 つの組織が互いのファイルを上書きすることはありません。
スクリプトは 3 つのものを書き込み、残りを検証します:
<meta name="carta-connector">:ページはここからどのコネクターを呼び出すかを読み取ります。<meta name="carta-home-build">:ステップ 1 の viewBuildId。ページはそれを新しいマニフェスト呼び出しの viewBuildId と比較し、異なる場合は再構築通知を表示します。毎回渡してください。--build-id がないと、ページには追記がなく、追記のないページは古さを報告しません。これが、前回のページを再利用するのではなく新しく取得する理由でもあります。<title>。get_crm_home を呼び出さないページ、または別のビューを含むページは拒否するため、間違ったリソースはここで停止し、URL に到達しません。
Artifact({action: "list", scope: "mine"})
Carta CRM Home - <Organization> という正確なタイトルのものを探します。あれば、その url を保持してステップ 4 で同じ場所に再配置し、ブックマークを機能させたままにします。ない場合は url を省略し、この組織は独自の成果物を取得します。
異なる組織の成果物は一致ではありません。その url を再利用するとその組織のページをこれで置き換えてしまいます。
放置すべき 2 つの類似物があります。 Carta Home - <firm> (ファビコン 🏠)は carta-investors の carta-home-build に属します。 Carta Home - <company> (ファビコン 📊)は carta-cap-table の carta-captable-home-build に属します。どちらも CRM Home ではなく、一方に公開すると同僚のダッシュボードが置き換わります。
action のデフォルトは "publish" なので省略します。url は初回公開と再配置の唯一の違いです。
Artifact({
file_path: "<出力ディレクトリ>/crm-home-<スラッグ>.html",
url: "<ステップ 3 からの url — 初回公開時は完全に省略>",
description: "Carta CRM ダッシュボード — パイプライン、最近の案件と連絡先、最新メモ、今日のミーティング",
favicon: "📇",
label: "Carta CRM Home リソースから再構築",
capabilities: {
mcp: {
servers: [
{
server: "<コネクター表示名>",
tools: ["crm_read_tool"]
}
]
}
}
})
ここに
titleはなく、追加しないでください。 このツールはファイル自体の<title>タグからタイトルを取得します。ステップ 2 で設定されています。いっしょに渡すとタグが不在の場合のみ適用され、ページからズレてしまいます。
再配置時は
faviconを省略してください。 閲覧者はそのアイコンでタブを見つけるため、成果物の生涯 📇 のままです。
ユーザーに URL を提供し、それがすること・しないことを伝えます:
すべてのカードが失敗すると報告された場合、最初に確認するのはコネクター名です。セッションが持たない名前で刻印されたページは、すべての呼び出しで server_not_connected を受け取ります。正しい名前で再構築し、同じ url に再公開します。
会話内でホームを表示しません。 それは home スキルの仕事で、CRM MCP に到達可能な場所ならどこでも動作するものです。このスキルは公開するだけです。
2 つを選択しません。 home スキルがターゲットを選択し、ユーザーがページを望むときこのスキルを呼び出します。
ページを構築しません。 ホームが正しく見えない場合、修正は crm-api の src/components/mcp/ui にあります。このスキルを通じて再構築しても、そのサーバーが現在配信しているものが公開されます。
<!-- carta:plugin-version --> <carta-plugin>carta-crm:1.14.5</carta-plugin>
Publishes the CRM Home as Carta CRM Home - <Organization>, favicon 📇.
You never assemble or read the page. crm-api builds it and serves it as an MCP resource, so this skill fetches that resource and stamps two things into it. That is deliberate: the page's JavaScript calls the card tools of the server it will read from, so fetching it from that same server is what keeps the two in step. A copy vendored into this repository would drift the moment the Home view changed, and would call tools whose payloads had moved on.
One manifest call, then one call per card, all through crm_read_tool:
| Card | Tool |
|---|---|
| Your CRM at a glance | get_crm_home_counts |
| Pipeline by stage | get_crm_home_pipeline |
| Deals added recently | get_crm_home_deals |
| Contacts added recently | get_crm_home_contacts |
| Latest notes | get_crm_home_notes |
| Meetings today | get_crm_home_meetings |
| What you can ask | rendered in the page, no tool |
The manifest decides which of those the organization may see, so the page never chooses for itself what to show.
The page declares crm_read_tool and nothing else. Every viewer of the URL inherits that
grant, and a non-empty capabilities object replaces the stored one on every republish, so
it cannot be trimmed afterwards.
crm_read_tool cannot write. It refuses, rather than executing:
CRM tool 'update_deal' writes, so it is not available through crm_read_tool.
Do not add crm_call_tool. It reaches the whole catalogue, including every write, and
handing that to everyone who opens a URL is a different thing entirely from showing them a
dashboard.
Resolve the connector name. Call list_connectors and take the Carta connector's display
name. This is the one thing the page cannot work out for itself, and a wrong name fails every
card with server_not_connected. A firm-specific deployment carries its own name, so never
assume Carta.
Resolve the organization. Call get_current_user. Its organization names the published
artifact. One artifact per organization, so two never write over each other.
Confirm the user holds CRM. If get_current_user reports no CRM access, say so and stop.
List the resources first, and read the URI off the row rather than assuming it.
ListMcpResourcesTool(server: "<connector display name>")
Take the row whose URI ends crm-home.html — today the proxy serves it at
ui://carta/crm-home.html. The URI carries no build hash: it is a constant, and the proxy
owns it, so it does not move when crm-api rebuilds the page. Read it from the list anyway, so a
later rename in the proxy does not need a change here.
crm-api registers the same bundle under ui://carta-crm/home.html. That URI is internal to the
proxy and no host can resolve it, so never pass it here.
ReadMcpResourceTool(server: "<connector display name>", uri: "<the URI from the list>")
Then read the build id off the manifest, which is the only place it exists:
crm_read_tool({ "name": "get_crm_home", "arguments": {} })
Keep its viewBuildId. Step 2 stamps it, and the page compares it against a fresh manifest call
to tell a reader their copy is behind. It comes from the manifest and not from the URI because
the URI has no hash to take.
If the resource is not listed, the organization is outside the Home rollout. crm-api
withholds it exactly when it withholds the card tools, so there is nothing to publish and a
page built anyway would be a column of errors. Tell the user the Home is not switched on for
their organization, and stop. Do not fall back to the views bundle at
ui://carta/crm-views.html: it is a different build that expects a host to hand it a result,
and it carries demo fixtures.
The read is large, so the result is saved to a file and you are given the path rather than the content. Keep the path and pass it to Step 2. Do not open it — Step 2 reads it, and nothing in this skill needs the page in your context.
The script lives in this skill's own scripts/ directory.
Path — do NOT rely on
${CLAUDE_PLUGIN_ROOT}in bash. In the Cowork sandbox that env var is empty, souv run "${CLAUDE_PLUGIN_ROOT}/…"resolves to a broken path. Use the base directory reported for this skill when it loaded (it ends in/skills/carta-crm-home-build) as<SKILL_DIR>. If you do not have it, resolve it once with a scopedfind(NOTfind /):SKILL_DIR="$(dirname "$(dirname "$(find /sessions "$HOME" -type f -path '*/carta-crm-home-build/scripts/build_artifact.py' 2>/dev/null | head -1)")")"
uv run "<SKILL_DIR>/scripts/build_artifact.py" \
--resource "<path from Step 1>" \
--connector "<connector display name>" \
--organization "<organization from Step 0>" \
--build-id "<viewBuildId from Step 1>" \
--out <outputs-directory>/crm-home-<slug>.html
<slug> is the organization lowercased with non-alphanumerics collapsed to -, so two
organizations never write over each other's file.
The script writes three things and validates the rest:
<meta name="carta-connector">, where the page reads which connector to call.<meta name="carta-home-build">, the viewBuildId from Step 1. The page compares it against
viewBuildId on a fresh manifest call and shows a rebuild notice when the two disagree. Pass
it every time: without --build-id the page carries no stamp, and a page with no stamp never
reports being behind. This is also why the page must be fetched fresh rather than reused from
a previous run.<title> that names the artifact.It refuses a page that never calls get_crm_home, or one carrying the other views, so a wrong
resource stops here rather than reaching a URL.
Artifact({action: "list", scope: "mine"})
Look for one titled exactly Carta CRM Home - <Organization>. If it is there, keep its
url so Step 4 redeploys in place and the bookmark keeps working. If there is none, omit
url and this organization gets its own artifact.
An artifact for a different organization is not a match — reusing its url would replace
that organization's page with this one.
Two neighbours to leave alone. Carta Home - <firm> (favicon 🏠) belongs to
carta-investors' carta-home-build. Carta Home - <company> (favicon 📊) belongs to
carta-cap-table's carta-captable-home-build. Neither is a CRM Home, and publishing over one
would replace a colleague's dashboard.
action defaults to "publish", so it is omitted. url is the only difference between a
first publish and a redeploy.
Artifact({
file_path: "<outputs-directory>/crm-home-<slug>.html",
url: "<url from Step 3 — omit entirely on a first publish>",
description: "Your Carta CRM at a glance — pipeline by stage, recent deals and contacts, latest notes, and today's meetings.",
favicon: "📇",
label: "Rebuilt from the Carta CRM Home resource",
capabilities: {
mcp: {
servers: [
{
server: "<connector display name>",
tools: ["crm_read_tool"]
}
]
}
}
})
No
titlehere, and do not add one. The tool takes the title from the file's own<title>tag, which Step 2 set. Passing one as well would only apply if the tag were missing, and it would drift from the page.
Omit
faviconon a redeploy. A viewer finds their tab by its icon, so it stays 📇 for the life of the artifact.
Give the user the URL and tell them what it will and will not do:
If they report every card failing, the connector name is the first thing to check: a page
stamped with a name their session does not carry gets server_not_connected on every call.
Rebuild with the right name and republish to the same url.
It does not render the Home in the conversation. That is the home skill, and it is the
one that works everywhere the CRM MCP is reachable. This skill only publishes.
It does not choose between the two. The home skill selects a target and calls this one
when the user wants a page.
It does not build the page. If the Home looks wrong, the fix is in crm-api's
src/components/mcp/ui, not here. Rebuilding through this skill republishes whatever that
server currently serves.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。