Skip to main content
Glama

FinBridge

Import Portfolio Holdings

import_portfolio
Destructive

Store the structured holdings explicitly entered by the user in their FinBridge portfolio. Uploaded files, screenshots, chat history and extracted file content are not supported sources for this connector. Accepts listed stocks (KR/US/TW/JP) as well as cash, crypto (BTC etc.) and physical assets (gold): stocks are matched against the database, crypto and gold (PAXG) get live ccxt quotes, cash and physical assets are stored at the given value. For ETFs or foreign products not in the database, pass value directly. If the user specifies an asset class, pass asset_class as well (cash|bond|physical|growth|dividend|crypto|other; Korean labels 현금|채권|현물|성장주|배당주|가상자산|기타 are accepted). Registered listed stocks are also added to the watchlist automatically. Use when: the user explicitly enters what they hold and wants it stored for get_portfolio. There is no per-holding edit or delete tool: to change or remove holdings, re-import the complete corrected list with replace=true (replace=false only adds/updates the rows given). Not this tool for: the watchlist (manage_watchlist — companies followed, no quantities), valuing a company (get_valuation), or reading what is already stored (get_portfolio).

IMPORTANT — read the response before telling the user you are done:

  1. Confirmation gate: if the user already has a stored portfolio, this call returns preview:true with a changes diff (added/removed/changed) and does NOT save anything, unless you pass confirm=true. Show the diff to the user — call out changes.removed especially: if the submission was only part of their holdings, those positions will look fully sold. Only pass confirm=true after the user has seen and accepted the diff (skip this if get_portfolio was empty to begin with — there is nothing to compare against).

  2. Missing fields: each saved row reports missing_fields (commonly acquired_on, since brokerage statements rarely include it) and unresolved symbols appear in needs_input — ambiguous names/codes list candidates (do not guess one), unmatched symbols need a ticker/code or a value. Rows with missing fields ARE saved (never block on incompleteness) — ask the user for the missing pieces and call this tool again for just those rows to fill them in.

  3. Cash: check the cash field. If status is not_asked, the stored portfolio has no cash balance on file (this is different from a confirmed zero) — ask the user for their cash balance (amount or % of the portfolio) and its currency, then import it as one more holding: {symbol:'현금', value, currency, asset_class:'현금'}. Without it, equity weights in get_portfolio are overstated.

  4. Always show the user the per-row summary (name/qty/avg_price recognized) before treating the import as authoritative — a misread quantity produces a wrong return. If something was saved wrong, undo it with restore_portfolio_snapshot (defaults to the snapshot right before this one).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
