Skip to Content
GuidesMCP Tool Reference

MCP Tool Reference

Bliss exposes 42 tools over MCP at POST /api/mcp: 22 read tools available to every integration key and 20 write tools available only to Read & write keys. Setup: Use Bliss with Claude (MCP).

Conventions: dates are YYYY-MM-DD; amounts are { value, currency }; transaction amounts are signed (positive = money in, negative = money out); lists return hasMore and nextCursor — pass nextCursor back as cursor for the next page (default 50 items, max 100).

Reference data

list_accounts — List accounts

Access: Read (all keys)
Wraps: GET /api/accounts

List the user’s bank, card and brokerage accounts with their IDs, bank, currency and country. Use the returned id as accountId in other tools.

ParameterTypeRequiredDescription
currencyCodestringnoOnly accounts in this currency (ISO code).
countryIdstringnoOnly accounts in this country (ISO country code).
limitintegernoItems per page (1-100, default 100).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

list_categories — List categories

Access: Read (all keys)
Wraps: GET /api/categories

List transaction categories with their IDs, group and type (e.g. type “Essentials”, group “Food”). Categories are what transactions, review items and import rows are classified into. Filter by name (partial, case-insensitive), group or type.

ParameterTypeRequiredDescription
namestringnoPartial category name, case-insensitive.
groupstringnoExact category group, e.g. “Food”.
typestringnoExact category type, e.g. “Income”, “Essentials”, “Investments”.
limitintegernoItems per page (1-100, default 100).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

get_reference_data — Get reference data

Access: Read (all keys)
Wraps: GET /api/tenants, GET /api/tenants/settings, GET /api/banks, GET /api/countries, GET /api/currencies, GET /api/currency-rates

Reference data for the user’s workspace. tenant: display (portfolio) currency, enabled currencies and countries, years that have transactions, and classification thresholds — call it first to learn the currency to use for summaries. banks, countries, currencies: global lists (use search to filter). fxRates: stored exchange rates for one date (requires fxDate).

ParameterTypeRequiredDescription
kindsarray of tenant | banks | countries | currencies | fxRatesnoWhich lists to return (default [“tenant”]).
searchstringnoSubstring filter for banks, countries and currencies.
fxDatestringnoDate of the FX rates (YYYY-MM-DD)
fxFromstringnoFX rates from this currency only.
fxTostringnoFX rates to this currency only.

search_ticker — Search tickers

Access: Read (all keys)
Wraps: GET /api/ticker/search

Look up stock, ETF or crypto tickers by symbol or company name (market data provider search).

ParameterTypeRequiredDescription
querystringyesSymbol or name, e.g. “VWCE” or “Apple”.
typestringnoOptional instrument type filter passed to the provider.
limitintegernoMax results (default 20).

list_tags — List tags

Access: Read (all keys)
Wraps: GET /api/tags

List tags (free labels such as trips or projects, optionally with a budget and date range) with their IDs.

ParameterTypeRequiredDescription
limitintegernoItems per page (1-100, default 100).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

manage_tags — Create, update or delete a tag

Access: Write (Read & write keys only) · can delete or discard data
Wraps: POST /api/tags, PUT /api/tags, DELETE /api/tags

create: new tag (name required). update: change name, color, emoji, budget or dates of tagId. delete: remove tagId (refused while transactions still use it). Tag transactions with update_transaction.

ParameterTypeRequiredDescription
actioncreate | update | deleteyes
tagIdintegernoTag ID (update/delete). From list_tags.
namestringno
colorstringnoHex color, e.g. “#6D657A”.
emojistringno
budgetnumber | nullnoBudget amount; null clears it.
startDatestring | nullnoStart date (YYYY-MM-DD)
endDatestring | nullnoEnd date (YYYY-MM-DD)

Workspace setup

create_bank — Create bank

Access: Write (Read & write keys only)
Wraps: POST /api/banks

Add a bank (or broker, card issuer…) to the user’s workspace and return its ID for create_account. Idempotent: if a bank with this name already exists (any casing) it is reused and linked, never duplicated; created is false when the workspace already had it. This is the way to get a bankId — the banks in get_reference_data are a global list that may include banks this workspace has not linked. Bank creation shares a budget of 10 requests per 5 minutes with bank listing: reuse IDs you already have (from list_accounts or earlier calls) instead of calling this again.

