• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialproductivity

carta-crm-home-build

プラグイン
carta-crm
ソース
GitHub で見る ↗
説明

Carta CRM ホーム(顧客管理画面)をライブアーティファクト(リアルタイムで更新される埋め込み資料)として公開します。独立したページとして安定した URL で表示され、営業段階ごとのパイプライン、最近の取引と連絡先、オブジェクト数、最新のメモ、今週の会議が一目でわかります。このページは読み取り専用のアクセス権で CRM データを直接参照するため、閲覧者がページを開くたびに最新の情報に自動更新されます。 次のような場合に使用: ユーザーが「CRM ホームを作成」「CRM ホームを再構築」「CRM ホームを公開」「CRM ホームをピン留め」「CRM ホームをデプロイ」と要求した場合、またはブックマーク可能な CRM ホームページを求めている場合。 **その他の関連スキル:** - ファンド会社向けの Carta ホーム(投資案件概要、ファンド成績、出資者向けレポート)の場合は `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 ホームを公開ページとして作成する
  • 営業パイプラインと取引情報を一覧確認する
  • ブックマーク可能な CRM ホームページが必要
  • 最新の顧客データをリアルタイム表示する
本文(日本語訳)

Carta CRM Home — 公開

CRM Home を Carta CRM Home - <Organization> というタイトルで公開します。ファビコン(ページタブに表示されるアイコン)は 📇 です。

このページを組み立てたり読み込んだりすることはありません。 crm-api がページを構築して MCP リソース(接続されたサーバーから取得できるデータやファイル)として配信するため、このスキルはそのリソースを取得して 2 つの情報を書き込むだけです。これは意図的な設計です。ページの JavaScript はそれが読み込むサーバーのツールを呼び出すため、同じサーバーから取得することで、ページとサーバーを同期させたままにします。このリポジトリにコピーを保管すると、Home ビューが変わった瞬間にズレが生じ、仕様が変わったツールを呼び出してしまいます。

ページの動作

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 を開くすべての人にそれを渡すことは、ダッシュボードを見せることとはまったく異なります。

ステップ 0: 確認事項

コネクター名を解決する。 list_connectors を呼び出し、Carta コネクターの表示名を取得します。これはページが自分では確認できない唯一のことで、間違った名前はすべてのカードを server_not_connected エラーで失敗させます。会社固有のデプロイ環境には独自の名前が付いているため、Carta と仮定しないでください。

組織を解決する。 get_current_user を呼び出します。その結果の組織名が公開されたアーティファクトの名前になります。1 組織につき 1 つのアーティファクトなので、互いに上書きされることはありません。

ユーザーが CRM アクセス権を持つことを確認する。 get_current_user が CRM アクセス権がないと報告した場合は、ユーザーに通知して停止します。

ステップ 1: ページとそのビルド ID を取得する

最初にリソースをリストして、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 から取得される理由は、URI にはハッシュがないためです。

リソースがリストにない場合、 その組織は Home ロールアウト(段階的な機能展開)外です。crm-api はカードツールを保留するときとまったく同じタイミングでそれを保留するため、公開するものはなく、とにかく構築されたページはエラーのカラムになります。その組織では Home がオンになっていないことをユーザーに告知して停止します。ui://carta/crm-views.html にあるビューバンドルにフォールバックしないでください。これは別のビルドで、ホストが結果を渡すことを期待し、デモ用の固定データを含んでいます。

読み込みは大きいため、結果はファイルに保存され、コンテンツではなくパスが提供されます。パスを保持して、ステップ 2 に渡します。ファイルを開かないでください。 ステップ 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 と比較し、2 つが異なるときに再構築通知を表示します。毎回渡します。--build-id なしでは、ページは印が付いていない状態になり、印が付いていないページは古いことを報告しません。これは、以前の実行から再利用するのではなく、ページを新しく取得する必要がある理由です。
  • <title> アーティファクトに名前を付けます。

get_crm_home を呼び出さないページ、または他のビューを含むページは拒否するため、間違ったリソースはここで停止し、URL に到達しません。

ステップ 3: 既に公開されている CRM Home を見つける

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 ではなく、1 つを上書きして公開すると、同僚のダッシュボードが置き換わります。

ステップ 4: 公開する

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 がそれを設定しました。1 つを同時に渡すと、タグが欠落している場合にのみ適用され、ページからズレます。

再デプロイの場合は favicon を省略します。 ビューアーはアイコンでタブを見つけるため、アーティファクトの有効期間全体で 📇 のままです。

ステップ 5: 動作確認

ユーザーに URL を提供し、それが何をできて何ができないかを説明します:

  • リアルタイムに読み込むため、スナップショットではなく、開くたびに現在のデータです。
  • CRM に書き込むことはできません。
  • 共有したすべての人がそれを通じて CRM データを読み込みます。これを明確に説明します。

すべてのカードが失敗すると報告する場合、コネクター名が最初に確認すべきことです。セッションが持っていない名前で刻印されたページは、すべての呼び出しで server_not_connected エラーになります。正しい名前で再構築し、同じ url に再公開します。

このスキルが行わないこと

会話内で Home をレンダリング(描画)しません。 これは home スキルが行うことで、CRM MCP に到達できるすべての場所で動作するものです。このスキルは公開するだけです。

2 つの間で選択しません。 home スキルはターゲットを選択し、ユーザーがページを希望するときにこれを呼び出します。

ページを構築しません。 Home の見た目が間違っている場合、修正は crm-api の src/components/mcp/ui にあり、ここではありません。このスキルを通じて再構築すると、そのサーバーが現在配信しているものがすべて再公開されます。

原文(English)を表示

<!-- carta:plugin-version --> <carta-plugin>carta-crm:1.15.0</carta-plugin>

Carta CRM Home — publish

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.

What the page does

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 grant, and why it is this narrow

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.

Step 0: Gates

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.

Step 1: Fetch the page and its build id

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.

Step 2: Stamp the page

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, so uv 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 scoped find (NOT 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 "<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.
  • the <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.

Step 3: Find an already-published CRM Home

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.

Step 4: Publish

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 title here, 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 favicon on a redeploy. A viewer finds their tab by its icon, so it stays 📇 for the life of the artifact.

Step 5: Confirm it works

Give the user the URL and tell them what it will and will not do:

  • It reads live, so it is current whenever they open it, not a snapshot.
  • It cannot write to their CRM.
  • Anyone they share it with reads their CRM data through it. Say this plainly.

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.

What this skill does not do

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 による自動翻訳です。