confirmNoSet true to apply after the user has reviewed the `changes` preview from a prior call with the same holdings/replace. Required whenever a portfolio already exists and this submission would change it; not needed for a first import into an empty portfolio.
replaceNotrue = wipe the existing portfolio (stocks + assets) and replace it; default false = merge
holdingsYesStructured holdings entered by the user. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value, acquired_on, price_symbol, unit, price_scale. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
cashNo
errorNo
notesNo
changesNo
previewNo
holdingsNo
importedNo
snapshotNo
unmatchedNo
needs_inputNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changed
    • addedInput schema / properties / confirm
      Added value: +{
      +  "description": "Set true to apply after the user has reviewed the `changes` preview from a prior call with the same holdings/replace. Required whenever a portfolio already exists and this submission would change it; not needed for a first import into an empty portfolio.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / holdings / description
      Previous value: -"Structured holdings entered by the user. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value, price_symbol, unit, price_scale. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling."New value: +"Structured holdings entered by the user. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value, acquired_on, price_symbol, unit, price_scale. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling."
    • addedInput schema / properties / holdings / items / properties / acquired_on
      Added value: +{
      +  "description": "Purchase date (YYYY-MM-DD), if the user gave one. Brokerage statements usually omit this — it is fine to leave it out and ask later.",
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
    • changedInput schema / properties / holdings / items / properties / currency / description
      Previous value: -"Display currency. Defaults to USD for crypto and US tickers, KRW otherwise."New value: +"Display currency. Defaults to USD for crypto and US tickers, KRW otherwise. Always ask when cash is mixed KRW/USD."
    • addedOutput schema / properties / cash
      Added value: +{
      +  "additionalProperties": true,
      +  "properties": {},
      +  "type": "object"
      +}
    • addedOutput schema / properties / changes
      Added value: +{
      +  "additionalProperties": true,
      +  "properties": {},
      +  "type": "object"
      +}
    • addedOutput schema / properties / needs_input
      Added value: +{
      +  "items": {
      +    "additionalProperties": true,
      +    "properties": {},
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / preview
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / snapshot
      Added value: +{
      +  "additionalProperties": true,
      +  "properties": {},
      +  "type": "object"
      +}
  2. Changed5 schema fields changed
    • changedInput schema / properties / holdings / description
      Previous value: -"Holdings read from the screenshot or table. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling."New value: +"Structured holdings entered by the user. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value, price_symbol, unit, price_scale. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling."
    • changedInput schema / properties / holdings / items / properties / asset_class / description
      Previous value: -"Asset class, passed through as shown if the screen has a type/category column. Values are stored codes: 현금 (cash) | 채권 (bonds) | 현물 (commodities) | 성장주 (growth equity) | 배당주 (dividend equity) | 가상자산 (crypto) | 기타 (other)."New value: +"Asset class supplied by the user. Values are stored codes: 현금 (cash) | 채권 (bonds) | 현물 (commodities) | 성장주 (growth equity) | 배당주 (dividend equity) | 가상자산 (crypto) | 기타 (other)."
    • changedInput schema / properties / holdings / items / properties / avg_price / description
      Previous value: -"Average purchase price, if the screen shows one"New value: +"Average purchase price supplied by the user"
    • changedInput schema / properties / holdings / items / properties / qty / description
      Previous value: -"Quantity held, if the screen shows one. Fractions are allowed (crypto)."New value: +"Quantity explicitly supplied by the user. Fractions are allowed (crypto)."
    • changedInput schema / properties / holdings / items / properties / return_pct / description
      Previous value: -"Return % as displayed on the screen"New value: +"Reference return % supplied by the user"
  3. Changed1 schema field changed
    • changedInput schema / properties / holdings / description
      Previous value: -"Holdings read from the screenshot or table"New value: +"Holdings read from the screenshot or table. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling."
  4. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true, openWorldHint=true, and readOnlyHint=false, but the description adds rich behavioral context beyond them: a confirmation gate that returns preview:true with a changes diff and does not save unless confirm=true, the fact that rows with missing fields are saved with missing_fields and needs_input, cash status not_asked meaning no balance is on file, and undo via restore_portfolio_snapshot. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage, then organized into a numbered list under an 'IMPORTANT' heading for response handling. Despite its length, each sentence earns its place by conveying essential operational detail for a complex, destructive import tool with a confirmation gate. No redundant or filler content is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, schema richness, and the presence of an output schema, the description is complete. It explains the preview/confirm workflow, how to handle missing fields and unresolved symbols, cash balance detection, and the undo path, covering everything an agent needs to invoke the tool correctly and interpret its responses.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful usage context beyond the schema, such as how different asset types are priced, when to pass value directly for ETFs or foreign products, and additional asset_class labels. However, much of the parameter-level detail (e.g., unit, price_scale, price_symbol) is already well documented in the schema, so the added value is helpful but not exhaustive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Store the structured holdings... in their FinBridge portfolio'), and explicitly distinguishes itself from siblings by naming what it is not for: 'Not this tool for: the watchlist (manage_watchlist), valuing a company (get_valuation), or reading what is already stored (get_portfolio).' It also clarifies supported sources and asset types. An agent can tell this apart from related tools without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is provided: 'Use when: the user explicitly enters what they hold and wants it stored for get_portfolio.' It also gives when-not conditions, lists alternatives, and covers prerequisites through the confirmation gate, missing fields, cash handling, and undo instructions. The routing logic is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.