This repository contains an agent skill for retrieving a user's financial ground-truth data from copilot.money.
The skill is designed to help an agent:
- understand what kinds of financial data Copilot exposes
- choose the right GraphQL operation for that data
- fetch the data with the local authenticated runner
It is not meant to teach financial analysis, planning, or advice. The intended workflow is:
- use this skill to gather facts from Copilot
- hand those facts to another skill, or the base agent, for interpretation
Paths below are relative to the skill root (aka {baseDir}):
SKILL.md: the main skill instructions for agentsscripts/copilot-gql.mjs: local runner for captured GraphQL operationsreferences/runtime/copilot-api: operation catalog, GraphQL documents, example requests, and use-case recipesreferences/capture: lower-level capture artifacts used to expand the known API surface
To use this project, you will need COPILOT_API_KEY and COPILOT_REFRESH_TOKEN from an authenticated Copilot web session. You can obtain both with Chrome DevTools.
- Open Copilot in Chrome and log in.
- Open DevTools.
- Go to
Application->IndexedDB->firebaseLocalStorageDb->firebaseLocalStorage. - Open the row with key like
firebase:authUser:<apiKey>:[DEFAULT]. - Copy
stsTokenManager.refreshToken.
- In that same IndexedDB row, inspect the key:
firebase:authUser:<apiKey>:[DEFAULT] - The middle segment is the Firebase API key, usually starting with
AIza....
You can also get COPILOT_API_KEY from DevTools Network by finding a request to either:
https://identitytoolkit.googleapis.com/...?...key=...https://securetoken.googleapis.com/v1/token?key=...
Then copy the key query parameter.
COPILOT_API_KEYusually starts withAIza...COPILOT_REFRESH_TOKENis a long opaque string, often starting withAMf-...
Treat both values as secrets.
- retrieving balances and account histories
- retrieving holdings, movers, cost basis, and allocation data
- retrieving categorized transactions and recurring-payment data
- finding the right account, institution, category, recurring, or security identifiers needed for later queries
- giving investment advice
- performing retirement modeling
- deciding how to interpret the data once retrieved
- Start with the user's finance question.
- Translate it into the facts you need from Copilot.
- Use the skill to discover the right operations and required IDs.
- Fetch the data.
- Pass the retrieved facts into a separate analysis step if needed.
scripts/copilot-gql.mjs hydrates transaction responses with local cache data from cache/accounts.json, cache/categories.json, cache/category-tree.json, and cache/recurrings.json.
Hydrated run and raw commands automatically refresh missing or stale cache files. Cache files are considered stale after seven days. Refresh runs in parallel with the requested GraphQL query, then hydration waits for the refreshed cache when available.
Useful commands and flags:
node scripts/copilot-gql.mjs refresh-cache
node scripts/copilot-gql.mjs run TransactionsFeed --refresh-cache
node scripts/copilot-gql.mjs run TransactionsFeed --no-refresh
node scripts/copilot-gql.mjs run TransactionsFeed --no-hydrateIf automatic refresh fails, the runner warns and continues with existing cache when possible. If no usable cache exists, it prints the unhydrated GraphQL response instead of failing the query.
For transaction filter.dates, prefer YYYY-MM-DD strings:
node scripts/copilot-gql.mjs run TransactionsFeed --vars-json '{"filter":{"dates":[{"start":"2026-02-01","end":"2026-02-28"}]}}'The runner converts those date-only strings to UTC-midnight Unix seconds before calling Copilot. Copilot treats the start and end bounds as inclusive date labels, so passing the same date for both fields returns all transactions for that date.
- Copilot should be treated as the user's financial data hub, similar to Mint-style aggregation.
- Some workflows are partial because the captured API surface is incomplete.
- If a needed data path is missing, the skill should say so plainly rather than guessing.