Thank you for your work on this project! I am setting up the MCP locally for reporting, and found a cache synchronization edge case that can cause older transaction history — including later edits to older transactions — to be silently missed.
The issue appears to be that _delta_sync sends last_knowledge_of_server when fetching transactions, but does not send since_date. since_date is instead applied later as a client-side filter in get_transactions.
Older edits can be missed permanently
The most concerning case is an edit to a transaction outside the API's default transaction window.
I tested this by editing an older transaction and then requesting the transaction delta using last_knowledge_of_server without since_date.
The API returned zero transaction entities, but the response still contained an advanced server_knowledge value.
Because the cache persists that new knowledge value, the changed transaction is no longer returned by subsequent delta requests. From the cache's perspective it is up to date, even though it never received the edit.
I reproduced this both when making the change and when reverting it.
This means an older transaction can be changed in YNAB and the local cache can silently remain stale, with no error or indication that anything was missed.
Initial history can also be incomplete
The same behavior affects the initial transaction history stored in the cache.
Without an explicit since_date, the API returns only its default transaction window. On a budget with several years of history, I found that the large majority of transactions were absent from the initial cached result.
This also makes the existing since_date argument to list_transactions potentially misleading: asking for transactions from an earlier date filters the rows that are already in the cache, but cannot recover history that was never fetched.
The result can therefore be a successful-looking but incomplete response.
Expected behavior
The transaction cache should be able to:
- bootstrap the complete history requested for a plan;
- observe changes to transactions anywhere within that history on subsequent delta syncs; and
- avoid advancing its local knowledge past changes that it did not actually receive.
I've been working on this locally and have a tested branch that sends the appropriate transaction history boundary during synchronization and handles existing caches that may already be truncated.
I haven't opened that as a PR yet because the migration strategy involves a few implementation choices that seem worth discussing before proposing them as the upstream design. I'm happy to open the branch or describe the approach if that would be helpful.
Thank you for your work on this project! I am setting up the MCP locally for reporting, and found a cache synchronization edge case that can cause older transaction history — including later edits to older transactions — to be silently missed.
The issue appears to be that
_delta_syncsendslast_knowledge_of_serverwhen fetching transactions, but does not sendsince_date.since_dateis instead applied later as a client-side filter inget_transactions.Older edits can be missed permanently
The most concerning case is an edit to a transaction outside the API's default transaction window.
I tested this by editing an older transaction and then requesting the transaction delta using
last_knowledge_of_serverwithoutsince_date.The API returned zero transaction entities, but the response still contained an advanced
server_knowledgevalue.Because the cache persists that new knowledge value, the changed transaction is no longer returned by subsequent delta requests. From the cache's perspective it is up to date, even though it never received the edit.
I reproduced this both when making the change and when reverting it.
This means an older transaction can be changed in YNAB and the local cache can silently remain stale, with no error or indication that anything was missed.
Initial history can also be incomplete
The same behavior affects the initial transaction history stored in the cache.
Without an explicit
since_date, the API returns only its default transaction window. On a budget with several years of history, I found that the large majority of transactions were absent from the initial cached result.This also makes the existing
since_dateargument tolist_transactionspotentially misleading: asking for transactions from an earlier date filters the rows that are already in the cache, but cannot recover history that was never fetched.The result can therefore be a successful-looking but incomplete response.
Expected behavior
The transaction cache should be able to:
I've been working on this locally and have a tested branch that sends the appropriate transaction history boundary during synchronization and handles existing caches that may already be truncated.
I haven't opened that as a PR yet because the migration strategy involves a few implementation choices that seem worth discussing before proposing them as the upstream design. I'm happy to open the branch or describe the approach if that would be helpful.