ParameterTypeRequiredDescription
namestringyesBank name, e.g. “Revolut” (2-100 characters).

create_account — Create account

Access: Write (Read & write keys only)
Wraps: POST /api/accounts

Create a manual account (bank, card, savings, brokerage…) in the user’s workspace, then use its id as accountId when creating transactions or importing. Get bankId from create_bank. currencyCode and countryId must already be enabled for the workspace (get_reference_data → tenant lists them); if not, ask the user to enable them in Settings. Owners default to the admin who connected Bliss; other users can be added in the app. Safe to retry: a second account with the same bank, currency and name is refused with the existing account’s id. Bank-synced (Plaid) accounts are connected in the app, not here.

ParameterTypeRequiredDescription
namestringyesAccount name, e.g. “Revolut EUR” (1-100 characters).
bankIdintegeryesBank ID from create_bank.
currencyCodestringyesAccount currency, 3-letter ISO 4217 code, e.g. EUR.
countryIdstringyesAccount country, ISO 3166 alpha-3 code as listed by get_reference_data (e.g. DEU, USA, GBR).
accountNumberstringyesAccount number or IBAN. Stored encrypted and never shown back (only the last 4 characters) — use the last 4 digits or a short label if the user prefers not to share it.
ownerIdsarray of stringnoUser IDs of the owners. Omit to make the connecting admin the owner.

Transactions

search_transactions — Search transactions

Access: Read (all keys)
Wraps: GET /api/transactions

Search committed transactions, newest first. totals (in / out / net over the whole filtered set, not just this page) is only returned when currency is set. Amounts are signed: positive = money in (credit), negative = money out (debit), in the transaction’s own currency. Filter by date range, account, category, category group/type, tag, currency, source or amount range. To find one transaction, combine a date range with amountMin = amountMax (e.g. 2003.76 for a €2,003.76 payment) and/or a category. Descriptions are encrypted at rest and cannot be searched: to find a merchant use get_merchant_history, or narrow by date/amount/category and read the page.

ParameterTypeRequiredDescription
fromstringnoStart date, inclusive (YYYY-MM-DD)
tostringnoEnd date, inclusive (YYYY-MM-DD)
accountIdintegernoAccount ID from list_accounts.
categoryIdintegernoCategory ID from list_categories.
categoryGroupstringnoCategory group, e.g. “Food”.
categoryTypestringnoCategory type, e.g. “Essentials” or “Income”.
tagstringnoTag name or tag ID.
currencystringnoOnly transactions in this currency. Required for totals.
sourceMANUAL | PLAID | CSVno
amountMinnumbernoSmallest amount, inclusive: an unsigned amount in the transaction’s own currency, matched against money in or out at 2-decimal precision.
amountMaxnumbernoLargest amount, inclusive: an unsigned amount in the transaction’s own currency, matched against money in or out at 2-decimal precision.
limitintegernoItems per page (1-100, default 50).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

get_merchant_history — Get merchant history

Access: Read (all keys)
Wraps: GET /api/transactions/merchant-history

Past bank-synced (Plaid) transactions whose merchant or name contains description, with the category each was filed under — useful to decide how to categorise a new charge from the same merchant.

ParameterTypeRequiredDescription
descriptionstringyesMerchant name or part of it.
limitintegernoMax results (default 10).

create_transaction — Create transaction

Access: Write (Read & write keys only)
Wraps: POST /api/transactions

Record a manual transaction. Same effect as adding it in the app: analytics and portfolio update and the category choice trains the classifier. Stock, ETF/fund and crypto categories (buys and sells) require assetQuantity and assetPrice (both > 0) and a ticker. Only in the built-in Funds category is the ticker optional (private / unlisted funds have none); ETFs always need one. All three are optional for manually valued investments.

