Every SAP API call is a round-trip to a production system. Every round-trip is a load on the tenant, a token refresh, and a line in someone's rate-limit budget. When an agent wants to search master data, it should not hammer OData. It should query a local mirror.
The problem
An agent that needs to look up a business partner, a GL account, or a supplier has two bad options: call the live API every time (slow, rate-limited, load on prod), or keep a copy in memory (lost on restart, no search). Neither scales.
The design
sapctl mirrors fetched OData rows into a local SQLite database with FTS5 full-text search. The mirror tracks a watermark per entity, so incremental sync pulls only what changed since the last cursor.
sapctl s4 odata get --cred sandbox --service API_BUSINESS_PARTNER \
--entity A_BusinessPartner --mirror
sapctl mirror search --query "acme" --entity A_BusinessPartner
sapctl mirror stats
Extract once, consume downstream. Agents read from the mirror; the live API is only touched on sync.
Why FTS5
SQLite's FTS5 gives us full-text search with zero extra infrastructure. No Elasticsearch cluster, no vector database to operate. For the 95% of SAP lookups that are keyword searches, FTS5 is fast, local, and free.
Why this matters for agents
An agent that reads from a local mirror is faster, cheaper, and kinder to the production tenant. It also stays on-policy: the mirror is populated by sapctl's constrained, audited calls, not by an agent's ad-hoc queries.
What this buys you
Extract once, consume downstream. A local SQLite mirror is the difference between an agent that respects the production system and one that hammers it.