post_finance_transfers

Changes data · you confirm first

Calls POST /api/finance/transfers as the signed-in person · REST reference

Move PFF's money between its two Stripe accounts (platform staff)

OPERATIONS_TO_POOL — operations covering the voucher pool — posts the fund at once (OPERATING → VOUCHER_POOL, COMPLETED) and settles its cash by withholding: what operations owes the pool is kept on the platform out of the next operations-share transfers, never below zero, until settled; no Stripe call is made. POOL_TO_OPERATIONS — the pool repaying operations — opens an outbox row with no ledger line, makes a Stripe transfer to the operations account, and records it: SENT moves VOUCHER_POOL → OPERATING and completes the row; FAILED books nothing. Answers the row as recorded, a failure included — Stripe's reason is on lastError, not an error status. A transfer to operations is refused above the platform balance's available cents, before anything is written. Every documented write is an MCP tool, so this also runs over MCP with the person's confirmation.

Arguments

ArgumentTypeDescription
bodyJSONobjectrequiredThe request body, as a JSON object. Its fields are listed below.

Fields of body

FieldTypeDescription
amountintegerrequiredCENTS to move.
direction"OPERATIONS_TO_POOL" | "POOL_TO_OPERATIONS"requiredWhich way an internal transfer moves PFF's money, and the fund with it. OPERATIONS_TO_POOL: operations covers the voucher pool — cash from the operations connected account to the platform balance, OPERATING to VOUCHER_POOL. POOL_TO_OPERATIONS: the pool repays operations, the reverse of both.
memostringrequiredWhy the money moves; kept on the transaction.

Example call

A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "post_finance_transfers",
    "arguments": {
      "body": {
        "amount": 1,
        "direction": "OPERATIONS_TO_POOL",
        "memo": "string"
      }
    }
  }
}
Confirmation
The client shows the person the exact request and waits. Nothing runs until they tick Make this change. See Reading and changing.

Result

On success (HTTP 201) the tool returns one text item holding the API's JSON, pretty-printed.

The transfer, as recorded after the Stripe call

json
{
  "amount": 1,
  "attempts": 1,
  "cashSettlement": "STRIPE_TRANSFER",
  "completedAt": 1,
  "createdAt": 1,
  "createdBy": "11111111-1111-4111-8111-111111111111",
  "currency": "string",
  "destinationAccount": "STRIPE_PLATFORM",
  "direction": "OPERATIONS_TO_POOL",
  "id": "11111111-1111-4111-8111-111111111111",
  "lastError": "string",
  "memo": "string",
  "settledAmount": 1,
  "sourceAccount": "STRIPE_PLATFORM"
}

Fields

FieldTypeDescription
amountintegerCENTS moved.
attemptsintegerFailed attempts recorded.
cashSettlement"STRIPE_TRANSFER" | "WITHHOLDING"How the cash settles. STRIPE_TRANSFER (the pool repaying operations): a Stripe transfer, SENT or FAILED. WITHHOLDING (operations covering the pool): the fund posted at once and the cash is kept on the platform out of later operations-share transfers until settled.
completedAtinteger | nullEpoch milliseconds the transfer was recorded SENT.
createdAtintegerEpoch milliseconds.
createdBystring (uuid) | nullThe platform staff member who asked for it.
currencystring
destinationAccount"STRIPE_PLATFORM" | "STRIPE_OPERATIONS"The Stripe balance the cash reached.
direction"OPERATIONS_TO_POOL" | "POOL_TO_OPERATIONS"Which way an internal transfer moves PFF's money, and the fund with it. OPERATIONS_TO_POOL: operations covers the voucher pool — cash from the operations connected account to the platform balance, OPERATING to VOUCHER_POOL. POOL_TO_OPERATIONS: the pool repays operations, the reverse of both.
idstring (uuid)The INTERNAL_TRANSFER Transaction's id.
lastErrorstring | nullStripe's refusal, when the transfer failed.
memostringWhy the money moved, as the operator wrote it.
settledAmountintegerWITHHOLDING only — CENTS of later operations shares kept on the platform against this transfer so far.
sourceAccount"STRIPE_PLATFORM" | "STRIPE_OPERATIONS"The Stripe balance the cash left.
status"PENDING" | "COMPLETED" | "FAILED" | "REVERSED" | "CANCELLED" | "PROCESSING" | … (7 values)PENDING until Stripe answers, COMPLETED once SENT, FAILED when Stripe refused.
stripeTransferIdstring | nullThe Stripe transfer (tr_…) that moved the cash; null until one is recorded.
transferState"PENDING" | "SENT" | "FAILED" | "NOT_REQUIRED"The Stripe transfer's outbox state; NOT_REQUIRED never applies here.

When it fails

A failed call returns isError: true with the API's message as text. A change the person declines, or lets time out, also comes back this way and nothing changes.

400

The request was malformed or failed a guard.

403

Authenticated, but the caller holds none of the required permissions.

409

The platform Stripe balance does not cover a transfer to operations (INSUFFICIENT_STRIPE_BALANCE)

What the model is shown

This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.

json
{
  "name": "post_finance_transfers",
  "description": "POST /api/finance/transfers — OPERATIONS_TO_POOL — operations covering the voucher pool — posts the fund at once (OPERATING → VOUCHER_POOL, COMPLETED) and settles its cash by withholding: what operations owes the pool is kept on the platform out of the next operations-share transfers, never below zero, until settled; no Stripe call is made. POOL_TO_OPERATIONS — the pool repaying operations — opens an outbox row with no ledger line, makes a Stripe transfer to the operations account, and records it: SENT moves VOUCHER_POOL → OPERATING and completes the row; FAILED books nothing. Answers the row as recorded, a failure included — Stripe's reason is on `lastError`, not an error status. A transfer to operations is refused above the platform balance's available cents, before anything is written. Every documented write is an MCP tool, so this also runs over MCP with the person's confirmation.\n\nThis changes data. The person is asked to confirm it before it runs, and nothing happens if they decline.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "body": {
        "type": "string",
        "description": "The JSON request body: { amount*: integer (CENTS to move.); direction*: one of \"OPERATIONS_TO_POOL\" | \"POOL_TO_OPERATIONS\" (Which way an internal transfer moves PFF's money, and the fund with it.); memo*: string (Why the money moves; kept on the transaction.) }"
      }
    },
    "required": [
      "body"
    ]
  },
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": true,
    "idempotentHint": false,
    "openWorldHint": false
  }
}