Claude
Skills
Sign in
Back

carta-consolidating-balance-sheet

Included with Lifetime
$97 forever

Generate a consolidating Balance Sheet for all entities under a firm for a given month and write it as a side-by-side Excel tab with Assets / Liabilities / Equity sections and a Total column. Sourced from Carta MCP (firm/entity resolution + DWH SQL). TRIGGER when the user asks for "balance sheet of all entities of [firm] for [month]", a consolidating BS by entity, or to replicate the "Balance Sheet - consolidating" tab format for a different firm/period. Trigger phrases include "consolidating balance sheet", "BS by entity", "balance sheet of all entities". DO NOT TRIGGER for single-entity BS, P&L / income statement (carta-consolidating-pnl), new budgets (carta-create-budget), pulling Carta-stored budgets (carta-fetch-budget), refreshing actuals (carta-budget-actuals), pacing (carta-budget-vs-actuals), or what-if (carta-budget-scenarios).

Backend & APIsassets

What this skill does


[PATTERN carta-writing-style v0.0.2]
[PATTERN etiquette v0.0.6]
[PATTERN text v0.0.8]
[PATTERN tables v0.0.12]
[PATTERN carta-watermark v0.0.10]
[PATTERN base v0.1.0]

# Consolidating balance sheet

Generates a side-by-side Balance Sheet across every entity under a firm for a
single month, matching the "Balance Sheet - consolidating" tab format. The
data is pulled live from Carta's DWH via the Carta MCP connector — nothing is
embedded in the skill.

This skill runs primarily inside the **Claude for Excel** add-in. The audience
is an accountant working in their workbook, not an engineer running CLI
commands.


## When to use

Trigger this skill when the user asks for any of the following:

- "Give me the balance sheet of all the entities of `<FIRM>` for `<MONTH>`"
- "Consolidating balance sheet for `<FIRM>`"
- "BS by entity for `<FIRM>` `<MONTH>`"
- Any request to replicate the "Balance Sheet - consolidating" tab structure
  for another firm/period

Do **NOT** use this skill for:

- Single-entity balance sheets (use a plain trial-balance / GL query instead)
- P&L / income statement requests (use the **carta-consolidating-pnl** skill)
- Historical multi-period BS (this skill is point-in-time, single month)

## UX Rules

This skill ships as a standalone Claude for Excel skill, so the Carta CLI
session-start hook does **not** apply. The following rules — normally enforced
globally by the hook — are the skill's own responsibility here:

- **Speak plain English to the user.** The audience is an accountant.
  Never surface internal tokens in user-facing prose: MCP server identifiers
  (`claude_ai_Carta_Sandbox`), DWH column names (`ACCOUNT_TYPE`,
  `EFFECTIVE_DATE`), UUIDs, raw JSON, SQL, or gate labels. Those belong in
  Claude's own reasoning, not on screen.
- **Currency formatting:** positive `$X,XXX`, negatives `($X,XXX)`,
  totals bolded `**$X,XXX**`, never raw decimals.
- **Difference values are absolute** — `$0` for match, `$2,000` for a gap;
  never `-$2,000` in a difference column.
- **Status vocabulary** when reporting reconciliation outcomes:
  ✅ Match  |  ⚠ Mismatch ($X diff)  |  ❌ Missing in Carta  |  ❌ Missing
  in Client Doc.
- **Citation links** — when pointing to the resulting Excel range, format as
  `[A1:I65](<citation:Balance Sheet - Acme Mar-26!A1:I65>)` so the user
  can jump into the workbook. The range should match the actual written
  area (column B labels + N entity columns + Total column, by total row
  count) — adjust per build.
- **No environment URLs.** This skill builds Excel output, not Carta web
  links. There is no `BASE_URL` to construct.

## Environment detection (Claude for Excel)

This skill does **not** call `carta auth-status` — that command isn't
available inside the Excel add-in. Instead, the active Carta environment is
detected at Gate 0 from the connected MCP server's prefix
(`mcp__claude_ai_Carta_<Env>__fetch`). Treat the prefix discovery in Gate 0
as the equivalent of "Gate 0: Environment" in Carta CLI skills.

## Inputs to collect

Before running, confirm with the user:

1. **Firm name** — must match a firm reachable from the active Carta MCP
   context (resolved fuzzily). Example: `Acme Ventures`.
2. **Month** — format as `YYYY-MM` (e.g. `2026-03` for March 2026). The
   period is **cumulative as-of month-end** by default, not month-only
   activity (see `references/schema.md` for why).

