Copilot Money MCP
MCP-сервер Copilot Money
Запрашивайте и управляйте своими личными финансами с помощью ИИ, используя локальные данные Copilot Money
Отказ от ответственности
Это независимый проект, созданный сообществом, который никоим образом не связан с Copilot Money или ее материнской компанией, не поддерживается и не одобрен ими. Этот инструмент был создан независимым разработчиком для обеспечения возможности ИИ-запросов к локально кэшированным данным. «Copilot Money» является торговой маркой соответствующего владельца.
Related MCP server: LunchMoney MCP Server
Обзор
Сервер MCP, который предоставляет ИИ-ассистентам доступ к вашим данным о личных финансах в Copilot Money. Он считывает данные из локально кэшированной базы данных Firestore (LevelDB + Protocol Buffers) на вашем Mac. Чтение происходит на 100% локально, без сетевых запросов.
17 инструментов чтения для анализа расходов, инвестиций, бюджетов, целей и многого другого — запрашивайте транзакции, счета, активы, остатки, категории, регулярные платежи, бюджеты, цели и эффективность инвестиций.
Приоритет конфиденциальности
Мы никогда не собираем, не храним и не передаем ваши данные на какой-либо сервер, управляемый этим проектом — у нас их просто нет. Подробности см. в нашей Политике конфиденциальности.
Никакой аналитики, телеметрии или отслеживания любого рода
Чтение полностью локальное — ноль сетевых запросов
Открытый исходный код — проверьте код самостоятельно
[!IMPORTANT] Важное примечание об ИИ-провайдерах. Хотя сам этот сервер работает локально и никогда не отправляет ваши данные на серверы, управляемые этим проектом, ИИ-ассистент, к которому вы его подключаете (Claude, ChatGPT, Gemini и т. д.), увидит ваши данные Copilot Money в процессе ответов на ваши вопросы. Это означает, что ваши финансовые данные будут переданы и обработаны провайдером выбранной вами модели — Anthropic, OpenAI, Google или другой третьей стороной — в соответствии с политикой конфиденциальности и условиями хранения данных этого провайдера.
Используя этот MCP-сервер с облачной ИИ-моделью, вы осознанно делитесь своими финансовыми данными с этим ИИ-провайдером. Используйте этот инструмент только в том случае, если вас устраивает такой компромисс. Если нет, рассмотрите возможность ожидания официальной интеграции Copilot Money или использования полностью локальной модели.
Быстрый старт
Предварительные требования
Node.js 18+ (поставляется в комплекте с Claude Desktop)
Copilot Money (версия из macOS App Store)
Claude Desktop, Cursor или любой другой MCP-совместимый клиент
Установка через Claude Desktop
Загрузите последний пакет
.mcpbиз раздела ReleasesДважды щелкните файл
.mcpbдля установки в Claude DesktopПерезапустите Claude Desktop
Начните задавать вопросы о своих финансах!
Установка через npm
npm install -g copilot-money-mcpЗатем добавьте в конфигурацию Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"copilot-money": {
"command": "copilot-money-mcp"
}
}
}Установка для Cursor
Установите пакет глобально:
npm install -g copilot-money-mcpОткройте настройки Cursor (
Cmd + ,) > Features > MCP ServersДобавьте конфигурацию сервера:
{
"mcpServers": {
"copilot-money": {
"command": "copilot-money-mcp"
}
}
}Что вы можете делать
Анализ расходов
«Сколько я потратил на рестораны в прошлом месяце?»
«Покажи мне все мои покупки на Amazon за последние 30 дней»
«Какие 5 категорий расходов у меня самые крупные в этом году?»
Использует get_transactions, get_categories с диапазонами дат, текстовым поиском и фильтрами категорий.
Обзор счетов
«Каков мой чистый капитал по всем счетам?»
«Покажи мне остаток на моем расчетном счете за последние 6 месяцев, помесячно»
«Какие банковские подключения требуют внимания?»
Использует get_accounts, get_balance_history, get_connection_status.
Инвестиционный портфель
«Какие у меня текущие активы и общая доходность?»
«Покажи мне историю цен AAPL за последний год»
«Какова моя доходность с учетом времени (TWR) за этот квартал?»
Использует get_holdings, get_investment_prices, get_securities, get_investment_performance, get_twr_returns.
Бюджеты и цели
«Укладываюсь ли я в свои бюджеты в этом месяце?»
«Как продвигается накопление моего резервного фонда?»
«Покажи мне историю моих целей за последние 6 месяцев»
Использует get_budgets, get_goals, get_goal_history.
Подписки и регулярные платежи
«За какие подписки я плачу?»
«Сколько я трачу на регулярные платежи в месяц?»
Использует get_recurring_transactions.
Доступные инструменты
Инструменты чтения (17)
Инструмент | Описание |
| Запрос транзакций с фильтрами — диапазон дат, категория, продавец, сумма, счет, местоположение, текстовый поиск и специальные типы (иностранные, возвраты, дубликаты, соответствующие HSA). |
| Список всех счетов с остатками, фильтрация по типу (расчетный, сберегательный, кредитный, инвестиционный). Включает расчет чистого капитала. |
| Список категорий с количеством транзакций и общими суммами расходов. Поддерживает списочный, древовидный и поисковый виды. |
| Идентификация подписок и регулярных платежей с частотой, стоимостью и следующей ожидаемой датой. |
| Получение бюджетов со сравнением расходов и лимитов. |
| Получение финансовых целей с целевыми суммами, прогрессом и ежемесячными взносами. |
| Ежемесячные снимки прогресса по целям с ежедневными данными и записями о взносах. |
| Ежедневные снимки остатков на счетах с течением времени. Поддерживает ежедневную, еженедельную или ежемесячную детализацию. |
| Текущие инвестиционные активы с тикером, количеством, ценой, базой затрат и общей доходностью. |
| Исторические данные о ценах (ежедневные + высокочастотные) для акций, ETF, взаимных фондов и криптовалют. |
| История дробления акций с коэффициентами, датами и множителями. |
| Данные об эффективности инвестиций по ценным бумагам. |
| Ежемесячные данные о доходности с учетом времени (TWR) для инвестиционных активов. |
| Основные данные о ценных бумагах — тикер, название, тип, цена и идентификаторы (ISIN/CUSIP). |
| Состояние банковской синхронизации для подключенных учреждений, включая временные метки последней синхронизации и ошибки. |
| Метаданные локального кэша — диапазон дат, количество транзакций, возраст кэша. |
| Перезагрузка данных с диска. Кэш автоматически обновляется каждые 5 минут. |
Конфигурация
TTL кэша
Сервер кэширует данные в памяти на 5 минут. Настраивается через переменную окружения:
# Set cache TTL to 10 minutes
COPILOT_CACHE_TTL_MINUTES=10 copilot-money-mcp
# Disable caching (always reload from disk)
COPILOT_CACHE_TTL_MINUTES=0 copilot-money-mcpВы также можете обновить данные вручную с помощью инструмента refresh_database.
Тайм-аут декодирования
Для больших баз данных (500 МБ+) увеличьте тайм-аут декодирования (по умолчанию: 90 секунд):
# Via environment variable
DECODE_TIMEOUT_MS=600000 copilot-money-mcp
# Via CLI flag
copilot-money-mcp --timeout 600000Для баз данных объемом более 1 ГБ также увеличьте объем памяти Node.js:
{
"mcpServers": {
"copilot-money": {
"command": "node",
"args": [
"--max-old-space-size=4096",
"/path/to/copilot-money-mcp/dist/cli.js",
"--timeout", "600000"
]
}
}
}Поддерживаемые периоды дат
Параметр period поддерживает следующие сокращения:
this_month last_month last_7_days last_30_days last_90_days ytd this_year last_year
Известные ограничения
Зависимость от локального кэша
Этот сервер считывает данные из локального кэша Firestore приложения Copilot Money, а не из облака. Автономное хранилище Firestore кэширует каждый документ, который когда-либо загружало приложение, поэтому локальная база данных обычно содержит все транзакции, счета, бюджеты, цели и другие данные, которые вы просматривали в приложении. Размер кэша Firestore по умолчанию составляет 100 МБ (этого достаточно для десятков тысяч транзакций), а старые документы удаляются через сборщик мусора LRU только в случае превышения этого лимита.
Чтобы максимизировать объем кэшированных данных: Откройте приложение Copilot Money и просмотрите свои данные (историю транзакций, счета, бюджеты), чтобы убедиться, что они были загружены и кэшированы локально.
Устранение неполадок
База данных не найдена
Если вы видите сообщение «Database not available»:
Убедитесь, что Copilot Money установлена и данные синхронизированы
Проверьте расположение базы данных:
~/Library/Containers/com.copilot.production/Data/Library/Application Support/firestore/__FIRAPP_DEFAULT/copilot-production-22904/mainУбедитесь, что файлы
.ldbсуществуют в каталогеУкажите путь вручную:
copilot-money-mcp --db-path /path/to/database
Тайм-аут рабочего процесса декодирования
Если вы видите сообщение «Decode worker timed out»:
Увеличьте тайм-аут:
copilot-money-mcp --timeout 300000(5 минут)Для баз данных объемом 1 ГБ+ также увеличьте память Node.js:
node --max-old-space-size=4096 dist/cli.js --timeout 300000
Транзакции не найдены
Откройте приложение Copilot Money и дождитесь синхронизации
Структура базы данных могла измениться — откройте issue
Участие в разработке
См. CONTRIBUTING.md для настройки среды разработки, архитектуры и информации о том, как добавлять новые инструменты.
Лицензия
Лицензия MIT — подробности см. в файле LICENSE.
Благодарности
Available Tools
14 toolsget_accountsARead-only
Get all accounts with balances, plus summary fields: total_balance (net worth = assets minus liabilities), total_assets, and total_liabilities. Optionally filter by account type (checking, savings, credit, investment). Checks both account_type and subtype fields for better filtering (e.g., finds checking accounts even when account_type is 'depository'). By default, hidden accounts are excluded. name is your Copilot nickname when set, else the provider label — it is user-editable, so key on account_id, never on name. Default rows are terse: account_id, name, account_type, subtype, current_balance, institution_name, iso_currency_code, item_id, plus user_hidden / user_deleted when set (the flags include_hidden controls). That drops the other ~35 document fields. PARTIAL list of what goes, not exhaustive: the embedded holdings array (get_holdings covers it), institution logo images plus their logo_content_type (base64-encoded, several KB each — this PAIR is where the removed include_logos flag went, and the flag gated both, so request them together), mask (the last-4 digits humans identify an account by), available_balance, limit, institution_id, creation_timestamp (when the account was created in Copilot, YYYY-MM-DD — written only on newer rows, so absent means unknown, not old), the denormalized official_name / original_* name dupes, and user_id. Any document field is requestable by name: fields: ["default", "mask", "available_balance"], or "all" / "*" for full rows. include_logos was removed in v3.0.0 — passing it now raises an error naming this migration.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Return only these fields per account row (e.g. ["account_id", "name", "current_balance"] for get_accounts, or ["id", "name", "balance"] for get_accounts_live — field names differ between the two modes). "default" expands to a terse baseline covering identity, name, type, balance, institution, and item — see each tool's own description for its exact field list and what "default" excludes. "all" or "*" returns the full row. Unknown names are omitted and reported via _field_warning. | |
| account_type | No | Filter by account type (checking, savings, credit, loan, investment, depository). Note: summary totals (total_assets, total_liabilities, total_balance) reflect only the filtered subset. | |
| include_hidden | No | Include hidden accounts (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering safety, the description adds substantial behavioral context: default rows omit roughly 35 fields, hidden accounts are excluded unless include_hidden is set, name is user-editable and must not be used as a key, and include_logos was removed in v3.0.0 and now raises an error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose, filtering behavior, and default projection are front-loaded, and most detail is relevant. The long parenthetical inventory of excluded fields is informative but dense, making the description longer than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description specifies the default return fields, the summary fields, the kinds of fields omitted by default, and how to request any document field by name. Combined with readOnlyHint and full schema coverage, this is enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description meaningfully expands parameter semantics. It explains how fields supports 'default', 'all', '*', and explicit names; how account_type filtering checks both account_type and subtype; and how include_hidden controls the user_hidden/user_deleted flags.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get all accounts with balances, plus summary fields.' It also clarifies scope and identity versus siblings by noting that embedded holdings are covered by get_holdings and by explaining the default field projection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: optional filtering by account type, hidden accounts excluded by default, and fields projection via 'default', 'all', or explicit names. It also routes the agent away for holdings data by naming get_holdings, though it does not systematically compare against all relevant siblings such as get_balance_history.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balance_historyARead-only
Get daily balance snapshots for accounts over time. Each entry returns current_balance, available_balance, limit, account_id, and account_name. The response also includes an accounts array listing the distinct account IDs in the paginated page. Requires a granularity parameter (daily, weekly, monthly) to control response size. Weekly and monthly modes downsample by keeping the last data point per period. Filter by account_id and date range.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default: 100, max: 10000) | |
| offset | No | Number of results to skip for pagination (default: 0) | |
| end_date | No | End date (YYYY-MM-DD) | |
| account_id | No | Filter by account ID | |
| start_date | No | Start date (YYYY-MM-DD) | |
| granularity | Yes | Required. Controls response density: daily (every day), weekly (one per week), or monthly (one per month). Use weekly or monthly for longer time ranges. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is already covered by annotations, so the description is free to add real value: it discloses downsampling behavior (keeping the last data point per period) and that the accounts array reflects the paginated page. These are non-obvious behavioral traits beyond the annotations, though pagination/limit interaction and freshness are not spelled out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then return shape, then the granularity/downsampling caveat. Every sentence carries information; only the restatement of the required granularity slightly overlaps with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the returned fields (current_balance, available_balance, limit, account_id, account_name) and the accounts array. It covers the key non-obvious behavior (downsampling), leaving only secondary details like cache vs live data and error/empty behavior unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining the semantic effect of granularity (downsampling via last data point per period) beyond the enum values, and noting account_id/date-range filtering. This adds meaning the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get daily balance snapshots for accounts over time,' which distinguishes it from siblings like get_transactions, get_goal_history, and get_investment_prices that return different resource types. It doesn't name siblings explicitly, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives useful intra-tool guidance ('use weekly or monthly for longer time ranges'), but offers no explicit when-to-use-this-vs-alternatives guidance relative to the many sibling read tools, nor any prerequisites/exclusions. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_budgetsARead-only
Get budgets from Copilot's native budget tracking. Returns the current-month effective budget per category plus the full amounts map of per-month overrides for history lookups. For parent categories, the returned amount is the resolved total (children + rollovers) that Copilot displays in the Budgets view. Totals use the current-month effective amount.
| Name | Required | Description | Default |
|---|---|---|---|
| active_only | No | Only return active budgets (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true. The description adds value by detailing that budgets are from native tracking, returns effective budget per category and amounts map, and explains resolved totals for parent categories. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the main action, and every sentence adds necessary information. No redundancy or wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but the description compensates by explaining return values (effective budget, amounts map, resolved totals). It provides sufficient context for a simple read operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of the single parameter (active_only) with a clear description. The tool description adds no additional meaning to the parameter beyond what the schema provides, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves budgets from Copilot's native budget tracking, specifies the return content (current-month effective budget per category plus full amounts map), and explains behavior for parent categories. It distinguishes itself from sibling tools by focusing on budgets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for budget retrieval but does not explicitly state when to use this tool versus alternatives like get_transactions or get_categories. No exclusions or when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cache_infoARead-only
Get information about the local data cache, including the date range of cached transactions and total count. Useful for understanding data availability before running historical queries. This tool reads from a local cache that may not contain your complete transaction history. Also reports decode_health: per-collection counts of documents dropped on schema validation failure (a "degraded" status means some cached documents are missing from results).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond readOnlyHint=true by disclosing that the tool reads a local cache that may not contain complete transaction history, and by defining what a "degraded" decode_health status means (documents dropped on schema validation). A useful caveat about the remediation path (refresh_database) is missing, but the data-quality semantics are well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with what the tool returns before the usage hint and the caveats. The parenthetical explaining decode_health is dense but earns its place by preventing misinterpretation of returned fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the return-value burden, and it names the key fields (date range, count, per-collection decode_health) along with their interpretation. The only meaningful omission is guidance on what to do when the cache is incomplete or degraded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is nothing for the description to compensate for and it makes no claims about inputs that could mislead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reports cache metadata (date range of cached transactions, total count) plus decode_health counters. This is clearly distinguishable from sibling data-fetching tools like get_transactions because it describes availability metadata rather than transaction records, though it never explicitly names those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Useful for understanding data availability before running historical queries" gives a concrete when-to-use trigger. It stops short of explicit alternatives or exclusions — notably it never points to refresh_database when the cache is found to be stale or incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_categoriesARead-only
Unified category retrieval tool. Supports multiple views: list (default) - user categories with transaction counts/amounts for a time period; tree - user categories as hierarchical tree; search - search user categories by keyword. Use parent_id to get subcategories. For list view, use period (e.g., "this_month") or start_date/end_date to filter by date. Includes all categories, even those with $0 spent (matching UI behavior).
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | View mode: list (categories with spend totals), tree (parent/child hierarchy), search (find by keyword) | |
| query | No | Search query (required for 'search' view) | |
| period | No | Time period for list view (e.g., 'this_month', 'last_month', 'last_30_days', 'this_year'). Takes precedence over start_date/end_date if provided. | |
| end_date | No | End date for list view (YYYY-MM-DD format) | |
| parent_id | No | Get subcategories of this parent category ID | |
| start_date | No | Start date for list view (YYYY-MM-DD format) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint: true. The description adds that the tool includes categories with $0 spent, matching UI behavior, and explains the behavior of different views. This goes beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly concise given the complexity of three views and multiple parameters. It is front-loaded with the main purpose. Minor redundancy could be trimmed, but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all major aspects: views, filtering, parent_id, date options, and the inclusion of zero-spend categories. Despite no output schema, the description is sufficient for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all parameters with descriptions (100% coverage). The description adds extra meaning by explaining that categories with $0 spent are included, and that period takes precedence over dates, which is not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Unified category retrieval tool' and explains three distinct views (list, tree, search) with specific use cases. It distinguishes itself from sibling tools like get_accounts and get_transactions by focusing on category data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use each view (e.g., list for spend totals, tree for hierarchy, search for keyword) and how to filter by date or parent_id. However, it does not explicitly state when not to use this tool or mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_connection_statusARead-only
Get connection status for all linked financial institutions. Shows per-institution sync health including last successful update timestamps for transactions and investments, login requirements, and error states. Use this to check when accounts were last synced or to identify connections needing attention. Also reports decode_health: per-collection counts of cached documents dropped on schema validation failure (a "degraded" status means some documents are missing from results). Also reports scheduled_smoke: the last scheduled API-drift check with timestamp, or null if the weekly job is not installed. Only "fail" means the API drifted; "auth-missing" and "incomplete" mean drift is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering safety, the description adds substantial behavioral detail: per-institution sync health, timestamps, login requirements, error states, decode_health semantics, scheduled_smoke behavior, and the meaning of fail vs auth-missing/incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose and then adds return-value semantics, which are important because there is no output schema. It is dense but every sentence contributes; it could be slightly more structured, but it is not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, no output schema, and only a readOnly annotation, the description carries the return-value burden well. It explains the main status payload and the auxiliary decode_health and scheduled_smoke fields, including status interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there are no parameter semantics to explain. Baseline for a no-parameter tool is 4, and the description correctly does not invent parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: get connection status for linked financial institutions. It then scopes the response to sync health, login requirements, error states, decode_health, and scheduled_smoke, making the tool clearly distinct from the data-retrieval siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this to check when accounts were last synced or to identify connections needing attention. That gives clear positive usage context, but it does not name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_goal_historyARead-only
Get monthly progress snapshots for financial goals. Returns current_amount, target_amount, daily data points, and contribution records per month. Filter by goal_id or month range (YYYY-MM). Cache-only: no live-mode (--live-reads) counterpart exists because Copilot's GraphQL endpoint does not expose goal data, so this tool always returns cached LevelDB data regardless of the --live-reads flag.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default: 100, max: 10000) | |
| offset | No | Number of results to skip for pagination (default: 0) | |
| goal_id | No | Filter by goal ID | |
| end_month | No | End month (YYYY-MM) | |
| start_month | No | Start month (YYYY-MM) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral context beyond the readOnlyHint annotation, explaining that the tool is always cached, ignores the --live-reads flag, and why (backend limitation). This helps the agent understand the tool's data freshness and constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each serving a purpose: purpose, return fields, and cache behavior. It is front-loaded with the core function, then details, then important behavioral note. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 optional parameters and no output schema, the description covers purpose, return fields, filtering, and cache behavior. It does not explain pagination parameters (limit/offset) but those are standard and described in the schema. Overall, it provides enough context for the agent to select and use the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the description doesn't need to repeat parameter details. However, it adds value by clarifying that the tool returns 'daily data points' and 'contribution records per month,' which are not in the schema. This enriches the agent's understanding of the output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves monthly progress snapshots for financial goals, listing specific return fields (current_amount, target_amount, daily data points, contribution records). It distinguishes from siblings like get_goals or get_balance_history by focusing on monthly history snapshots.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states this tool is cache-only and always returns cached data, with no live-mode counterpart. It explains the reason (GraphQL endpoint does not expose goal data), guiding the agent on when to use this tool versus others. It could be improved by explicitly stating when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_goalsARead-only
Get financial goals from Copilot's native goal tracking. Retrieves user-defined savings goals, debt payoff targets, and investment goals. Returns goal details including target amounts, monthly contributions, status (active/paused), start dates, and tracking configuration. Calculates total target amount across all goals. Cache-only: no live-mode (--live-reads) counterpart exists because Copilot's GraphQL endpoint does not expose goal data, so this tool always returns cached LevelDB data regardless of the --live-reads flag.
| Name | Required | Description | Default |
|---|---|---|---|
| active_only | No | Only return active goals (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses beyond readOnlyHint: always returns cached LevelDB data regardless of --live-reads flag, alerting the agent to staleness. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences efficiently convey purpose and key constraint. Could be slightly more structured with bullet points, but no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given simple read-only tool with one parameter and no output schema, description covers all essential aspects: goals covered, fields returned, cache limitation, and no live mode.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 1 parameter with full description. Description adds no new info beyond schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves financial goals from Copilot's native goal tracking, listing types (savings, debt, investment) and details returned. It distinguishes from siblings like get_accounts and get_budgets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly mentions cache-only nature and lack of live-mode counterpart, indicating when to use. No explicit alternatives among siblings, but context implies this is the only goal tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_holdingsARead-only
Get current investment holdings with position-level detail. Returns ticker, name, quantity, current price, equity value, average cost, and total return per holding. Joins data from account holdings, securities, and optionally historical snapshots. Filter by account or ticker symbol. Note: cost_basis may be unavailable for cash-equivalent positions. Positions on hidden and merged accounts are EXCLUDED by default, matching get_accounts — pass include_hidden: true for them. Do NOT sum holdings as portfolio value: unvested stock-plan shares are reported as holdings, so the sum can far exceed the investment balance; with --live-reads use get_investment_balance_live for the total.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default: 100, max: 10000) | |
| offset | No | Number of results to skip for pagination (default: 0) | |
| account_id | No | Filter by investment account ID. Returns empty for a hidden or merged account unless include_hidden is also set. | |
| ticker_symbol | No | Filter by ticker symbol, case-insensitive (e.g., "AAPL", "SCHX"). The cash sleeve is CUR:USD here and USD in live mode; either spelling matches it in both modes (CUR:USD matches only cash; a bare USD also matches a security tickered USD). | |
| include_hidden | No | Include positions on hidden and merged accounts (default: false). Same flag, same default as get_accounts — leave it off and the two tools agree on which accounts exist. | |
| include_history | No | Include monthly price/quantity snapshots per holding (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds meaningful behavioral context beyond that: hidden/merged accounts are excluded by default, cost_basis may be unavailable for cash-equivalents, and unvested stock-plan shares inflate the sum. Minor gap on pagination behavior, but the safety and edge-case profile is well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose and return fields, then adds scoping and caveats in order of importance. Every sentence carries a distinct fact (return fields, join sources, filtering, hidden-account behavior, summation warning). Slightly dense but no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description enumerates the returned fields so an agent knows the shape. Combined with the behavioral caveats and filtering guidance, the definition is complete enough to call correctly, with only pagination left to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters thoroughly. The description restates filtering by account/ticker and the include_hidden alignment with get_accounts, adding only marginal value beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (current investment holdings) at position-level detail, then enumerates the return fields (ticker, quantity, price, equity value, cost, return). This distinguishes it cleanly from siblings like get_transactions, get_investment_prices, and get_investment_splits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when filtering applies (account/ticker), explains the include_hidden default matches get_accounts so the two agree, and gives a clear when-not-to-use with an alternative: 'Do NOT sum holdings... use get_investment_balance_live for the total.' This is exactly the routing guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_investment_pricesARead-only
Get investment price history for portfolio tracking. Returns one row per (security, period) for stocks, ETFs, mutual funds, and crypto. Filter by ticker symbol, date range, or price type (daily/hf). By default each row is TERSE: the security, the period, and its latest price (latest_price / latest_at) — enough to answer "what is this worth". The full price series (prices, an epoch-millis map) is most of a full row and roughly quadruples response size, so it is omitted unless requested via fields; ask for it only when you need the time series itself, not a current value.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default: 100, max: 10000) | |
| fields | No | Return only these fields per row. Default when omitted: a terse row (security_id, ticker_symbol, price_type, date/month, latest_price, latest_at). The full intraday/daily series lives in `prices`, which is EXCLUDED by default because it is most of a row and multiplies response size several-fold — request it explicitly with fields: ["default", "prices"], or use "all" / "*" for full rows. Unknown names are omitted and reported via _field_warning. | |
| offset | No | Number of results to skip for pagination (default: 0) | |
| end_date | No | End date (YYYY-MM-DD) | |
| price_type | No | Filter by price type: daily (monthly aggregates) or hf (high-frequency intraday) | |
| start_date | No | Start date (YYYY-MM-DD) | |
| ticker_symbol | No | Filter by ticker symbol (e.g., "AAPL", "BTC-USD", "VTSAX") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint; the description goes well beyond that by disclosing default projection (terse rows), the specific fields returned, and that `prices` 'roughly quadruples response size' and is excluded unless requested. That is exactly the cost/behavior signal an agent needs before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and row shape, then the default-terse behavior, then the opt-in cost. Five sentences all carry information, though the `prices`/response-size point is restated in both the description and the schema, slightly inflating it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates fully: it describes the returned row shape, the default field set, the `latest_price`/`latest_at` semantics, and the shape of `prices` (epoch-millis map). An agent can invoke and interpret this tool from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description still adds value by explaining the why behind `fields` (full series omitted by default, how to opt in) and by framing ticker/date/price_type as filters. Some of this duplicates the schema's own `fields` text, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get investment price history') plus the row granularity ('one row per (security, period)') and the covered asset classes. An agent knows exactly what dataset comes back and can tell it apart from holdings/splits tools without reading the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-request guidance for the expensive `prices` field: 'ask for it only when you need the time series itself, not a current value.' It does not name sibling alternatives (e.g. get_holdings for current positions), so routing between tools is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_investment_splitsARead-only
Get stock split events from the local Firestore cache. Returns one row per (security, effective_date) with the adjustment multiplier (e.g. 0.1 for a 10-for-1 split — multiply pre-split prices/quantities by this value to convert to the post-split equivalent). Joined with the securities collection so each row includes ticker and name. IMPORTANT: prices returned by get_investment_prices and get_investment_prices_live are ALREADY split-adjusted by Copilot. Use this tool only when you need the split events themselves (e.g., for narrative or historical-analysis purposes) — you do NOT need to apply these multipliers to the prices yourself. Securities that have never split are not included in the output. Coverage is limited to securities Copilot currently syncs in your local cache (typically currently-held or recently-held).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of rows. Default 100, max 10000. | |
| offset | No | Pagination offset, default 0. | |
| end_date | No | Optional. Inclusive upper bound on effective_date (YYYY-MM-DD). | |
| start_date | No | Optional. Inclusive lower bound on effective_date (YYYY-MM-DD). | |
| ticker_symbol | No | Optional. Case-insensitive ticker filter (e.g. "NVDA"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds details about output structure (one row per security/date), the meaning of the multiplier, the join with securities, and cache coverage. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and details, then usage guidance. It is somewhat lengthy but all sentences add value. Could be slightly more concise, but structure is logical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully explains the output structure, including the multiplier meaning and joined fields. All 5 parameters are well-documented. The tool's behavior is completely described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with good descriptions, but the description adds extra context (e.g., case-insensitive ticker, inclusive date bounds, effective_date field name). This enhances clarity beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves stock split events from the local Firestore cache, specifying verb 'get', resource 'stock split events', and scope. It distinguishes from siblings like get_investment_prices by noting that those return already-adjusted prices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use this tool ('when you need the split events themselves') and when not to ('you do NOT need to apply these multipliers to the prices yourself'). Also mentions coverage limitations, guiding the agent appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recurring_transactionsARead-only
Identify recurring/subscription charges. Combines two data sources: (1) Pattern analysis - finds transactions from same merchant with similar amounts, returns estimated frequency, confidence score, and next expected date. (2) Copilot's native subscription tracking - returns user-confirmed subscriptions stored in the app. Both sources are included by default for comprehensive coverage. Rows in the pattern-analysis recurring array are terse by default: merchant, normalized_merchant, occurrences, average_amount, total_amount, frequency, confidence, category_name, last_date, next_expected_date. That excludes the matched transactions array (already reachable via get_transactions) and confidence_reason (prose explaining the score) — see fields for how to get either back.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Filter by name (case-insensitive partial match). When filtering, returns detailed view with additional fields like min_amount, max_amount, match_string, account info, and transaction history. | |
| fields | No | Return only these fields per detected recurring merchant. Default when omitted omits two expensive fields: `transactions` (the matched date/amount pairs, ~29% of a row) and `confidence_reason` (prose explaining the confidence score, ~15%). `confidence` itself is always in the default. Request the rest with fields: ["default", "transactions", "confidence_reason"], or "all" / "*" for full rows. Unknown names are omitted and reported via _field_warning. | |
| period | No | Period to analyze (default: last_90_days). Options: this_month, last_month, last_7_days, last_30_days, last_90_days, ytd, this_year, last_year | |
| end_date | No | End date (YYYY-MM-DD) | |
| start_date | No | Start date (YYYY-MM-DD) | |
| recurring_id | No | Filter by exact recurring ID. When filtering, returns detailed view with additional fields like min_amount, max_amount, match_string, account info, and transaction history. | |
| min_occurrences | No | Minimum number of occurrences to qualify as recurring (default: 2) | |
| include_copilot_subscriptions | No | Include Copilot's native subscription tracking data (default: true). Returns copilot_subscriptions array with user-confirmed subscriptions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint, so the heavy lifting is on the description — and it delivers: default rows are a projection that omits two named expensive fields with rough payload shares, and it discloses the _field_warning mechanism for unknown names. It also notes that filtering by name/recurring_id switches to a 'detailed view'. Missing any guidance on result-set size or how many merchants a broad period can return, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose and the source split before the payload detail, which is the right ordering. The `fields`/default-projection exposition is somewhat redundant with the schema's own description of the same parameter, costing a few lines of duplicated content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description properly enumerates the default row fields and explains what is excluded — enough for an agent to know what it will get back. The shape of the copilot_subscriptions rows and the size of the combined payload under a broad period are left unspecified, but the core contract is covered for a 0-required-param read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter including the fields projection language and the period enum values. The description largely restates the `fields` default behavior that the schema also explains, adding emphasis rather than new meaning. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Identify recurring/subscription charges') and immediately decomposes the tool into two named data sources with distinct semantics (pattern analysis vs. user-confirmed Copilot subscriptions). It also names the sibling that already owns the matched transaction data (get_transactions), so an agent can tell it apart from the other read tools in the set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states both sources are included by default for 'comprehensive coverage' and points to get_transactions as the route for matched transaction detail, which is real routing guidance. It stops short of saying when to prefer one source over the other or when to disable include_copilot_subscriptions, so it does not reach full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transactionsARead-only
Reads from the local LevelDB cache, which may lag behind Copilot's server if the macOS app hasn't synced recently. For real-time data use --live-reads with get_transactions_live. Unified transaction retrieval tool. Supports multiple modes: (1) Filter-based: Use period, date range, category, merchant, amount filters. (2) Single lookup: Provide transaction_id to get one transaction. (3) Text search: Use query for free-text merchant search. (4) Special types: Use transaction_type for foreign, refunds, credits, duplicates, hsa_eligible, tagged. (5) Location-based: Use city or lat/lon with radius_km. (6) Tag filter: Use tag to find transactions with a specific tag. Rows are TERSE by default: transaction_id, date, amount, name, category_name, account_id, item_id, pending, excluded, internal_transfer. excluded answers "is this row excluded from spending?" — the raw per-transaction flag OR the row's category being user-excluded, the same union exclude_excluded filters on — so it is true for a row Copilot never stamped individually. It is therefore nearly always false in a default response, since exclude_excluded already removed those rows; it carries information only when you pass exclude_excluded: false. A cache row carries ~30 fields and most callers need a handful, so the rest are excluded unless asked for. PARTIAL list of what that drops, not exhaustive: Plaid metadata (plaid_category_id, plaid_category_strings, plaid_deleted), internal IDs (category_id, recurring_id, goal_id, parent_transaction_id, children_transaction_ids, user_id), enrichment and intelligence fields (normalized_merchant — still the normalized merchant name when requested — intelligence_suggested_category_ids, suggestion_ids, original_name), tag_ids, review state (user_reviewed, user_note, user_changed_type — true only when a human re-typed the row, so do not second-guess its type), location (city, region, country, lat/lon), and flags like is_amazon/from_investment. amazon is worth naming because nothing else hints it exists: on rows Copilot matched to an Amazon order it carries the receipt — {order_id, items: [{id, name, link, price, quantity}], other: {giftWrapping, rewards, savings, shipping, tax}} — so fields: ["default", "amazon"] answers "what was in this order" without an exported CSV. Ask for any of them by name with fields: ["default", "tag_ids"], or take the whole document with fields: ["all"] (or "*"). category_name is always resolved to a human-readable name. compact was removed in v3.0.0 — passing it now raises an error naming this migration.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude for proximity search (use with lon and radius_km) | |
| lon | No | Longitude for proximity search (use with lat and radius_km) | |
| tag | No | Filter by tag name (e.g. "vacation") | |
| city | No | Filter by city name (partial match) | |
| limit | No | Maximum number of results (default: 100) | |
| query | No | Free-text search in merchant/transaction names | |
| fields | No | Return only these fields per transaction. Default when omitted: a terse row (transaction_id, date, amount, name, category_name, account_id, item_id, pending, excluded, internal_transfer). Anything else is requestable by name alongside the preset: fields: ["default", "tag_ids"], or "all" / "*" for the whole row. THIS TOOL's own description names what its rows drop — the two modes drop different things, because a live row is not a cache document. The note is user_note in cache mode and user_notes live; either spelling works in either mode, and each mode returns its own. Unknown names are omitted and reported via _field_warning. | |
| offset | No | Number of results to skip for pagination (default: 0) | |
| period | No | Period shorthand: this_month, last_month, last_7_days, last_30_days, last_90_days, ytd, this_year, last_year | |
| region | No | Filter by region/city (case-insensitive substring) | |
| country | No | Filter by country code (e.g., US, CL) | |
| pending | No | Filter by pending status (true for pending only, false for settled only) | |
| category | No | Filter by category ID from get_categories (exact match, not a name). A parent category's id also returns its subcategories' rows. An id that belongs to no category and to no transaction the call looked at is an error. | |
| end_date | No | End date (YYYY-MM-DD) | |
| merchant | No | Filter by merchant name (case-insensitive substring) | |
| radius_km | No | Search radius in kilometers (default: 10) | |
| account_id | No | Filter by account ID | |
| max_amount | No | Maximum transaction amount | |
| min_amount | No | Minimum transaction amount | |
| start_date | No | Start date (YYYY-MM-DD) | |
| transaction_id | No | Get a single transaction by ID (ignores other filters, though a `category` value must still be a real id) | |
| exclude_deleted | No | Exclude deleted transactions marked by Plaid (default: true) | |
| exclude_excluded | No | Exclude user-excluded transactions (default: true) | |
| transaction_type | No | Filter by special type. Cache-only: foreign (international) and duplicates (potential duplicate transactions, paired among the rows the other filters keep; pass the matching exclude_*: false, e.g. exclude_deleted: false, to bring a hidden copy back). Same rule in cache and live mode (positive amount = money out). refunds: a negative REGULAR row in a spending category; never INCOME, a transfer or uncategorized. credits: a negative REGULAR row whose name has credit/cashback/reward/rebate/bonus and whose category is not income or transfer; may overlap refunds. hsa_eligible: a heuristic, not an eligibility ruling: a positive REGULAR row whose category name has health/medical/pharmac/dental/eye care/vision or whose name has cvs/walgreens/pharmacy/medical/dental/vision/hospital. tagged: has a tag. type_specific_data totals cover all matching rows, not just the returned page. | |
| exclude_transfers | No | Exclude transfers between accounts and credit card payments (default: true) | |
| exclude_split_parents | No | Exclude split-transaction parents (docs with children_transaction_ids). The children already carry the real categorized amounts — returning the parent would double-count the spend. Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already declare `readOnlyHint=true`, the description adds substantial behavioral context: cache lag, default terse rows, the approximately 30 dropped fields, how `excluded` behaves, the special `amazon` receipt field, and that `compact` was removed and now raises an error. These are exactly the kind of beyond-annotation details an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but the complexity and parameter count justify substantial detail. It is front-loaded with the cache-lag caveat and then organized by numbered usage modes, though some field-list prose could be trimmed without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 26-parameter read tool with no output schema, the description is complete: it covers cache behavior, alternate live tooling, supported retrieval modes, default return shape, field expansion, and a migration error for `compact`. An agent has enough information to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 26 parameters thoroughly. The description adds useful meaning beyond the schema by grouping parameters into retrieval modes, explaining the default terse field set, and clarifying the nuanced behavior of `excluded` and field selection. It is not a 5 because much of the parameter-level detail is already present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reading transactions from a local LevelDB cache. It clearly distinguishes itself from the live sibling by naming `get_transactions_live` and explains that the cache may lag. An agent can tell this is the cached retrieval tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use this tool versus the real-time alternative: use the cache read normally, but use `get_transactions_live` for real-time data. It also enumerates the supported retrieval modes, giving clear context for selecting filters, transaction_id lookup, text search, type filters, location, and tags.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refresh_databaseARead-only
Refresh the in-memory cache by reloading data from the local Copilot Money database. Use this when the user has recently synced new transactions in the Copilot Money app, or when you suspect the cached data is stale. The cache also auto-refreshes every 5 minutes. Returns the updated cache info after refresh.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it reloads from local database, returns cache info, and auto-refreshes. No contradiction with readOnlyHint=true. Adds value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no fluff, front-loaded with purpose, then usage, then additional context. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and simple operation, description is complete. Mentions return of cache info, which is sufficient though slightly vague.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters; schema coverage 100%. Baseline score 4 for zero-param tool; description adds no parameter info but none needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Refresh the in-memory cache by reloading data from the local Copilot Money database'. Verb and resource specific, distinct from sibling get_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use: after user syncs new transactions or when cache may be stale. Notes auto-refresh every 5 minutes but lacks explicit exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v3.0.0- Changed
get_accounts1 field changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Return only these fields per account row (e.g. [\"account_id\", \"name\", \"current_balance\"] for get_accounts, or [\"id\", \"name\", \"balance\"] for get_accounts_live — field names differ between the two modes). \"default\" expands to a terse baseline covering identity, name, type, balance, institution, and item — see each tool's own description for its exact field list and what \"default\" excludes. \"all\" or \"*\" returns the full row. Unknown names are omitted and reported via _field_warning.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
get_holdings3 fields changed- changed
Input schema / properties / account_id / descriptionPrevious value: -"Filter by investment account ID"New value: +"Filter by investment account ID. Returns empty for a hidden or merged account unless include_hidden is also set." - added
Input schema / properties / include_hiddenAdded value: +{ + "default": false, + "description": "Include positions on hidden and merged accounts (default: false). Same flag, same default as get_accounts — leave it off and the two tools agree on which accounts exist.", + "type": "boolean" +} - changed
Input schema / properties / ticker_symbol / descriptionPrevious value: -"Filter by ticker symbol (e.g., \"AAPL\", \"SCHX\")"New value: +"Filter by ticker symbol, case-insensitive (e.g., \"AAPL\", \"SCHX\"). The cash sleeve is CUR:USD here and USD in live mode; either spelling matches it in both modes (CUR:USD matches only cash; a bare USD also matches a security tickered USD)."
- Changed
get_investment_prices3 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"End date (YYYY-MM-DD or YYYY-MM)"New value: +"End date (YYYY-MM-DD)" - added
Input schema / properties / fieldsAdded value: +{ + "description": "Return only these fields per row. Default when omitted: a terse row (security_id, ticker_symbol, price_type, date/month, latest_price, latest_at). The full intraday/daily series lives in `prices`, which is EXCLUDED by default because it is most of a row and multiplies response size several-fold — request it explicitly with fields: [\"default\", \"prices\"], or use \"all\" / \"*\" for full rows. Unknown names are omitted and reported via _field_warning.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / start_date / descriptionPrevious value: -"Start date (YYYY-MM-DD or YYYY-MM)"New value: +"Start date (YYYY-MM-DD)"
- Changed
get_recurring_transactions1 field changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Return only these fields per detected recurring merchant. Default when omitted omits two expensive fields: `transactions` (the matched date/amount pairs, ~29% of a row) and `confidence_reason` (prose explaining the confidence score, ~15%). `confidence` itself is always in the default. Request the rest with fields: [\"default\", \"transactions\", \"confidence_reason\"], or \"all\" / \"*\" for full rows. Unknown names are omitted and reported via _field_warning.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
get_transactions4 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Filter by category (case-insensitive substring)"New value: +"Filter by category ID from get_categories (exact match, not a name). A parent category's id also returns its subcategories' rows. An id that belongs to no category and to no transaction the call looked at is an error." - added
Input schema / properties / fieldsAdded value: +{ + "description": "Return only these fields per transaction. Default when omitted: a terse row (transaction_id, date, amount, name, category_name, account_id, item_id, pending, excluded, internal_transfer). Anything else is requestable by name alongside the preset: fields: [\"default\", \"tag_ids\"], or \"all\" / \"*\" for the whole row. THIS TOOL's own description names what its rows drop — the two modes drop different things, because a live row is not a cache document. The note is user_note in cache mode and user_notes live; either spelling works in either mode, and each mode returns its own. Unknown names are omitted and reported via _field_warning.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / transaction_id / descriptionPrevious value: -"Get a single transaction by ID (ignores other filters)"New value: +"Get a single transaction by ID (ignores other filters, though a `category` value must still be a real id)" - changed
Input schema / properties / transaction_type / descriptionPrevious value: -"Filter by special type: foreign (international), refunds, credits (cashback/rewards), duplicates (potential duplicate transactions), hsa_eligible (medical expenses), tagged (has tags)"New value: +"Filter by special type. Cache-only: foreign (international) and duplicates (potential duplicate transactions, paired among the rows the other filters keep; pass the matching exclude_*: false, e.g. exclude_deleted: false, to bring a hidden copy back). Same rule in cache and live mode (positive amount = money out). refunds: a negative REGULAR row in a spending category; never INCOME, a transfer or uncategorized. credits: a negative REGULAR row whose name has credit/cashback/reward/rebate/bonus and whose category is not income or transfer; may overlap refunds. hsa_eligible: a heuristic, not an eligibility ruling: a positive REGULAR row whose category name has health/medical/pharmac/dental/eye care/vision or whose name has cvs/walgreens/pharmacy/medical/dental/vision/hospital. tagged: has a tag. type_specific_data totals cover all matching rows, not just the returned page."
5 tool updates
v2.2.0- Removed
get_investment_performance - Changed
get_investment_splits5 fields changed- changed
Input schema / properties / end_date / descriptionPrevious value: -"End date (YYYY-MM-DD)"New value: +"Optional. Inclusive upper bound on effective_date (YYYY-MM-DD)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results (default: 100, max: 10000)"New value: +"Maximum number of rows. Default 100, max 10000." - changed
Input schema / properties / offset / descriptionPrevious value: -"Number of results to skip for pagination (default: 0)"New value: +"Pagination offset, default 0." - changed
Input schema / properties / start_date / descriptionPrevious value: -"Start date (YYYY-MM-DD)"New value: +"Optional. Inclusive lower bound on effective_date (YYYY-MM-DD)." - changed
Input schema / properties / ticker_symbol / descriptionPrevious value: -"Filter by ticker symbol (e.g., \"AAPL\", \"TSLA\")"New value: +"Optional. Case-insensitive ticker filter (e.g. \"NVDA\")."
- Removed
get_securities - Changed
get_transactions1 field changed- added
Input schema / properties / exclude_split_parentsAdded value: +{ + "default": true, + "description": "Exclude split-transaction parents (docs with children_transaction_ids). The children already carry the real categorized amounts — returning the parent would double-count the spend. Default: true.", + "type": "boolean" +}
- Removed
get_twr_returns
17 tool updates
v2.0.1- First observed
get_accounts - First observed
get_balance_history - First observed
get_budgets - First observed
get_cache_info - First observed
get_categories - First observed
get_connection_status - First observed
get_goal_history - First observed
get_goals - First observed
get_holdings - First observed
get_investment_performance - First observed
get_investment_prices - First observed
get_investment_splits - First observed
get_recurring_transactions - First observed
get_securities - First observed
get_transactions - First observed
get_twr_returns - First observed
refresh_database
TDQS
Scored across 14 tools
Each tool targets a distinct resource (transactions, accounts, holdings, budgets, goals, categories, splits, connection/cache status), and the descriptions steer callers correctly for the closest pairs (get_goals vs get_goal_history, get_accounts vs get_balance_history, get_cache_info vs get_connection_status). The main ambiguity comes from get_transactions being a six-mode mega-tool and from multiple tools referencing absent `_live` counterparts (get_transactions_live, get_investment_prices_live, get_investment_balance_live), which an agent cannot call.
All tools use snake_case with a get_<resource> pattern, and the single exception (refresh_database) still follows the verb_noun convention. Resource names are predictable and parallel across domains (get_goals/get_goal_history, get_holdings/get_investment_prices).
14 tools is well within the sweet spot for a personal-finance server covering transactions, accounts, investments, budgets, goals, and cache management. Each tool maps to a real domain object and none look redundant or padding.
Read coverage is thorough across every major domain: accounts, transactions (with search/filter/location/tag modes), balance history, budgets, categories, goals plus goal history, holdings, prices, splits, recurring charges, and cache/connection health. The gap is the absence of any mutation tools (edit transaction category, adjust budget/goal, create tags), so agents can analyze but not change anything.
Maintenance
Related MCP Connectors
Personal finance for AI agents — onboard, import statements, categorize & budget over MCP.
Read-only finance MCP server. Connects your banks, cards, payment apps, books and payroll into one ledger for your AI. Can't move money. Open source (AGPL-3.0), free during beta.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseBqualityCmaintenanceMCP server that provides AI assistants access to stock market data including financial statements, stock prices, and market news through a Model Context Protocol interface.112,317MIT
- AlicenseAqualityBmaintenanceAn MCP server implementation that provides programmatic access to personal finance data through LunchMoney's API, enabling AI assistants to manage transactions, budgets, categories, and assets.59366 npm112MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Splitwise expenses with atomic duplicate prevention, smart fuzzy matching, and support for flexible split ratios between two people.MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to perform comprehensive Microsoft Excel operations including data analysis, cell editing, advanced formatting, and VBA execution on Windows systems. It provides a structured workflow for managing workbooks and worksheets through a dedicated Model Context Protocol interface.575 npm4MIT