ParameterTypeRequiredDescription
datestringyesTransaction date (YYYY-MM-DD)
accountIdintegeryesAccount ID from list_accounts.
categoryIdintegeryesCategory ID from list_categories.
descriptionstringyes
amountnumberyesSigned amount: positive = money in (credit), negative = money out (debit).
currencystringyesISO currency of the amount, usually the account currency.
detailsstringnoFree-text note.
tagsarray of stringnoTag names (created if new).
tickerstringno
assetQuantitynumberno
assetPricenumberno
exchangestringnoISO-10383 MIC of the listing (mic_code from search_ticker), e.g. “XETR”. Pass it when the ticker trades on several exchanges.
isinstringnoISIN of the security, e.g. “US67066G1040”.

update_transaction — Update transaction

Access: Write (Read & write keys only)
Wraps: GET /api/transactions, PUT /api/transactions

Change fields of a transaction (only the ones you pass). Re-categorising here is identical to doing it in the app: it teaches the classifier and refreshes analytics. tags replaces the whole tag list. A stock, ETF/fund or crypto transaction must end up with assetQuantity and assetPrice (both > 0) and a ticker (optional only in the built-in Funds category).

ParameterTypeRequiredDescription
transactionIdintegeryesTransaction ID from search_transactions.
datestringnoNew date (YYYY-MM-DD)
accountIdintegernoNew account ID.
categoryIdintegernoNew category ID.
descriptionstringno
detailsstring | nullno
amountnumbernoSigned amount: positive = money in (credit), negative = money out (debit).
currencystringno
tagsarray of stringnoFull list of tag names (replaces).
tickerstringno
assetQuantitynumberno
assetPricenumberno
exchangestringnoISO-10383 MIC of the listing (mic_code from search_ticker), e.g. “XETR”. Pass it when the ticker trades on several exchanges.
isinstringnoISIN of the security, e.g. “US67066G1040”.

bulk_update_transactions — Recategorise transactions in bulk

Access: Write (Read & write keys only)
Wraps: PATCH /api/transactions/bulk

Recategorise up to 50 committed transactions in one call. All-or-nothing: if any ID is not found, or the target category or a row’s current category is Investments or Debt, nothing changes. Category only: for tags or other fields use update_transaction. Trains the classifier for each changed row and refreshes analytics once. Rows already in the category are reported as unchanged.

ParameterTypeRequiredDescription
idsarray of integeryes1 to 50 distinct transaction IDs from search_transactions.
categoryIdintegeryesTarget category ID from list_categories (not Investments or Debt).

delete_transaction — Delete transaction

Access: Write (Read & write keys only) · can delete or discard data
Wraps: DELETE /api/transactions

Permanently delete a transaction. A bank-synced source item goes back to the review queue.

ParameterTypeRequiredDescription
transactionIdintegeryesTransaction ID from search_transactions.

Analytics, insights & notifications

get_spending_summary — Get income and spending summary

Access: Read (all keys)
Wraps: GET /api/analytics, GET /api/tenants/settings

Income and spending totals per period, by category type and category group, from the same pre-computed analytics as the Analytics page (all currencies converted into one). in = credits, out = debits (positive numbers), net = in - out. For a single category (not group), sum search_transactions instead.

ParameterTypeRequiredDescription
viewmonth | quarter | yearyesPeriod granularity.
fromstringyesFirst period: “YYYY-MM” (month), “YYYY-Qn” (quarter) or “YYYY” (year).
tostringyesLast period, same format as from (inclusive).
currencystringnoCurrency the totals are expressed in (default: the display currency from get_reference_data).
typesarray of stringnoOnly these category types, e.g. [“Essentials”].
groupsarray of stringnoOnly these category groups, e.g. [“Food”].
countriesarray of stringnoOnly accounts in these countries (ISO codes).
limitintegernoItems per page (1-100, default 100).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

get_tag_summary — Get tag summary

Access: Read (all keys)
Wraps: GET /api/analytics/tags, GET /api/tenants/settings

Income and spending for tagged transactions (e.g. a trip), per tag and period, broken down by category. Amounts in one currency; out = spending, in = income.

ParameterTypeRequiredDescription
tagIdsarray of integeryesTag IDs from list_tags.
viewmonth | quarter | yearyesPeriod granularity.
fromstringyesFirst period: “YYYY-MM” (month), “YYYY-Qn” (quarter) or “YYYY” (year).
tostringyesLast period, same format as from (inclusive).
currencystringnoCurrency the totals are expressed in (default: the display currency from get_reference_data).

