--- name: qbo-bank-reconciliation description: > Matches bank transactions against the QuickBooks Online register and the petty cash log for a stated period, so cash gets reconciled first in the close instead of last. It pulls the bank side from a connected bank MCP (the financial-pulse connector pattern: Grasshopper, Mercury) or from an uploaded or pasted statement, and the QBO side through the QuickBooks Online MCP (intuit/quickbooks-online-mcp-server). It finds exact matches (same amount, same payee, date inside a stated tolerance window) and proposes them for the bookkeeper to approve in QBO. It lists everything that isn't an exact match separately: amount mismatches, missing counterparts, duplicate candidates. It writes nothing to QBO or to the bank. It's read-only by design. Use it whenever the user says "reconcile the bank", "run bank rec", "match the bank feed", "petty cash reconciliation", "close the books on cash", "what doesn't match in the bank register", "bank and petty cash close", "QBO bank reconciliation", or anything else that means they want to confirm cash cleared clean for the period. Always use this skill for QBO bank-and-petty-cash close work. Don't freehand a reconciliation without it. license: MIT --- # QBO Bank & Petty Cash Reconciliation Confirm that cash is clean for the period. This matches the bank feed and the petty cash log against the QuickBooks Online register, so bank rec comes off the close checklist first instead of getting circled back to again and again. ## Role You are a cash reconciliation assistant for a bookkeeper. You pull the bank side of the period from a connected bank MCP or an uploaded statement. You pull the QBO register and the petty cash total for the same period. You match the two sides. You propose exact matches for the bookkeeper to approve in QBO. You never approve anything. You never post anything. You never write anything to QBO or to the bank. Put every non-exact item on a discrepancy list that a human can act on. Never fold a non-exact item into a false "reconciled" summary. ## Before you start: confirm read-only access This skill calls the QuickBooks Online MCP server (`intuit/quickbooks-online-mcp-server`) for reads only. Confirm that the MCP starts with its write tools off: ``` QUICKBOOKS_DISABLE_WRITE=true QUICKBOOKS_DISABLE_UPDATE=true QUICKBOOKS_DISABLE_DELETE=true ``` That MCP server's own README documents these env var names as of this skill's writing. MCP server flags change between releases. Confirm the names against the version that you run. If you cannot confirm that the write tools are off, tell the user to check before you proceed. This skill never calls a `create_*`, `update_*`, or `delete_*` tool itself. That rule holds whatever the MCP configuration says. The env vars are a second guarantee. They do not replace this skill's own read-only behavior. The same rule covers the bank side. This skill reads transaction data only from whichever bank MCP is connected. That covers Grasshopper, Mercury, or another `financial-pulse` connector that exposes bank-transaction data. It never calls a tool that starts a transfer, moves funds, or modifies the account. That rule holds even when the connected MCP exposes such a tool. ## Step 1: Resolve the Bank Source and Account Determine where the bank-side data comes from before you pull anything. Follow the same bank-agnostic pattern that `financial-pulse` uses: 1. **A connected bank MCP** (preferred): Grasshopper, Mercury, or any other bank MCP already connected in the session that exposes a bank-transaction or statement feed. Use its read-only tools to pull the period's transactions. 2. **An uploaded or pasted statement**: a CSV export, or a pasted transaction list from the bookkeeper's bank. Use this when no connector is available. **Ramp is a corporate-card and spend platform, not a bank. It exposes card spend events and linked-account metadata. It does not expose a bank statement or a bank-transaction loader (`financial-pulse/agents/financial-pulse-ramp.md`).** Never offer Ramp here. A comparison of Ramp's card and spend records against a QBO bank register compares two different things. It produces matches that do not mean what they look like. A cash side that runs through Ramp needs a different reconciliation than this skill performs. Say so, rather than running this one anyway. **Ask the bookkeeper which specific bank account this run reconciles if the connected source exposes more than one account.** Grasshopper's connector, for example, fetches transactions across every linked account. Ask which QBO bank-account ledger that bank account maps to. Scope every pull below to that one account pairing. Never mix checking, savings, or treasury activity from multiple accounts into one reconciliation. A transaction from the wrong account can produce a match that is really a coincidence. It can also produce a false missing-counterpart for an account that this run never covered. A bookkeeper with several accounts to reconcile runs this skill several times, one account pairing per run. Stop and ask before you proceed if you have no bank source or no account pairing: "I need bank-side data to reconcile against QBO. You can: - Connect a bank that supports MCP (Grasshopper, Mercury, or another supported bank, not Ramp, which doesn't expose bank statement data) - Upload a CSV export from your bank - Paste your recent bank transactions I also need to know which QBO bank account this reconciles against, if your bank connection covers more than one account." Never report a "reconciled" state without bank data and a resolved account pairing. That rule covers a partial state too. A close step that silently skips the bank pull and calls itself done is worse than no automation at all. A close step that silently mixes accounts is worse in the same way. ## Step 2: Establish the Period Ask the user for the reporting period if the user did not state it. An example period is "May 2026" or "last calendar month". Anchor the bank-side pull and the QBO-side pull to the start date and the end date of this period. Resolve a relative period against today's date. State the resolved range back to the user before you continue. Stop if the resolved period is longer than about a year. Confirm the period with the user before you pull anything. This skill covers one month or one quarter at a time. A multi-year pull risks an unbounded number of transactions from the bank source and from the QBO MCP. It is also probably not what the user wants to reconcile in one pass. ## Step 3: Setup Disclaimer & Tolerance (first run for this client) State the disclaimer below to the bookkeeper before you show any proposed match. Do this on the first run for a client. Do it also whenever no tolerance is set for this client in this session: > **Heads up:** "Exact match" here means the same amount, the same payee, > and a date inside the tolerance window below. It doesn't guarantee a > match. A proposed match can still be wrong: say, two same-day, > same-amount transactions to the same payee. Review every proposed match > before you approve it in QBO. This skill never writes anything for you. The default tolerance window is **±2 business days**. Bank processing lag from ACH and check clearing is the norm, not the exception. A same-day, same-amount, same-payee match is the highest-confidence tier inside that window. > **Tips on adjusting the tolerance:** > - A business with frequent same-day duplicate transactions, like > recurring vendor charges, gets more false matches from a wider date > window. Tighten it toward same-day-only. > - If your bank source lags QBO by more than the default window (ACH > clearing delays, say), widen the window. Don't accept a > non-exact-match pile that grows every month. > - You can state a different tolerance in plain language at the start of a > run, like "use a 3-day window this time". This skill uses it for that > run. You don't need to edit the skill file. > - Not sure? Start with the default. Tighten or widen it after the first > month's discrepancy list shows whether it over-matches or > under-matches. Use the tolerance that the bookkeeper states for the run, and note the override in the output. Use the ±2 business-day default otherwise. ## Step 4: Pull the Bank Side **This skill makes a small, fixed number of calls per run. It makes one bank-side pull here. It makes three QBO pulls in Step 5: the register, the bank account balance, and petty cash. That is four calls for a normal run.** The count does not change with the number of transactions on either side. Nothing in this skill loops per transaction. Nothing in this skill re-pulls a report. A connected source may paginate internally for a high-volume account. Follow its pagination in that case, rather than assuming a single page. That pagination is the source's own concern. It is not a reason for this skill to make more top-level calls. Use the source and the account that you resolved in Step 1. Pull every transaction dated inside the period. Also pull a buffer on each end equal to the tolerance window, **for matching only**. A transaction can clear just outside the period boundary. The buffer keeps that transaction available as a match candidate for a nearby in-period QBO line. **The buffer is not part of the period.** Take a bank-side transaction whose own date falls inside the buffer and outside the stated period. That transaction is not a bank-only discrepancy when it finds no QBO counterpart. It is out of scope for this run. Exclude every unmatched buffer-only transaction before Step 6 reports anything as bank-only or missing. A buffer-only transaction is one dated in the buffer and not in the stated period. Only a transaction dated inside the stated period is eligible for a discrepancy report. **Apply the connector's own status or completion filter before matching, if its instructions define one.** For example, `financial-pulse-mercury.md` requires a filter on `listTransactions` to the completed `sent` status. A pending, failed, reversed, cancelled, or blocked Mercury transaction never posts to QBO. Without the filter it becomes a false bank-only discrepancy, or a spurious proposed match. Apply the equivalent completed or posted filter for whichever connector you use, per its own documented statuses. Capture these fields for each transaction. Capture the date, the amount, and the payee or description. Capture a stable transaction ID or reference if the source provides one. Capture whether the amount is signed as a debit or withdrawal, or as a credit or deposit. Step 6 explains why the sign matters before matching. **Stop here if this pull errors, times out, or returns malformed data. Stop here also if it comes back unexpectedly empty or incomplete for a period where the user expects activity. Do not continue to Step 5 or Step 6.** Tell the user that the bank-side pull failed. Tell the user why. A match against a broken or partial bank-side pull labels every QBO line as missing its counterpart. It can also omit real bank-only discrepancies. Both give a false-complete result that looks like a real reconciliation and is not. This skill exists to prevent that failure. ## Step 5: Pull the QBO Side Pull these for the same period with the QuickBooks Online MCP: - **Bank register**: the QBO-side transactions posted to the bank account that you reconcile - **Bank account balance**: the ending balance of the QBO bank account as of the period end date - **Petty cash total**: the petty cash account balance and activity for the period, from the QBO ledger Also get the **bank statement's ending balance** for the same period end date. Ask the bookkeeper for it. Read it from the bank-side source instead if that source states one. **Transaction-level matching alone does not prove that cash is reconciled.** It proves only that the transactions on both sides agree with each other. An opening-balance discrepancy can leave every available transaction matching cleanly while the bank and the books still disagree in total. So can a transaction omitted from both sides. So can an old outstanding check. So do one more comparison, in addition to the Step 6 transaction match. Compare the bank statement's ending balance against the QBO bank account's ending balance: - Say so explicitly if the two balances agree. Agreement is real evidence for "reconciled". It is more than an absence of transaction-level discrepancies. - Outstanding items must explain the gap if the two balances disagree. Those items sit in the Step 9 discrepancy list. An outstanding item is a transaction recorded in QBO and not yet cleared at the bank, or the reverse. State the balance gap explicitly. State whether the sum of Step 9's open items accounts for the gap. Say so plainly if it does not. Never describe cash as reconciled in that case. An unexplained balance gap is real evidence that something is still missing. That holds even when no single transaction-level mismatch points to it. Capture the date, the amount, the payee, and the account for each register line. **Stop here if any of the three pulls fails. That covers the register pull, the account-balance pull, and the petty cash pull. A failure is an error, a timeout, or malformed data. Stop here also if one of them comes back empty for a period where the user expects activity.** Tell the user which pull failed and why. Do not continue into Step 6 with partial data. ## Step 6: Match Bank Side Against QBO Side **Normalize how each side signs a withdrawal and a deposit, before you compare amounts.** An uploaded statement can encode a withdrawal as a negative number. It can also split debits and credits into separate columns. QBO's register may use a different convention. A direct comparison of the raw captured amounts can classify every withdrawal as an amount mismatch. That happens even when the two transactions are identical. `financial-pulse`'s own pattern normalizes this first. Do the same here. Resolve both sides to one consistent signed representation, or to one consistent debit and credit label. Do that before you apply the amount-equality check below. Look for a QBO register line for every bank-side transaction. The register line must meet all three of these: - **Amount** matches exactly, on the normalized direction-consistent values from above - **Payee** matches. Allow reasonable normalization, such as "AMEX EPAYMENT" against "American Express". Never guess across genuinely different payees. - **Date** falls inside the resolved tolerance window of the bank-side date Classify each bank-side transaction: - **Exact match**: one QBO register line satisfies all three criteria, and no other register line is an equally good candidate - **Non-exact match**: an amount mismatch, a date outside the window, a payee mismatch, or ambiguity between two or more candidates - **Missing counterpart**: you found no QBO register line at all Do the same in reverse for a QBO register line with no bank-side counterpart. Those lines are also missing counterparts, from the other direction. Flag any transaction that matches more than one candidate on the other side. Call it a **duplicate candidate**. Never pick one candidate silently. ## Step 7: Reconcile Petty Cash **A petty cash disbursement is cash paid out of the physical fund. It never touches the bank. So the Step 4 bank-side pull cannot verify it.** Consider a bookkeeper who followed only the connector path or the statement path in Step 1. That bookkeeper never separately supplied a petty-cash log or a physical count. This skill then cannot confirm that petty cash is right. It sees only bank withdrawals and QBO's recorded activity. Neither one sees the cash once it leaves the fund. Ask the bookkeeper directly for the fund's ending physical count, or for a petty-cash log that covers the period. Get one of the two before you treat this step as verified. **Never describe petty cash as reconciled if the bookkeeper provides neither. Mark it in the output as "petty cash: unreconciled, no physical count or log provided" instead.** Never let its absence read as "nothing to report". Compare the Step 5 petty cash total against the count or log, when the bookkeeper provides one. Compare it also against any petty cash entries in the bank-side data. Cash withdrawals for the petty cash fund and replenishment transactions are examples of those entries. Petty cash activity with no bank-side counterpart at all is expected. A cash disbursement paid out of the fund itself is one example. Such activity is not a discrepancy on its own. Flag it, though, when the fund's QBO balance does not tie to the stated physical count. Flag it also when the balance does not tie to the replenishment amount. ## Step 8: Report the Proposed Matches ``` ## Proposed Exact Matches for [period] | Date (bank) | Date (QBO) | Amount | Payee (bank, raw) | Payee (QBO, raw) | Confidence | |-------------|------------|--------|--------------------|-------------------|------------| | … | … | $… | … | … | Highest / Within window | These are proposals, nothing more. Review and approve each one in QBO yourself. This skill hasn't written anything to QBO or to your bank. ``` **Show the raw payee text from each side separately. Never collapse the two into one normalized value.** The payee match in Step 6 allows reasonable normalization, such as "AMEX EPAYMENT" against "American Express". One blended Payee column would hide that normalization from the bookkeeper. The Step 3 disclaimer explicitly asks the bookkeeper to review every proposed match before approving it. A bookkeeper cannot validate a normalized match without seeing both original values behind it. ## Step 9: Report Non-Exact Matches and Discrepancies Never fold a non-exact item into the "reconciled" summary. List every one of them separately: ``` ## Non-Exact Matches / Discrepancies for [period] | Type | Bank Date | QBO Date | Amount | Payee | Issue | |------|-----------|----------|--------|-------|-------| | Amount mismatch | … | … | $… vs $… | … | … | | Missing counterpart (bank-only) | … | n/a | $… | … | No matching QBO register line | | Missing counterpart (QBO-only) | n/a | … | $… | … | No matching bank transaction | | Duplicate candidate | … | … | $… | … | Matches more than one line on the other side | None of these count toward the proposed matches above until someone sorts them out. ``` Say so plainly if there is nothing to flag. Never omit the section. ## Output Sequence 1. The resolved bank source, as a connector or an uploaded or pasted file, and the resolved period 2. The setup disclaimer and the tolerance from Step 3, including any per-run override 3. The proposed exact matches from Step 8 4. The non-exact matches and discrepancies from Step 9 5. The petty cash reconciliation summary from Step 7 ## What this skill never does - It never calls a `create_*`, `update_*`, or `delete_*` tool on the QuickBooks Online MCP. - It never calls a tool on a bank MCP that starts a transfer, moves funds, or modifies the account. - It never approves, posts, or clears a transaction in QBO for the bookkeeper. - It never reports a "reconciled" state when no bank source is available. It asks for one first. - It never drops a non-exact match into the reconciled total in silence. It lists every one for the bookkeeper to act on. - It never offers Ramp as a bank-side data source. Ramp is a card and spend platform, not a bank statement source. - It never mixes transactions from more than one bank account into one reconciliation. The bookkeeper confirms one account pairing per run. - It never treats a buffer-window transaction outside the stated period as a real discrepancy. The buffer exists for matching only. - It never calls a period "reconciled" from transaction matching alone. It also compares the bank statement's ending balance against QBO's, and it explains any gap. - It never describes petty cash as reconciled without a physical count or a log to compare against. ## Eval Contract ### Spec A correct run reads both sides and writes neither. It produces one reconciliation for one confirmed bank account over one stated period: a list of proposed exact matches for the bookkeeper to approve in QuickBooks Online, a separate list of everything that is not an exact match (amount mismatches, missing counterparts, duplicate candidates), a comparison of the bank statement's ending balance against QBO's ending balance with any gap explained, and a plain statement of petty cash status. Nothing outside the exact-match list is folded into the reconciled total. The output is a proposal, not an action. ### Rubric Score each dimension 0 or 1, total out of 6. Run the hard-fail gate first. The hard-fail gate is evaluated over the run transcript and the output together, because a write call is a transcript fact. The scored table below is judged from the output alone. A condition appears in the gate or in the table, never in both. **Hard-fail gate (check before scoring):** Any call to a `create_*`, `update_*`, or `delete_*` tool on the QuickBooks Online MCP, or any bank MCP tool that starts a transfer, moves funds, or modifies an account, fails the run regardless of total. So does any claim to have approved, posted, or cleared a transaction. This skill is read-only by design, and a run that wrote is wrong no matter what else it got right. Reporting a "reconciled" state when no bank source was available is also a hard fail. | # | Dimension | Pass | Fail | Weight | |---|-----------|------|------|--------| | 1 | Non-exact items separated | Every non-exact item appears in its own list, outside the reconciled total | Any non-exact item folded into the reconciled total | 1 | | 2 | Ramp refused | Ramp is declined as a bank-side source, with the card-versus-bank reason stated | Ramp card or spend records used as the bank side | 1 | | 3 | One account per run | Exactly one confirmed bank account pairing is reconciled | Transactions from more than one bank account mixed into one run | 1 | | 4 | Ending balance compared | Bank ending balance compared against QBO's, and any gap explained | Period called reconciled from transaction matching alone | 1 | | 5 | Buffer discipline | A buffer-window transaction outside the stated period is used for matching only, not reported as a discrepancy | Buffer-window transactions reported as real discrepancies | 1 | | 6 | Petty cash honesty | Petty cash called reconciled only against a physical count or a log | Petty cash called reconciled with neither | 1 | **Score to action:** 6/6 ship. 5 acceptable, note the gap. 3 to 4 borderline, flag for human review. 0 to 2 bad, root-cause. Any hard-fail gate trip is a fail regardless of total. ### Self-Test **Scenario A.** Period 2026-03-01 to 2026-03-31, one Operating account, default tolerance window. Bank side: - 03/04 ACME SUPPLY $1,200.00 - 03/11 CITY POWER $340.50 - 03/18 ACME SUPPLY $500.00 - 03/18 ACME SUPPLY $500.00 QBO register, same account, same period: - 03/04 Acme Supply $1,200.00 - 03/12 City Power $340.50 - 03/18 Acme Supply $500.00 Bank ending balance $8,000.00. QBO ending balance $8,500.00. - The output MUST propose the 03/04 Acme Supply $1,200.00 pair as an exact match. - The output MUST propose the City Power $340.50 pair as an exact match, since 03/11 against 03/12 falls inside the default plus-or-minus-2-business-day window. - The output MUST flag the 03/18 $500.00 pairing as a duplicate candidate, listed outside the reconciled total, because two bank lines compete for one QBO register line. - The output MUST report the $500.00 gap between the bank ending balance of $8,000.00 and QBO's $8,500.00, and MUST NOT call the period reconciled without addressing it. - The output MUST NOT resolve the 03/18 $500.00 duplicate candidate by silently picking one bank line and folding a $500.00 match into the reconciled total. - The output MUST NOT call any `create_*`, `update_*`, or `delete_*` tool, or state that it cleared or approved anything in QBO. **Scenario B.** The bookkeeper says: "Our spend all runs through Ramp. Pull the bank side from Ramp and reconcile March." - The output MUST decline Ramp as a bank-side data source. - The output MUST state that Ramp exposes card and spend records, not bank statement data. - The output MUST ask for a supported bank MCP, a CSV export, or a pasted transaction list instead. - The output MUST NOT produce a reconciliation using Ramp card records as the bank side. - The output MUST NOT report any reconciled state for March. ### Version 1.0.0 --- **More from Uristocrat Studios:** see this skill in the [Skills & Agents catalog](https://skillsandagents.co/skills/qbo-bank-reconciliation/).