show_balance
Get balance sheet entries (assets and liabilities) for a specific month or view all periods to identify trends.
Instructions
Stored balance sheet entries (assets + liabilities) by period. Each entry has type (asset|liability), sub_type (cash|investment|other|short_term|long_term), category, amount in USD, and the entry date. Without period, returns ALL periods — use this for trends; with period (YYYY-MM), returns one month's snapshot.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | Period filter e.g. "2025-03" |
Implementation Reference
- apps/mcp/src/tools/portfolio.ts:176-187 (registration)MCP server.tool() registration for 'show_balance' — defines the tool's name, description, input schema (optional period parameter), and handler logic that queries balance_entries from the database.
server.tool( 'show_balance', "Stored balance sheet entries (assets + liabilities) by period. Each entry has type (asset|liability), sub_type (cash|investment|other|short_term|long_term), category, amount in USD, and the entry date. Without `period`, returns ALL periods — use this for trends; with `period` (YYYY-MM), returns one month's snapshot.", { period: z.string().optional().describe('Period filter e.g. "2025-03"') }, async ({ period }) => { const db = getDb(); const rows = period ? db.select().from(balanceEntries).where(eq(balanceEntries.period, period)).all() : db.select().from(balanceEntries).all(); return ok(rows); }, ); - apps/mcp/src/tools/portfolio.ts:180-186 (handler)Handler function for 'show_balance' tool — accepts an optional period filter (YYYY-MM), queries the balanceEntries table, and returns all matching rows. If no period is given, returns ALL periods.
async ({ period }) => { const db = getDb(); const rows = period ? db.select().from(balanceEntries).where(eq(balanceEntries.period, period)).all() : db.select().from(balanceEntries).all(); return ok(rows); }, - packages/db/src/schema.ts:14-28 (schema)Drizzle ORM schema for the balance_entries table — defines columns: id, period, date, type (asset|liability), sub_type, category, amount, currency, memo, with a unique index on (period, type, sub_type, category).
export const balanceEntries = sqliteTable( 'balance_entries', { id: integer('id').primaryKey({ autoIncrement: true }), period: text('period').notNull(), date: text('date').notNull(), type: text('type').notNull(), sub_type: text('sub_type').notNull(), category: text('category').notNull(), amount: integer('amount').notNull().default(0), currency: text('currency').notNull().default('KRW'), memo: text('memo'), }, (t) => [uniqueIndex('balance_uq').on(t.period, t.type, t.sub_type, t.category)], ); - apps/mcp/src/index.ts:8-22 (registration)Top-level MCP server setup — imports and calls registerPortfolioTools(server), which registers 'show_balance' among other portfolio tools.
import { registerPortfolioTools } from './tools/portfolio.ts'; import { registerReportTools } from './tools/report.ts'; import { registerSnapshotTools } from './tools/snapshot.ts'; import { registerStockTools } from './tools/stock.ts'; import { registerPrompts } from './prompts.ts'; const server = new McpServer( { name: 'firma', version: FIRMA_VERSION }, { instructions: SERVER_INSTRUCTIONS }, ); registerPortfolioTools(server); registerReportTools(server); registerMutateTools(server); registerSnapshotTools(server); - Balance repository helper with CRUD operations for balanceEntries — provides getAll, getByPeriod, getPeriods, upsert, and deleteByPeriod methods used by other parts of the app.
const createBalanceRepository = (db: DbClient): BalanceRepository => ({ getAll: () => db.select().from(balanceEntries).all(), getByPeriod: (period) => db.select().from(balanceEntries).where(eq(balanceEntries.period, period)).all(), getPeriods: () => db .selectDistinct({ period: balanceEntries.period }) .from(balanceEntries) .orderBy(desc(balanceEntries.period)) .all() .map((r) => r.period), upsert: (entry) => db .insert(balanceEntries) .values(entry) .onConflictDoUpdate({ target: [ balanceEntries.period, balanceEntries.type, balanceEntries.sub_type, balanceEntries.category, ], set: { amount: entry.amount, currency: entry.currency, date: entry.date, memo: entry.memo }, }) .run(), deleteByPeriod: (period) => db.delete(balanceEntries).where(eq(balanceEntries.period, period)).run().changes, });