list_insights — List insights

Access: Read (all keys)
Wraps: GET /api/insights

AI-generated financial insights: tiers MONTHLY, QUARTERLY and ANNUAL health checks, and PORTFOLIO notes (generated weekly; there is no WEEKLY tier), most important first. Dismissed insights are hidden unless includeDismissed is true.

ParameterTypeRequiredDescription
tierMONTHLY | QUARTERLY | ANNUAL | PORTFOLIOno
categorySPENDING | INCOME | SAVINGS | PORTFOLIO | DEBT | NET_WORTHno
severityINFO | WARNING | POSITIVE | CRITICALno
periodKeystringnoe.g. “2026-03” (MONTHLY), “2026-Q1” (QUARTERLY), “2025” (ANNUAL), “2026-W14” (PORTFOLIO).
includeDismissedbooleanno
limitintegernoItems per page (1-100, default 20).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

generate_insights — Generate insights

Access: Write (Read & write keys only)
Wraps: POST /api/insights

Start AI insight generation for a period (runs in the background; check list_insights in a few minutes). Defaults to the current month/quarter/year. Unchanged data is skipped unless force is true.

ParameterTypeRequiredDescription
tierMONTHLY | QUARTERLY | ANNUAL | PORTFOLIOyes
yearintegerno
monthintegernoMONTHLY only.
quarterintegernoQUARTERLY only.
forcebooleanno

dismiss_insight — Dismiss or restore an insight

Access: Write (Read & write keys only)
Wraps: PUT /api/insights

Hide an insight (dismissed: true, the default) or bring it back (dismissed: false).

ParameterTypeRequiredDescription
insightIdstringyesInsight ID from list_insights.
dismissedbooleanno

get_notifications_summary — Get notifications summary

Access: Read (all keys)
Wraps: GET /api/notifications/summary

What needs the user’s attention: pending review items (bank sync + imports), failed classifications, bank connections needing action, new insights and onboarding steps.

No parameters.

get_processing_status — Get background processing status

Access: Read (all keys)
Wraps: GET /api/activity

Whether derived data is still being recalculated after a change. Writes (transactions, tags, manual values, imports, bank-sync approvals) refresh portfolio values and analytics in the background: poll this until inFlight has nothing whose affects includes the data you changed (settled = nothing in flight at all), then read the summaries. summary has one row per activity type (PORTFOLIO_UPDATE, ANALYTICS_UPDATE, BANK_SYNC, IMPORT, SECURITY_DATA, SUBSCRIPTION_SCAN, INSIGHTS) with state queued | running | stalled | failed, stage and progress (0-100). lastCompletedAt is per type; recent holds the latest finished jobs (last 24 h) with errorCode on failures. available: false means status is unknown, not idle; workerOnline: false means the background worker is down and queued work will not start.

No parameters.

Bank-sync (Plaid) review queue

get_plaid_review_queue — Get bank-sync review queue

Access: Read (all keys)
Wraps: GET /api/plaid/transactions

Bank-synced transactions waiting for review, each with an AI-suggested category and confidence (0-1). Default status CLASSIFIED = ready to approve. FAILED = classification failed (retry with requeue_plaid_transactions). SKIPPED = the user skipped them. Amounts: negative = money out. summary counts items per status. Approve or re-categorise with review_plaid_transactions.

ParameterTypeRequiredDescription
statusCLASSIFIED | PENDING | SKIPPED | FAILED | PROMOTED | ALLno
minConfidencenumberno
maxConfidencenumberno
categoryIdintegernoOnly items suggested into this category.
uncategorizedbooleannoOnly items without a suggested category.
limitintegernoItems per page (1-100, default 50).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

review_plaid_transactions — Review bank-sync items

Access: Write (Read & write keys only)
Wraps: PUT /api/plaid/transactions/[id], POST /api/plaid/transactions/bulk-promote

Act on review queue items. items (max 50): approve (creates the transaction; optional categoryId overrides the suggestion), recategorize (categoryId required, stays in the queue), skip, or unskip. Investment categories need ticker, assetQuantity and assetPrice to approve. bulkPromote approves many at once: every CLASSIFIED item with confidence >= minConfidence, or exactly the given ids. Pass either items or bulkPromote.

