# BennyBooks agent skill

Use BennyBooks when the user wants to inspect or propose bookkeeping work for a small company: list transactions, categorize spend, attach notes, link receipts, or run a month-end check.

Do not treat this as a full ERP. There is no payroll, inventory, tax filing, or multi-entity consolidation.

## Connect

Base URL: `https://bennybooks.com/api/v1`

```
Authorization: Bearer bb_live_<token>
```

Create tokens in the BennyBooks UI: Settings → MCP access. `read` can query. `propose-write` can create proposals (and includes read).

Public, no token:

- `https://bennybooks.com/llms.txt`
- `https://bennybooks.com/openapi.json` (includes agent instructions + `x-mcp` annotations)
- `https://bennybooks.com/api/v1/ontology.jsonld`

Success envelope: `{ "data": T, "meta"?: { … } }`. Errors: `{ "error": { "code", "message", "details?" } }`.

There is no hosted Streamable HTTP MCP endpoint on this origin. Import the OpenAPI spec into an MCP bridge (AnythingMCP is the documented path) or call REST directly. Enable **only** the curated tools below — not every OpenAPI operation.

## MCP design (keep agents efficient)

1. **Curated tools** — ~12 tools, not a 1:1 REST dump. Config: `config/anythingmcp-bennybooks.yaml`.
2. **Lean lists** — default `limit=50`; avoid large payloads in context.
3. **Read freely, write carefully** — writes create pending proposals until a human approves.
4. **Stable codes** — prefer `categoryCode` (e.g. `5100`) over display names.
5. **Compose reads** — `get_transaction` already returns notes + receipts; skip `list_notes` unless needed.
6. **Annotations** — OpenAPI `x-mcp.annotations` carry `readOnlyHint` / `destructiveHint` / `idempotentHint` for bridges that honor them.

Design guide: https://bennybooks.com/developers/guides/mcp-design.md

## Curated tools (enable these)

| Tool | Scope | Use when |
| --- | --- | --- |
| `get_ontology` | public | Load the public BennyBooks ontology (JSON-LD): chart codes, synonyms, and seed counterparties. |
| `list_categories` | read | Return this org's chart of accounts with stable codes, synonyms, and inUse flags. |
| `list_transactions` | read | List ledger rows for the token's organization. |
| `get_transaction` | read | Fetch one transaction plus linked notes and receipts. |
| `get_dashboard_summary` | read | Org financial snapshot and workload: revenue, expenses, cashPosition, uncategorized, missingReceipts, agentSuggested (pending proposals count), notifications. |
| `search_receipts` | read | Search receipt file names and OCR text by query string q. |
| `list_connectors` | read | Show bank/payment connectors with provider, lastSyncAt, and syncStatus (ok|error|stale). |
| `list_pending_proposals` | read | List agent proposals awaiting human approval. |
| `propose_categorization` | propose-write | Propose a category for an existing transaction. |
| `propose_journal_entry` | propose-write | Propose a new manual ledger row (date, amount, currency, description, optional categoryCode). |
| `propose_receipt_link` | propose-write | Propose linking an existing receiptId to a transactionId. |
| `attach_note` | propose-write | Propose attaching a free-text note to a transaction (approval-gated; audit-logged in Log). |

### Optional (off by default)

| Tool | Scope | Use when |
| --- | --- | --- |
| `get_ontology_context` | public | Public JSON-LD @context only. |
| `get_proposal` | read | Fetch one proposal by id. |
| `get_receipt` | read | Receipt metadata by id (not file bytes). |
| `list_notes` | read | Notes for a transactionId. |
| `create_note` | propose-write | Directly create a note without approval. |

## Hard rules

1. Prefer `categoryCode` (e.g. `5100`) over free-text category names.
2. Writes go to `/proposals/*` or `POST /notes` (proposal). Avoid `PUT /notes` unless trusted automation.
3. Never auto-post a journal entry. A proposal is not a posted transaction.
4. Stay inside the token's organization. There is no cross-tenant access — do not send `org_id`.
5. When you categorize, send `confidence` (0–1), `reason`, and optional `evidence[]`.
6. Write for humans: `reason`, `confidence`, and `evidence` are what reviewers see in Ledger → Approvals and the durable **Log** (`https://bennybooks.com/log`). There is no agent API to read Log in v1 — do not scrape the UI.

## Audit trail (Log)

Every propose-write and every human approve/reject is recorded in `audit_log` and shown in-app at **Log** (`https://bennybooks.com/log`).

| Human UI | Role |
| --- | --- |
| Ledger → Approvals | Decide pending proposals |
| Log (`/log`) | Durable history of agent writes + approval outcomes |

Tell the user: proposals are pending until approved; the action is also recorded in Log. Prefer short, specific `reason` strings over vague ones.

Guide: https://bennybooks.com/developers/guides/audit-log.md

## Workflows

### Categorize

1. `list_categories` (or public `get_ontology`) — learn codes, synonyms, counterparties.
2. `list_transactions` with `status=uncategorized&limit=50`
3. Match `description` to seed counterparties (AWS → `5300`, Figma → `5100`) or synonyms.
4. If unsure, `get_transaction` for notes and receipts.
5. `propose_categorization` with `transactionId`, `categoryCode`, `confidence`, `reason`, `evidence`.
6. Tell the user the change is pending in Ledger → Approvals and visible in Log.

### Investigate one transaction

`get_transaction` returns the row plus notes and receipts. Search unmatched files with `search_receipts`.

### Month-end

`get_dashboard_summary` then chase:

- `uncategorized` → `list_transactions` `status=uncategorized`
- `missingReceipts` → `list_transactions` `status=receipt_missing`
- pending proposals → `list_pending_proposals`
- connector health → `list_connectors` (`syncStatus`: `ok` | `error` | `stale`)

### Manual entry

`propose_journal_entry` with date, amount (negative = outflow), currency, description, optional `categoryCode`. Wait for approval; the propose action appears in Log.

## Evidence types

Use structured evidence when you have it: `counterparty_match`, `keyword`, `rule`, `historical`, `receipt`. Put the matching string in `value`.

## More

- Map: https://bennybooks.com/llms.txt
- Full docs: https://bennybooks.com/llms-full.txt
- HTML docs: https://bennybooks.com/developers
- Audit Log guide: https://bennybooks.com/developers/guides/audit-log.md
- AnythingMCP: https://bennybooks.com/developers/guides/anythingmcp.md
