Skip to main content
Glama

Update project allocations

well_update_project_allocations
Destructive

Set the project split of a journal entry's revenue and expense lines: every selected line carries the same split, and the percents of one line add up to exactly 100.

Use this to allocate revenue or expense to projects (cost centers, campaigns, deals). Name exactly one source the split hangs on:

  • journal_entry_id — the journal entry itself, obtained with well_query_records on the journal_entries view, whose primary key is journal_entry_id, or from the entry the person names. The only source a DRAFT entry accepts.

  • invoice_id — a live invoice of this workspace. Its posted journal entry takes the split. Until it is posted, the split rides the invoice's live items, and the posted entry takes it over when the invoice is posted. Never an invoice item id.

  • transaction_id — a live bank transaction of this workspace. Its posted journal entry takes the split, whether the entry books the transaction directly or through a legacy invoice-transaction link. Never an expense claim without a posted entry.

REQUIRED: exactly one of journal_entry_id, invoice_id, transaction_id; and splits. OPTIONAL: journal_entry_line_ids — only with journal_entry_id; the live lines to split; absent, every live revenue and expense line of the entry takes it. OPTIONAL: selected_journal_entry_id — only with invoice_id or transaction_id when the source posts through several eligible posted entries; the numbered refusal names each candidate with its journal_entry_id, so ask the person which one and call again with this field set. Never invent a journal_entry_id that the refusal did not list.

A transaction source must already be posted (its journal entry VALIDATED or LOCKED, not reversed). An unposted transaction, a reversed one with no current eligible posting, or a source of another workspace refuses with no card and no write. An invoice source with no eligible posting writes on its items; it refuses only when the invoice has no readable side (a draft without issuer, or no confirmed own company). Two eligible postings refuse with the numbered list — never pick one yourself. Read the projects first with well_list_projects.

On a draft entry the split rides the lines until validation; on an already posted entry it writes the allocation rows at once, replacing any split those lines already carry. A second call with the same split writes nothing. A line that is not a live revenue or expense line, or an entry with none of them, is refused and nothing is written. A person confirms the split on a card before anything is written.

Returns { success: true, allocation: { entry_id, lines_changed, rows_written } } on success (entry_id is null when the items of an unposted invoice took the split), or { success: false, error } on failure.

Input Schema

NameRequiredDescriptionDefault
splitsYesThe split every selected line takes: distinct live projects whose percents total exactly 100.
invoice_idNoA live invoice of this workspace, as an alternative source: its posted (VALIDATED or LOCKED, not reversed) journal entry takes the split. Exactly one of journal_entry_id, invoice_id or transaction_id is required.
workspace_idNoTarget workspace. Omit when the token authorizes one workspace. Required when it authorizes several — a write lands in exactly one workspace and this call would not say which.
transaction_idNoA live bank transaction of this workspace, as an alternative source: its posted (VALIDATED or LOCKED, not reversed) journal entry takes the split, whether the entry books the transaction directly or through a legacy invoice-transaction link. Exactly one of journal_entry_id, invoice_id or transaction_id is required.
conversation_idNoThe conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.
idempotency_keyNoOptional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation.
workspace_scopeNoRestrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.
journal_entry_idNoThe journal entry whose lines take the split; the only source a draft entry accepts. Exactly one of journal_entry_id, invoice_id or transaction_id is required.
journal_entry_line_idsNoOnly with journal_entry_id: the live journal entry lines to split; absent, every live revenue and expense line of the entry takes it.
selected_journal_entry_idNoOnly with invoice_id or transaction_id: the journal entry to link when the source posts through several eligible entries; one of the entries the source resolved to, revalidated under the write lock.

Output Schema

NameRequiredDescriptionDefault
codeNo
errorNo
successYes
allocationNo
reply_linesNo
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
near_candidatesNo
newly_connectedNoTools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.
near_candidates_truncatedNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • removedOutput schema / properties / allocation / properties / entry_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / allocation / properties / entry_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • addedOutput schema / properties / code
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / near_candidates
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "company_id": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "company_id",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / near_candidates_truncated
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / reply_lines
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  2. Changed2 schema fields changed
    • addedOutput schema / properties / allocation / properties / entry_id / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / allocation / properties / entry_id / type
      Removed value: -"string"
  3. Changed6 schema fields changed
    • addedInput schema / properties / invoice_id
      Added value: +{
      +  "description": "A live invoice of this workspace, as an alternative source: its posted (VALIDATED or LOCKED, not reversed) journal entry takes the split. Exactly one of journal_entry_id, invoice_id or transaction_id is required.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • changedInput schema / properties / journal_entry_id / description
      Previous value: -"The journal entry whose lines take the split."New value: +"The journal entry whose lines take the split; the only source a draft entry accepts. Exactly one of journal_entry_id, invoice_id or transaction_id is required."
    • changedInput schema / properties / journal_entry_line_ids / description
      Previous value: -"The live journal entry lines to split; absent, every live revenue and expense line of the entry takes it."New value: +"Only with journal_entry_id: the live journal entry lines to split; absent, every live revenue and expense line of the entry takes it."
    • addedInput schema / properties / selected_journal_entry_id
      Added value: +{
      +  "description": "Only with invoice_id or transaction_id: the journal entry to link when the source posts through several eligible entries; one of the entries the source resolved to, revalidated under the write lock.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / transaction_id
      Added value: +{
      +  "description": "A live bank transaction of this workspace, as an alternative source: its posted (VALIDATED or LOCKED, not reversed) journal entry takes the split, whether the entry books the transaction directly or through a legacy invoice-transaction link. Exactly one of journal_entry_id, invoice_id or transaction_id is required.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "journal_entry_id",
      -  "splits"
      -]New value: +[
      +  "splits"
      +]
  4. Added

TDQS

A4.9/5.0
Behavior5/5

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

Annotations declare a destructive, non-read-only write, and the description goes well beyond them: it discloses replacement of existing splits, idempotency on repeat calls, draft-vs-posted write timing, reversal/posting requirements, workspace refusal behavior, the confirmation card before writing, and nothing-is-written failure semantics. This is exactly the extra context the destructiveHint alone cannot convey.

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?

Front-loaded with the core rule, then structured into per-source bullets and REQUIRED/OPTIONAL blocks, so an agent can scan to the decision it needs. Length is justified by the branching source logic, and every sentence carries operational information.

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?

Covers the full decision surface for a 10-parameter destructive write with three alternative anchors: source eligibility, selection, refusal handling, replacement/idempotency behavior, and workspace scoping implications. Return values are restated briefly but an output schema also exists, so nothing an agent needs is missing.

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 coverage is 100%, so the baseline is 3; the description still adds real meaning by tying the exactly-one-of constraint to source semantics, restricting journal_entry_line_ids to journal_entry_id and selected_journal_entry_id to the refusal's numbered candidate list ("Never invent a journal_entry_id that the refusal did not list"). Minor overlap with the already-verbose schema descriptions keeps it from a 5.

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?

States a concrete verb+resource+scope ("Set the project split of a journal entry's revenue and expense lines") and adds the invariant that the percents of a line total exactly 100. It is clearly distinguishable from nearby siblings such as well_update_project, well_update_journal_entry, and well_update_project_budget.

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?

Explicitly says when to use it ("Use this to allocate revenue or expense to projects") and enumerates the three mutually exclusive source anchors with the conditions that select each, including which sources are invalid (invoice item ids, expense claims without a posted entry). It also gives a prerequisite ("Read the projects first with well_list_projects") and a recovery path when the call refuses.

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.

Resources