Skip to main content
Glama

buy

Destructive

Records a completed purchase in the local ledger, updating existing positions at weighted-average cost or opening new ones for unseen symbols; it never places broker orders.

Instructions

Record a buy in the local ledger: adds to an existing position with weighted-average cost, or opens a new position for an unseen symbol. This bookkeeps a trade the user already placed with their broker — openInvest never places real orders.

Confirm symbol, units, and price with the user before calling; this moves ledger cash. A position the user already held before using openInvest is not a purchase: record it with record_existing_position. Off-exchange China mutual funds (FUND:<6 digits>) settle T+1 or later at the NAV of the pricing day: use place_fund_order + confirm_fund_order instead (buy books them as instantly filled and total assets dip by the amount until the real confirmation).

Args: symbol: yfinance ticker (e.g. "AAPL", "510300.SS"). Gold = "GC=F", booked in CNY per gram only (units = grams, currency "CNY", kind "metal", unit_label "克"). units: Quantity bought; must be > 0. price: Execution price per unit, in currency. currency: Currency of price; omitted = the existing position's currency (CNY if new). kind: Asset kind tag: "equity", "etf", "metal" (gold), "crypto", "bond", "fund", "other". unit_label: Human display label for units (default "股", i.e. shares). idempotency_key: Reuse the same key when retrying this exact call; recorded once.

Returns: Updated position summary, or {"status": "error", "error": ...}.

Input Schema

NameRequiredDescriptionDefault
kindNoAsset kind tag: 'equity', 'etf', 'metal' (gold), 'crypto', 'bond', 'fund', 'other'.equity
priceYesExecution price per unit, in `currency`.
unitsYesQuantity bought; must be > 0.
symbolYesyfinance ticker, e.g. 'AAPL', '510300.SS'. Gold is 'GC=F' and must be booked per gram in CNY: units = grams, price = CNY/gram, currency='CNY', kind='metal', unit_label='克' (USD/oz bookings are rejected).
currencyNoCurrency of `price`, e.g. 'CNY', 'USD', 'AUD'. Omit to use the existing position's currency (CNY for a new position); a different currency than the position's is rejected.
unit_labelNoHuman display label for units (default '股', i.e. shares).股
idempotency_keyNoOptional client-generated key (e.g. a UUID4). When retrying this SAME call after a timeout or an unknown result, reuse the same key: the ledger records it once and later calls return {"status": "duplicate"} without touching cash or holdings. Only the key is compared, not the arguments — a different order (other symbol/units/price/amount) needs a new key, or it is silently treated as the retry.
existing_positionNoNot supported on buy. For a position held before using openInvest call `record_existing_position`; passing true here returns an error instead of deducting cash.

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.45.1
    • addedInput schema / properties / idempotency_key
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Optional client-generated key (e.g. a UUID4). When retrying this SAME call after a timeout or an unknown result, reuse the same key: the ledger records it once and later calls return {\"status\": \"duplicate\"} without touching cash or holdings. Only the key is compared, not the arguments — a different order (other symbol/units/price/amount) needs a new key, or it is silently treated as the retry.",
      +  "title": "Idempotency Key"
      +}
    • changedInput schema / properties / kind / description
      Previous value: -"Asset kind tag, e.g. 'equity', 'etf', 'commodity'."New value: +"Asset kind tag: 'equity', 'etf', 'metal' (gold), 'crypto', 'bond', 'fund', 'other'."
    • changedInput schema / properties / symbol / description
      Previous value: -"yfinance ticker, e.g. 'AAPL', '510300.SS', 'GC=F'."New value: +"yfinance ticker, e.g. 'AAPL', '510300.SS'. Gold is 'GC=F' and must be booked per gram in CNY: units = grams, price = CNY/gram, currency='CNY', kind='metal', unit_label='克' (USD/oz bookings are rejected)."
  2. Changed4 schema fields changedv0.42.4
    • addedInput schema / properties / currency / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / currency / default
      Previous value: -"CNY"New value: +null
    • changedInput schema / properties / currency / description
      Previous value: -"Currency of `price`, e.g. 'CNY', 'USD', 'AUD'."New value: +"Currency of `price`, e.g. 'CNY', 'USD', 'AUD'. Omit to use the existing position's currency (CNY for a new position); a different currency than the position's is rejected."
    • removedInput schema / properties / currency / type
      Removed value: -"string"
  3. Changed1 schema field changedv0.41.2
    • addedInput schema / properties / existing_position
      Added value: +{
      +  "default": false,
      +  "description": "Not supported on buy. For a position held before using openInvest call `record_existing_position`; passing true here returns an error instead of deducting cash.",
      +  "title": "Existing Position",
      +  "type": "boolean"
      +}
  4. Addedv0.34.0
  5. Removedv0.31.7
  6. Changed8 schema fields changedv0.31.4
    • addedInput schema / properties / currency / description
      Added value: +"Currency of `price`, e.g. 'CNY', 'USD', 'AUD'."
    • addedInput schema / properties / kind / description
      Added value: +"Asset kind tag, e.g. 'equity', 'etf', 'commodity'."
    • addedInput schema / properties / price / description
      Added value: +"Execution price per unit, in `currency`."
    • addedInput schema / properties / price / exclusiveMinimum
      Added value: +0
    • addedInput schema / properties / symbol / description
      Added value: +"yfinance ticker, e.g. 'AAPL', '510300.SS', 'GC=F'."
    • addedInput schema / properties / unit_label / description
      Added value: +"Human display label for units (default '股', i.e. shares)."
    • addedInput schema / properties / units / description
      Added value: +"Quantity bought; must be > 0."
    • addedInput schema / properties / units / exclusiveMinimum
      Added value: +0
  7. First observedv0.31.0

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, so the write/cash impact is partly covered. The description still adds real value beyond them: it is pure bookkeeping (no real orders are placed), it moves ledger cash, it requires user confirmation first, and it discloses the fund-settlement distortion. It does not cover edge cases like failure modes when cash is insufficient, but with annotations carrying the safety profile this is strong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

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

The prose is front-loaded with purpose and the routing caveats before the Args listing, and the Returns line is brief because an output schema exists. The Args section, however, duplicates the input schema nearly verbatim, which is expendable length even though each individual sentence is well-formed.

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?

For an 8-parameter write tool with an output schema, the description covers everything an agent needs: what it does, what alternatives exist for the two important edge cases, the confirmation prerequisite, the gold special case, and idempotency on retry. Nothing material is left unstated.

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

Parameters3/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 Args block is largely a restatement of the schema's own parameter descriptions (gold ticker/units/currency, idempotency reuse, unit_label default). It adds minor framing value, such as tying `currency` omission to the existing position, but nothing the schema does not already say.

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 opening sentence names a specific verb and resource — 'Record a buy in the local ledger' — and immediately explains both branches (weighted-average add to an existing position, or new position for an unseen symbol). It also states what the tool is not: 'openInvest never places real orders,' which sharply separates it from a real brokerage order path.

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?

It gives explicit routing rules: pre-existing holdings go to `record_existing_position`, off-exchange China mutual funds go to `place_fund_order` + `confirm_fund_order`, and it explains why (buy would book them as instantly filled, distorting totals). It even specifies a pre-call obligation — confirm symbol, units, and price with the user — which is actionable usage guidance, not just context.

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