ParameterTypeRequiredDescription
itemsarray of object { id, action, categoryId, ticker, assetQuantity, assetPrice, details }no
bulkPromoteobject { minConfidence, ids, categoryId, overrideCategoryId }no

requeue_plaid_transactions — Re-queue bank-sync items

Access: Write (Read & write keys only)
Wraps: POST /api/plaid/transactions/[id]/retry, POST /api/plaid/transactions/bulk-requeue

failedIds: retry classification of FAILED items (max 50). allSkipped: true: send every SKIPPED item back to the review queue (optionally only for one plaidItemId).

ParameterTypeRequiredDescription
failedIdsarray of stringno
allSkippedbooleanno
plaidItemIdstringnoBank connection ID (plaidItemId from the queue items).

list_plaid_seeds — List bank-sync seeds

Access: Read (all keys)
Wraps: GET /api/plaid/transactions/seeds

After a new bank connection, its most frequent merchants are held back as “seeds” for the user to confirm once. Lists them for one plaidItemId (from get_plaid_review_queue items or the notifications summary).

ParameterTypeRequiredDescription
plaidItemIdstringyes
limitintegernoMax seeds (default 15).

confirm_plaid_seeds — Confirm bank-sync seeds

Access: Write (Read & write keys only)
Wraps: POST /api/plaid/transactions/confirm-seeds

Confirm categories for seeds from list_plaid_seeds. Each confirmed seed trains the classifier and releases the held transactions of that merchant.

ParameterTypeRequiredDescription
plaidItemIdstringyes
seedsarray of object { description, rawName, categoryId }yes

Smart Import review

list_imports — List staged imports

Access: Read (all keys)
Wraps: GET /api/imports/pending, GET /api/imports/[id]

Without importId: imports (uploaded statements) that still have rows to review. With importId: that import’s status, row counts per status, category summary and a page of rows. Files are uploaded in the Bliss app — if nothing is pending, ask the user to upload the statement there first. Row statuses: PENDING (needs review), CONFIRMED (will be committed), POTENTIAL_DUPLICATE, DUPLICATE, SKIPPED, ERROR.

ParameterTypeRequiredDescription
importIdstringno
statusarray of PENDING | CONFIRMED | POTENTIAL_DUPLICATE | DUPLICATE | SKIPPED | ERROR | STAGEDnoOnly rows with these statuses (importId only).
uncategorizedbooleannoOnly rows without a suggested category (importId only).
categoryIdintegernoOnly rows suggested into this category (importId only).
limitintegernoItems per page (1-100, default 50).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

review_import_rows — Review staged import rows

Access: Write (Read & write keys only)
Wraps: PUT /api/imports/[id]/rows/[rowId], POST /api/imports/[id]/bulk-confirm

rows (max 50): set a row’s category, status (CONFIRMED to include it in the commit, SKIPPED to leave it out, PENDING to undo), account, details, tags or investment fields. bulkConfirm: confirm every reviewable row at once, or only those suggested into categoryId, or only uncategorised ones. Pass either rows or bulkConfirm. Commit afterwards with finalize_import.

ParameterTypeRequiredDescription
importIdstringyesImport ID from list_imports.
rowsarray of object { rowId, categoryId, status, accountId, details, tags, ticker, assetQuantity, assetPrice }no
bulkConfirmobject { categoryId, uncategorized }no

list_import_seeds — List import seeds

Access: Read (all keys)
Wraps: GET /api/imports/[id]/seeds

The most frequent descriptions in a staged import with their suggested category — confirming these first categorises many rows at once (confirm_import_seeds).

ParameterTypeRequiredDescription
importIdstringyesImport ID from list_imports.
limitintegernoMax seeds (default 15).

confirm_import_seeds — Confirm import seeds

Access: Write (Read & write keys only)
Wraps: POST /api/imports/[id]/confirm-seeds

Confirm a category for each seed description: every PENDING/CONFIRMED row with that exact description gets the category and is marked CONFIRMED, and the classifier learns it.

