# Carta Discover Commands

> 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.

- Skill: `carta/carta-discover-commands` (Agent Skill)
- Install (CLI): `npx skillmds@latest add carta/carta-discover-commands`
- Raw SKILL.md: https://api.skillmd.com/api/skills/carta/carta-discover-commands/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: carta (https://skillmd.com/u/carta)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/carta/carta-discover-commands

---


<!-- carta:instrumentation-fallback -->
<IMPORTANT>
`_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:
`_instrumentation_v2: {"skills": ["<plugin>:<skill>", ...], "model": "<model-id>", "surface": "<value>"}`
`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.
`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.
</IMPORTANT>

<!-- Part of the official Carta AI Agent Plugin -->

# 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:

```bash
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.

