create_transaction

Creates a new transaction for the authenticated user on one of their accounts.

Description

Creates a new transaction for the authenticated user on one of their accounts.

Required fields: name and amount.
category, accountId, and transactedAt can be omitted for intent-first MCP usage defaults.

⚠️  GOLDEN RULE — NEVER infer, guess, default, or invent ANY required field.
Every required field must come DIRECTLY from what the user said. If the user did not
clearly provide a field, STOP and ask them for it — do not proceed with a substitute.
MCP intent defaults:
  • If category is omitted, infer it from the transaction name and amount (e.g. "wireless headphones" => GENERAL_MERCHANDISE).
  • If transactedAt is omitted, default to today (RFC 3339).
  • If accountId is omitted, default to the account named "Main Checking" when available.
    If "Main Checking" is not available: use the only accessible account when exactly one exists.
    If still ambiguous, ask the user to choose an account.

Edge-case parsing rule for purchases:
  • If the user gives a TOTAL amount plus an item/service (e.g. "spent $300 on headphones" or "bought $300 headphones"),
    treat both as the same intent: a single purchase with that item name and amount -30000 (cents).
  • If quantity is NOT explicitly stated, assume default quantity = 1.
  • Do NOT split total into unit price × quantity unless the user explicitly gives quantity or per-item pricing.

Natural-language name is OK (e.g. name="Log $5 coffee") — amount/name/category are inferred.
A trailing "on <account>" in the name (e.g. "Log $5 coffee on checking") selects that account when it matches one.
Optional accountName resolves the account without an ID; an unknown or ambiguous accountName asks which account.
If an identical name+amount exists on the same account within 24 hours, this asks before doubling up unless confirmDuplicate=true.

Examples of what is NOT allowed:
  • User says "add a coffee transaction" (no amount) → DO NOT guess an amount. Ask: "How much was it?"
  • User says "Log $4.50" (no description) → DO NOT invent a name. Ask: "What was it for?"
  • User says "my account" with multiple accounts → DO NOT pick the default. Call list_accounts and ask which one.

Per-field rules:
  • accountId: the account the USER explicitly chose. Vague reference + multiple accounts → ask.
  • name: a specific label the user gave (e.g. "Coffee", "Rent"). Never a placeholder like "Transaction".
  • amount: the exact amount the user stated, in cents ($4.50 → -450 for an expense). Never 0 and never a guess.
  • category: inferred when omitted; informal names (e.g. "food", "groceries") auto-map to the closest system category (FOOD_AND_DRINK).
  • transactedAt: the date the user gave, as RFC 3339. "today" is fine to resolve to today's date.

RESOLVING MISSING CONTEXT — call the appropriate tool before retrying:
  • accountId unknown → call list_accounts; use account.id.
  • category unclear  → call list_categories; use category.name (only if inference is not suitable).
  • tagIds unknown    → call list_tags; use tag.id values.

Amounts are in cents. Sign convention: negative for expenses, positive for income.
type (INCOME, EXPENSE, TRANSFER) is optional and inferred from amount/category when omitted.
fileIds defaults to [] when omitted.

Input parameters

NameTypeRequiredDescription
accountIdstringNo
accountNamestringNo
amountnumberNo
appleCardTransactionobjectNo
categorystringNo
categoryIdstringNo
confirmDuplicatebooleanNo
cronExpressionstringNo
descriptionstringNo
endDatestringNo
expenseCategorystringNo
fileIdsarrayNo
incomeCategorystringNo
isExcludedFromAnalyticsbooleanNo
lineItemsarrayNo
namestringYes
subcategorystringNo
tagIdsarrayNo
tagNamesarrayNo
transactedAtstringNo
typestringNo
vendorIdstringNo
vendorNamestringNo