ParameterTypeRequiredDescription
importIdstringyesImport ID from list_imports.
seedsarray of object { description, categoryId }yes

finalize_import — Commit or cancel a staged import

Access: Write (Read & write keys only) · can delete or discard data
Wraps: POST /api/imports/[id]

commit: create transactions from the import’s CONFIRMED rows (optionally only rowIds); runs in the background — poll list_imports with importId for progress. cancel: discard the import and all its rows.

ParameterTypeRequiredDescription
importIdstringyesImport ID from list_imports.
actioncommit | cancelyes
rowIdsarray of stringnocommit only: a subset of rows.

Portfolio & passive income

get_portfolio_holdings — Get portfolio holdings

Access: Read (all keys)
Wraps: GET /api/portfolio/items, GET /api/portfolio/assets, GET /api/portfolio/holdings

view “positions” (default): current investments, assets and debts with quantity, market value, cost basis and P&L in the holding’s currency plus marketValueDisplay in the display currency. view “attention”: the Manage Assets list with what needs action (stale manual price, missing income or debt terms, lot mismatch). view “snapshots”: stored daily holding snapshots (quantity/value/cost) for one ticker or account. Use the assetId in the other portfolio tools.

ParameterTypeRequiredDescription
viewpositions | attention | snapshotsno
accountIdintegernoOnly holdings in this account.
categoryTypeInvestments | Asset | Debtnopositions only.
searchstringnoattention only: symbol/name search.
statusstale | debtTermsMissing | incomeMissing | lotMismatch | dividendOverride | assetClassOverriddennoattention only: filter by status.
tickerstringnosnapshots only: symbol.
limitintegernoItems per page (1-100, default 50).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

get_portfolio_history — Get portfolio value history

Access: Read (all keys)
Wraps: GET /api/portfolio/history

Total portfolio value over time (net worth of investments, assets and debts) in the display currency, with the split per category type. Prefer resolution “monthly” or “weekly” for long ranges. Pass symbol for one holding’s value over time (summed across accounts unless accountId is set), or itemId for a single item (manual assets such as real estate); not both.

ParameterTypeRequiredDescription
fromstringnoStart date (YYYY-MM-DD)
tostringnoEnd date (YYYY-MM-DD)
resolutiondaily | weekly | monthlyno
typesarray of Investments | Asset | Debtno
groupsarray of stringnoOnly these category groups.
accountIdintegernoOnly this account.
symbolstringnoOnly this holding (all items with this symbol).
itemIdintegernoOnly this portfolio item (asset ID from get_portfolio_holdings).
limitintegernoItems per page (1-100, default 100).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

get_equity_analysis — Get equity analysis

Access: Read (all keys)
Wraps: GET /api/portfolio/equity-analysis

Stock and ETF holdings grouped by sector, industry, country or asset class, with weights, weighted P/E and dividend yield. ETFs are looked through into their sectors/countries unless lookThrough is false. pendingSecurityData lists fund symbols left out until their security data is fetched.

ParameterTypeRequiredDescription
groupBysector | industry | country | assetClassno
accountIdintegernoOnly this account.
lookThroughbooleanno
topHoldingsintegernoHow many largest holdings to include (default 20).

get_passive_income — Get passive income projection

Access: Read (all keys)
Wraps: GET /api/portfolio/passive-income, GET /api/portfolio/income-terms/detached, GET /api/passive-income/streams

Projected dividends, bond coupons, rent, interest and other income streams for the next 12/24/36 months (display currency), next to the last 12 months of actual passive income. Also lists holdings missing income terms, user-defined income streams and detached terms left over from re-keyed holdings. Every amount is in the display currency (currency); the monthly/yearly series are plain numbers in it. byHolding[].holdingCurrency is the holding’s own currency, for reference only.

ParameterTypeRequiredDescription
horizon12 | 24 | 36no

get_holding_details — Get holding details

Access: Read (all keys)
Wraps: GET /api/portfolio/items/[assetId]/asset-class, GET /api/portfolio/items/[assetId]/income-terms, GET /api/portfolio/items/[assetId]/debt-terms, GET /api/portfolio/items/[assetId]/manual-values

