feat(api): expose bank-connection freshness in MCP and v1 REST (#2124)

* feat(api): expose bank-connection freshness in MCP and v1 REST

gnubok_connect_bank now returns last_synced_at, consent_expires and
error_message per connection, and its instructions tell the agent to
flag stale or expiring connections. New read-only endpoint
GET /api/v1/companies/{companyId}/bank-connections exposes the same
fields to API-key integrations (scope companies:read).

Background: a user's PSD2 feed died silently in July; bookkeeping
looked complete while three weeks stale, and nothing on the API/MCP
surface could reveal it. Sync stays cron-driven; an agent-triggerable
sync was considered and deferred (see DECISIONS.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USJHnxsindrs9X6zqQDLix

* fix(api): address skeptic findings on bank-connection freshness

- Map the bank-connections group into skills/accounted-api (apiskill:check
  crashed on the unmapped group; regenerated skill files included).
- Gate the v1 route on the bank_sync capability, mirroring the MCP twin:
  a lapsed entitlement now answers with a capability error instead of
  status=active with a frozen last_synced_at.
- Reword MCP instructions + v1 pitfalls: null last_synced_at right after
  connecting is normal, staleness threshold aligned to the UI's 36 hours,
  and re-authorisation is only advised for expired/error/consent-out, not
  for stale-but-active connections (lapsed subscription or deselected
  accounts are the usual causes there).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USJHnxsindrs9X6zqQDLix

* fix(mcp): keep gnubok_connect_bank schema under the tools/list token ceiling

The enriched outputSchema plus the worked examples that landed on main
(#2100) pushed the projected tools/list payload 20 tokens over the
61.6K context-budget ceiling. Drop the per-property descriptions from
the new freshness fields; the instructions string (runtime output, not
catalog payload) already explains them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USJHnxsindrs9X6zqQDLix

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-09-01 20:54:55 +02:00
committed by GitHub
co-authored by Claude Fable 5.1
parent a08bf51ced
commit b56da5d6c5
11 changed files with 453 additions and 14 deletions
+3 -2
View File
@@ -109,10 +109,11 @@ const GROUPS: Array<{ file: string; title: string; members: string[]; blurb: str
{
file: 'banking.md',
title: 'Banking',
members: ['transactions', 'cash-accounts', 'reconciliation', 'imports'],
members: ['transactions', 'cash-accounts', 'bank-connections', 'reconciliation', 'imports'],
blurb:
'Bank transactions (ingest, categorize, match against invoices), cash accounts with the ' +
'bank-reported balance, bank reconciliation runs, and file imports (SIE, bank statements).',
'bank-reported balance, PSD2 connection health (sync freshness, consent expiry), ' +
'bank reconciliation runs, and file imports (SIE, bank statements).',
},
{
file: 'employees.md',