Discover Commands
Use the command registry to find available commands when no specific skill covers the user's request. A prior discover call in this environment caches the full registry to disk — read that cache first and only hit the network on a miss.
Step 0 — Read the cached command registry (do this first)
The plugin's PostToolUse hook writes the full command registry to ${CLAUDE_PLUGIN_DATA}/cache/commands.json after any discover call. Read it before making any MCP call:
cat "${CLAUDE_PLUGIN_DATA}/cache/commands.json" 2>/dev/null || true
If the file exists and is valid, treat it as the command list and validate it before use:
- Freshness — the JSON has a
cached_at ISO timestamp. If cached_at is more than 24 hours old, treat the cache as stale and fall through to Step 1 (this matches the 24h TTL the welcome/accounts caches use).
- Version — the JSON has a
plugin_version. If it does not match the running plugin version (see the <carta-plugin version=… /> tag injected at session start), treat the cache as stale and fall through to Step 1.
- Shape — the command list lives under the
commands key (an array). If the file is empty, unparseable, or commands is missing/empty, fall through to Step 1.
When the cache is valid and fresh, skip Steps 1–2's network call — pick the best-matching command directly from the cached commands array (same name / description / inputSchema fields as the live search_tools result) and go straight to Step 3. This removes a network round-trip on warm sessions.
Step 1 — Search for Relevant Commands (cache miss / stale only)
search_tools({"query": "<keyword from user's request>"})
Use a keyword that captures the user's intent (e.g. "valuation", "grant", "safe", "stakeholder").
Step 2 — Pick the Best Match
Review the returned tools. Each has:
name: the tool name to pass to call_tool (e.g. cap_table__get__stakeholders)
description: what it returns
inputSchema: the required and optional parameters
Step 3 — Execute
call_tool({"name": "<tool_name>", "arguments": { ...params }})
You still need corporation_id for most commands — get it from list_accounts if you don't have it.
1---2name: carta-discover-commands3description: META-DISCOVERY ONLY — answers the question "what cap-table tools or commands exist?" when the user is lost about what's available. NEVER use this skill for any request that names a cap-table topic (stakeholders, grants, vesting, SAFEs, notes, valuations, ownership, waterfall, financing, exposure, etc.) — those are always direct data requests, even if the user phrases them vaguely. The matching specialist skill wins every time over this one.4---56<!-- carta:instrumentation-fallback -->7<IMPORTANT>8`_instrumentation_v2` is anonymous Carta skill-usage telemetry. ALWAYS include it in your Carta MCP tool-call arguments — the plugins' hooks overwrite it when they run, so always sending it is safe. Shape:9`_instrumentation_v2: {"skills": ["<plugin>:<skill>", ...], "model": "<model-id>", "surface": "<value>"}`10`skills` is cumulative for the session: list every Carta skill loaded so far, not only the one driving this call. Namespace each entry `"plugin:skill"` and keep them oldest-first, with the most recently used skill last. List only Carta skills (`carta-cap-table:*`, `carta-crm:*`, `carta-investors:*`) — never skills from non-Carta plugins.11`surface` is the Claude surface you are running in: `"chat"` (claude.ai or the Claude app, i.e. regular chat, not Cowork), `"cowork"` (Cowork mode), `"code-terminal"`, `"code-desktop"`, or `"excel"`. Omit it entirely if none of those describe your surface or you cannot tell — do not guess and do not invent another value.12</IMPORTANT>1314<!-- Part of the official Carta AI Agent Plugin -->1516# Discover Commands1718Use the command registry to find available commands when no specific skill covers the user's request. A prior `discover` call in this environment caches the full registry to disk — read that cache first and only hit the network on a miss.1920## Step 0 — Read the cached command registry (do this first)2122The plugin's PostToolUse hook writes the full command registry to `${CLAUDE_PLUGIN_DATA}/cache/commands.json` after any `discover` call. Read it before making any MCP call:2324```bash25cat "${CLAUDE_PLUGIN_DATA}/cache/commands.json" 2>/dev/null || true26```2728If the file exists and is valid, treat it as the command list and validate it before use:2930- **Freshness** — the JSON has a `cached_at` ISO timestamp. If `cached_at` is more than **24 hours** old, treat the cache as stale and fall through to Step 1 (this matches the 24h TTL the welcome/accounts caches use).31- **Version** — the JSON has a `plugin_version`. If it does not match the running plugin version (see the `<carta-plugin version=… />` tag injected at session start), treat the cache as stale and fall through to Step 1.32- **Shape** — the command list lives under the `commands` key (an array). If the file is empty, unparseable, or `commands` is missing/empty, fall through to Step 1.3334When the cache is valid and fresh, **skip Steps 1–2's network call** — pick the best-matching command directly from the cached `commands` array (same `name` / `description` / `inputSchema` fields as the live `search_tools` result) and go straight to Step 3. This removes a network round-trip on warm sessions.3536## Step 1 — Search for Relevant Commands (cache miss / stale only)3738```39search_tools({"query": "<keyword from user's request>"})40```4142Use a keyword that captures the user's intent (e.g. "valuation", "grant", "safe", "stakeholder").4344## Step 2 — Pick the Best Match4546Review the returned tools. Each has:47- `name`: the tool name to pass to `call_tool` (e.g. `cap_table__get__stakeholders`)48- `description`: what it returns49- `inputSchema`: the required and optional parameters5051## Step 3 — Execute5253```54call_tool({"name": "<tool_name>", "arguments": { ...params }})55```5657You still need `corporation_id` for most commands — get it from `list_accounts` if you don't have it.