Everything about one holding: asset class (and whether it is overridden), income terms (dividends, coupons, rent, interest), debt terms (loans) and the most recent manual valuations (per-unit prices). incomeTermsKind (STOCK, ETF, FUND, BOND, REAL_ESTATE, CASH, OTHER) is the income terms form, not the asset class.

ParameterTypeRequiredDescription
assetIdintegeryesAsset (portfolio item) ID from get_portfolio_holdings.
manualValuesLimitintegernoMost recent manual values (default 20).

set_asset_class — Set asset class

Access: Write (Read & write keys only)
Wraps: PUT /api/portfolio/items/[assetId]/asset-class

Override the automatic asset class of a holding (null restores the automatic one). applyToSymbol applies it to every holding of the same symbol across accounts.

ParameterTypeRequiredDescription
assetIdintegeryesAsset (portfolio item) ID from get_portfolio_holdings.
assetClassSTOCK | INDEX_ETF | SECTOR_ETF | BOND_ETF | REIT | FUND | GOV_BOND | CORP_BOND | REAL_ESTATE | CRYPTO | CASH | OTHER | nullyes
applyToSymbolbooleanno

manage_manual_values — Add, update or delete a manual valuation

Access: Write (Read & write keys only) · can delete or discard data
Wraps: POST /api/portfolio/items/[assetId]/manual-values, PUT /api/portfolio/items/[assetId]/manual-values/[valueId], DELETE /api/portfolio/items/[assetId]/manual-values/[valueId]

Manual valuations price holdings without market data (property, private assets, cash-like accounts); holdings priced from market data (stocks, ETFs, crypto with a ticker) refuse them. value is the PRICE PER UNIT, not the position total: market value = value × quantity. To enter a statement total, divide it by the holding quantity first (get_portfolio_holdings). add: date, value and currency required. update: valueId plus the fields to change. delete: valueId. add/update return currentQuantity and impliedMarketValue so the result can be checked. Each change triggers a portfolio revaluation. valueId comes from get_holding_details.

ParameterTypeRequiredDescription
assetIdintegeryesAsset (portfolio item) ID from get_portfolio_holdings.
actionadd | update | deleteyes
valueIdstringno
datestringnoValuation date (YYYY-MM-DD)
valuenumbernoPrice per unit on that date (NOT the position total; market value = value × quantity).
currencystringno
notesstringno

manage_income_and_debt_terms — Set or remove income / debt terms

Access: Write (Read & write keys only) · can delete or discard data
Wraps: PUT /api/portfolio/items/[assetId]/income-terms, DELETE /api/portfolio/items/[assetId]/income-terms, DELETE /api/portfolio/income-terms/[id], POST /api/portfolio/income-terms/[id]/attach, POST /api/portfolio/items/[assetId]/debt-terms, PUT /api/portfolio/items/[assetId]/debt-terms

target “income”: set (assetId + terms; applyToSymbol copies them to every holding of the symbol), delete (assetId), attach (termsId of detached terms + assetId), deleteDetached (termsId). target “debt”: set (assetId + debt fields; creates or replaces the loan terms). Terms drive the passive income projection and loan amortisation.

ParameterTypeRequiredDescription
targetincome | debtyes
actionset | delete | attach | deleteDetachedyes
assetIdintegernoAsset (portfolio item) ID from get_portfolio_holdings.
termsIdintegernoDetached income terms ID from get_passive_income.
applyToSymbolbooleanno
termsobject { incomeType, isDistributing, frequency, currency, dividendPerUnit, yieldPct, faceValuePerUnit, couponRate, spread, assumedIndexRate, referenceIndex, issuerType, maturityDate, anchorPaymentDate, monthlyRent, annualIndexationPct, leaseEndDate, apyPct }noIncome terms (replaces the existing terms). Rates are percentages.
initialBalancenumbernodebt: original loan amount.
interestRatenumbernodebt: annual interest rate, percent.
termInMonthsintegernodebt: loan term.
originationDatestringnodebt: loan start (YYYY-MM-DD)

manage_passive_income_streams — Create, update or delete an income stream

Access: Write (Read & write keys only) · can delete or discard data
Wraps: POST /api/passive-income/streams, PUT /api/passive-income/streams/[id], DELETE /api/passive-income/streams/[id], GET /api/passive-income/streams