If the user gave both in the request (e.g. *"balance sheet of all entities of
Acme Ventures for March 2026"*), proceed without re-asking.

---

## Execution discipline

Execute all gates silently. Do not narrate tool calls, intermediate results, or status updates. Only speak at explicit decision points: Gate 2 (entity scope picker), Gate 5 (pre-build review and approval), Gate 6 (output destination), and Gate 8 (post-action menu).

---

## Entry mode — fresh session vs. chained skill

Before Gate 0, check whether these context variables are already set from an earlier skill call in the same session (e.g. chained from `carta-consolidating-pnl`):

- `<SERVER>` — connected Carta MCP server prefix
- `<FIRM_NAME>` and `<FIRM_UUID>` — the resolved firm

**If both are in context:** skip Gate 0 entirely. In Gate 1, skip the `contexts:list` lookup — but still call `set_context(firm_id=<FIRM_UUID>)` with the already-known UUID to re-anchor the MCP session scope (a prior skill's scope can be reset by a new turn or connector refresh between invocations), then proceed to `fa:list:entities` to enumerate entities for Gate 2.

**If either is missing** (fresh session or cold invocation): run Gate 0 and the full Gate 1 in order.

Do not ask "which firm?" when it is already established from the skill the user just ran.

---

## Gate 0: Identify the Carta MCP environment

1. Call `refresh_mcp_connectors`. Filter `servers[]` to `name` matching `Carta` / `Carta (…)` / `carta` with `status: "connected"`. Drop `failed`.
2. For each connected candidate, probe both prefix forms in parallel: `mcp__claude_ai_Carta__welcome` and `mcp__carta__welcome`. First success = `<SERVER>`.
3. **Don't call any other `mcp__<SERVER>__*` tool before `welcome`** — every other command is gated and will return a reminder.

If none connected, list `failed` connectors and stop. If multiple, default to `Carta` (production). Don't probe every prefix in `allowed-tools` — only `connected` ones.

---

## Gate 1: Resolve the firm and its entities

1. `fetch(command="contexts:list", params={"firm_name": "<FIRM>"})` to find
   the firm. If multiple matches, present them via `AskUserQuestion` and
   confirm.
2. `set_context(firm_id=<uuid>)` to scope the session.
3. `fetch(command="fa:list:entities")` to enumerate **every** entity under
   the firm.

Prefer the granular tool when the server exposes it — one fewer hop, sidesteps `fetch`'s param-shape quirks:

| Granular tool | Generic equivalent |
|---|---|
| `mcp__<SERVER>__list_contexts(firm_name="<entity>")` | `fetch(command="contexts:list", params={"firm_name": "<entity>"})` |
| `mcp__<SERVER>__set_context(firm_id="<uuid>")` | `fetch(command="set_context", params={"firm_id": "<uuid>"})` |

For DWH queries (`dwh:execute:query`, `dwh:list:tables`, `dwh:get:table_schema`) there is **no granular equivalent** — always go through `fetch(command="…", params={…})`.

Each entity returned from step 3 (`fa:list:entities`) has the display name, `entity_id`, and a type field (e.g. `entity_type` — usually one of `FUND`, `GP`, `MANAGEMENT_COMPANY`, `SPV`, `HOLDING`, depending on the firm's structure). Cache the full list — Gate 2 reads from it.

**DWH param-name traps** — these cost a retry every time:
- `dwh:execute:query` takes `sql:`, **not** `query:` (the trailing `:query` in the command name is not the param key).
- `dwh:get:table_schema` takes `table_name:`, **not** `table:`.

Don't query `FUND_ADMIN` for entity metadata; the JE table is denormalized
and `FUND_NAME` is on every row.

**Done when:** the firm is locked and the full entity list (with type, if
available) is cached.

---

## Gate 2: Choose entity scope

Before pulling data, ask the user which entities to include. The default
("All entities") matches the legacy consolidating-BS behavior; the others
let the accountant trim noise from the output before any Excel write
happens.

Show a short summary first so the user knows what they're choosing from:

> **6 entities found under Acme Ventures:**
> - **Funds (3):** Acme Fund I, Acme Fund II, Acme Opportunity
>   Fund
> - **Other (3):** Acme Co-Invest (SPV), Acme GP LP (GP),
>   Acme SPV-1 (SPV)

(Group entities by `entity_type` if the field is available; otherwise
group by name pattern — common fund-name tokens are `Fund`, `LP`, `LLC`
with `Fund` in the name. Be conservative — when in doubt, surface the
entity in "Other".)

Then ask via `AskUserQuestion`:

```
Which entities should the Balance Sheet include?
1 - All entities (6)  ← recommended
2 - Funds only (3) — only fund-type entities
3 - Pick from a list — choose specific entit

Related in Backend & APIs