Skip to main content
Glama

Build a multi-asset allocation

build_allocation_strategy
Destructive

Build a multi-asset allocation, or rewrite one, and return its weights. Writes.

``strategy_id`` edits that strategy (only one this client owns). An edit replaces
the definition: ``items`` becomes the whole portfolio and omitted caps revert to
unconstrained; ``name`` may be omitted to keep it. Editing one with a track
record rebuilds that history in the background.

``items`` is the portfolio. Each is an instrument (``asset_id``), a strategy
(``strategy_id``, from ``find_portfolios``; its holdings are published first), or
an ``instrument`` of 'broad_equity', 'long_bond' or 'short_bond', resolved to the
client's currency default (see ``get_default_instruments``), so one call works in
any currency and needs no ``asset_class``.

``weight`` pins an item; unpinned items share the rest by risk parity, so a calmer
line weighs more. ``min_weight`` / ``max_weight`` bound an item without
pinning it. With a risk target, a long bond is added if no bond line is listed.

``short_rate_asset_id`` (id from ``find_assets``; default: the currency's) is a
reserve, not a line: held only when the target is below what the lines reach,
and only as much as needed. A short-duration fund listed in ``items`` is a line
instead, and risk parity gives it a large weight because it barely moves.

``risk_level`` targets the 0-10 ladder (anchors 0/1/2/5/8/10, the rest
interpolated); None is static: exactly its pins. ``loss_tolerance`` is a worst month (0.10 = 10%);
with both, the tighter wins.

Caps (None: unconstrained) look through strategy items:
``max_equity_weight`` / ``max_alternative_weight`` total by asset class;
``max_tactical_weight`` totals items tagged ``diversification='narrow'`` (a cap
with no tagged item is rejected); ``max_asset_weight`` / ``max_sector_weight`` /
``max_country_weight`` apply to the underlying equities. These are construction
parameters; no client profile is read.

``history_years`` starts no earlier than the first quarter end after the
youngest strategy item began.

``glide_target_date`` (needs ``risk_level``) glides toward the date the client
names: each rebalance holds the lower of ``risk_level`` and the published horizon
ceiling for the time left (``get_risk_ceiling_for_horizon``), reaching level 2
about a year before the date. ``glide`` is the yearly schedule. A backtest runs
today's level over the whole history.

``signal`` tilts or filters unpinned items at each rebalance on data up to its
observation date; an unscored item counts as average. It carries a client's own
momentum or factor rule; without it, items are sized by risk alone.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "items": "<items>"
    },
    "name": "build_allocation_strategy"
  }
}

Input Schema

NameRequiredDescriptionDefault
nameNo
itemsYes
signalNo
backtestNo
risk_levelNo
strategy_idNo
history_yearsNo
loss_toleranceNo
max_asset_weightNo
glide_target_dateNo
max_equity_weightNo
max_sector_weightNo
max_country_weightNo
max_tactical_weightNo
rebalance_frequencyNoquarterly
short_rate_asset_idNo
max_alternative_weightNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • addedInput schema / $defs / AllocationSignalInput
      Added value: +{
      +  "description": "A client's momentum or factor rule: tilts or filters the unpinned items at each\nrebalance.",
      +  "properties": {
      +    "direction": {
      +      "anyOf": [
      +        {
      +          "$ref": "#/$defs/TiltDirection"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "None: low for valuation, leverage, risk; else high."
      +    },
      +    "keep": {
      +      "anyOf": [
      +        {
      +          "minimum": 1,
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Filter only; the items it holds.",
      +      "title": "Keep"
      +    },
      +    "lookback_months": {
      +      "default": 12,
      +      "description": "Momentum sources only.",
      +      "maximum": 36,
      +      "minimum": 1,
      +      "title": "Lookback Months",
      +      "type": "integer"
      +    },
      +    "mode": {
      +      "$ref": "#/$defs/SignalMode",
      +      "default": "tilt",
      +      "description": "'tilt': risk budget x (1 + strength x z), z the capped cross-item score; 0 drops. 'filter': the `keep` best."
      +    },
      +    "skip_months": {
      +      "default": 1,
      +      "description": "Momentum sources only; the latest months left out.",
      +      "maximum": 3,
      +      "minimum": 0,
      +      "title": "Skip Months",
      +      "type": "integer"
      +    },
      +    "source": {
      +      "$ref": "#/$defs/SignalSource",
      +      "description": "'momentum': own return; 'risk_adjusted_momentum': per unit of volatility; the rest: what the item holds."
      +    },
      +    "strength": {
      +      "anyOf": [
      +        {
      +          "maximum": 5,
      +          "minimum": 0.1,
      +          "type": "number"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "description": "Tilt only; 1 when left out.",
      +      "title": "Strength"
      +    }
      +  },
      +  "required": [
      +    "source"
      +  ],
      +  "title": "AllocationSignalInput",
      +  "type": "object"
      +}
    • addedInput schema / $defs / SignalMode
      Added value: +{
      +  "enum": [
      +    "tilt",
      +    "filter"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / $defs / SignalSource
      Added value: +{
      +  "enum": [
      +    "momentum",
      +    "risk_adjusted_momentum",
      +    "valuation",
      +    "profitability",
      +    "leverage",
      +    "risk",
      +    "quality",
      +    "growth",
      +    "dividend_yield"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / $defs / TiltDirection
      Added value: +{
      +  "enum": [
      +    "low",
      +    "high"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / signal
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/AllocationSignalInput"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
  2. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, and the description earns credit on top by specifying exactly what an edit destroys: ``items`` becomes the whole portfolio, omitted caps revert to unconstrained, and an existing track record is rebuilt in the background. It also discloses client scoping (only strategies this client owns) and that no client profile is read by the construction caps.

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?

Front-loaded with the action and a one-word "Writes." warning, then organized into parameter-keyed paragraphs using consistent ``backtick`` markers. It is long and some sentences are dense (the currency-default paragraph), but for a 17-parameter mutation tool nearly every clause carries decision-relevant information.

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

Completeness4/5

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

Covers the high-risk areas an agent must understand before a destructive write: replace-on-edit semantics, background history rebuild, glide requiring ``risk_level``, and signal scope. With no output schema it says only "return its weights" and never describes the response shape (weights only, or also the glide schedule and backtest handle), which is the main gap for a tool this complex.

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

Parameters5/5

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

With 0% schema description coverage on the top-level properties, the description carries the full burden and does so: pinning via ``weight`` versus risk-parity residual, min/max as bounds without pinning, ``short_rate_asset_id`` as a reserve rather than a line, the 0-10 ``risk_level`` ladder with its anchors, ``loss_tolerance`` as a worst month with tighter-wins precedence, cap look-through behavior, and the ``history_years`` start constraint. Only ``rebalance_frequency`` is left unexplained, and its enum values are self-evident.

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?

Opens with a specific verb and resource -- "Build a multi-asset allocation, or rewrite one, and return its weights" -- and immediately flags that it writes. The multi-asset framing plus the ``strategy_id`` edit path distinguish it from the single-asset build_equity_strategy sibling without needing to name it.

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

Usage Guidelines4/5

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

Gives explicit create-vs-edit routing, and within ``items`` it tells the agent when to prefer ``instrument`` over ``asset_id`` (currency safety), when a short-duration fund is a line versus a reserve, and that a cap with no tagged item is rejected. It falls slightly short of 5 because it never routes to same-purpose siblings such as solve_allocation_weights or assign_strategy; the alternatives it cites (find_portfolios, get_default_instruments, get_risk_ceiling_for_horizon) are id/lookup helpers rather than substitutes.

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