Income streams are recurring fixed amounts not produced by a holding (allowance, pension, government benefit). create: categoryId (one of eligibleStreamCategories from get_passive_income), name, amountPerPayment, frequency, currency and startDate. update: streamId plus fields to change. delete: streamId.

ParameterTypeRequiredDescription
actioncreate | update | deleteyes
streamIdintegernoStream ID from get_passive_income.
categoryIdintegernoEligible Passive Income category.
namestringno
amountPerPaymentnumberno
frequencyWEEKLY | MONTHLY | QUARTERLY | SEMIANNUAL | ANNUALno
currencystringno
startDatestringnoFirst payment (YYYY-MM-DD)
endDatestring | nullnoLast payment (YYYY-MM-DD)
anchorPaymentDatestringnoA known payment date (YYYY-MM-DD)
annualIndexationPctnumberno

Subscriptions

list_subscriptions — List subscriptions

Access: Read (all keys)
Wraps: GET /api/subscriptions

Detected recurring charges, one per merchant: cadence, amount, next expected charge and whether it is still ACTIVE or LAPSED. state DETECTED = needs the user’s review, CONFIRMED = accepted, DISMISSED = not a subscription. summary has the monthly and annual recurring spend in the display currency. view “all” also shows dismissed, merged and split (splitByAmount: true) rows.

ParameterTypeRequiredDescription
viewactive | lapsed | allno
categoryIdintegernoOnly this category.
limitintegernoItems per page (1-100, default 25).
cursorstringnoOpaque cursor from a previous result’s nextCursor. Omit for the first page.

update_subscription — Update a subscription

Access: Write (Read & write keys only) · can delete or discard data
Wraps: POST /api/subscriptions

confirm (subscriptionId, or transactionId to mark a transaction’s merchant as recurring), dismiss (not a subscription), restore (undo dismiss), setCadence (cadence), rename (merchantLabel), merge (subscriptionId folded into targetSubscriptionId, e.g. two descriptors of one merchant), unmerge, split (one row per distinct recurring amount, e.g. two subscriptions billed by Apple at 22.00 and 22.99; kept across scans), unsplit, refresh (re-run detection; at most every 30 minutes).

ParameterTypeRequiredDescription
actionconfirm | dismiss | restore | setCadence | rename | merge | unmerge | split | unsplit | refreshyes
subscriptionIdstringno
transactionIdintegernoconfirm only: a transaction of the merchant.
cadenceWEEKLY | MONTHLY | QUARTERLY | ANNUALno
merchantLabelstringno
targetSubscriptionIdstringnomerge only: the row to keep.

Not available over MCP

These REST operations are reachable with an integration key but have no tool, on purpose:

OperationWhy
POST /api/imports/uploadFile upload stays in the app
POST /api/imports/detect-adapterFile upload stays in the app
GET /api/imports/adaptersImport adapter configuration is a UI job
POST /api/imports/adaptersImport adapter configuration is a UI job
GET /api/imports/similarReturns raw classifier embedding matches (no description); staged rows already carry the suggested category
PUT /api/imports/adapters/[id]Import adapter configuration is a UI job
DELETE /api/imports/adapters/[id]Import adapter configuration is a UI job
GET /api/plaid/itemsPlaid connections are managed in the app
GET /api/plaid/accountsPlaid connections are managed in the app
GET /api/plaid/sync-logsPlaid connections are managed in the app
POST /api/currency-ratesReference-data writes stay in the app
PUT /api/currency-ratesReference-data writes stay in the app
DELETE /api/currency-ratesReference-data writes stay in the app
GET /api/transactions/exportCSV export; search_transactions pages the same data
POST /api/analyticsAnalytics cache maintenance, not user data (501 today)
PUT /api/analyticsAnalytics cache maintenance, not user data (501 today)
DELETE /api/analyticsAnalytics cache maintenance, not user data (501 today)
PUT /api/notifications/summaryMarks the creating admin’s notifications as seen
GET /api/onboarding/progressOnboarding UI state
PUT /api/onboarding/progressOnboarding UI state
POST /api/subscriptions action fullScanMaintenance (Settings → Maintenance)