Skip to main content
Glama

heal

Restore HP to an adjacent damaged allied unit using a healer unit. The healer must be READY or MOVED and becomes DONE after healing. Healing amount scales with the healer's magic stat. Returns amount healed and target's updated HP.

Instructions

Mutating. Heal an adjacent allied unit. Only units with the heal ability (typically Mages) can use this. healer_id is your healing unit (must be READY or MOVED); target_id is an adjacent allied unit that is damaged. Restores HP based on the healer's magic stat. After healing, the healer's status becomes DONE for this turn. Use get_legal_actions on the healer to see which allies are valid heal targets. Returns the amount healed and the target's updated HP.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
connection_idYes
healer_idYes
target_idYes

Implementation Reference

  • The `heal` tool handler function. Validates session/ownership, applies HealAction via engine rules, enriches errors, returns result with healer_status.
    def heal(session: Session, viewer: Team, healer_id: str, target_id: str) -> dict:
        _require_active(session, viewer)
        _require_own_unit(session.state, healer_id, viewer)
        try:
            result = apply(session.state, HealAction(healer_id=healer_id, target_id=target_id))
        except IllegalAction as e:
            raise ToolError(_enrich_heal_error(session.state, healer_id, target_id, e)) from e
        # Healer is DONE after healing. Status hint lets the model skip
        # re-deriving the rule.
        healer_after = session.state.units.get(healer_id)
        result["healer_status"] = (
            healer_after.status.value if healer_after else "killed"
        )
        _record_action(session, result)
        return result
  • Core `_apply_heal` engine rule. Validates can_heal, adjacency, ownership, self-heal, then applies heal amount and sets healer status to DONE.
    def _apply_heal(state: GameState, healer: Unit, target_id: str) -> dict:
        if not healer.stats.can_heal:
            raise IllegalAction(f"{healer.id} cannot heal")
        if healer.status is UnitStatus.DONE:
            raise IllegalAction(f"{healer.id} has already acted this turn")
        target = state.units.get(target_id)
        if target is None or not target.alive:
            raise IllegalAction(f"target {target_id} not found (dead, nonexistent, or hidden by fog)")
        if target.owner is not healer.owner:
            raise IllegalAction("cannot heal enemy unit")
        if target.id == healer.id:
            raise IllegalAction("cannot self-heal")
        if healer.pos.manhattan(target.pos) != 1:
            raise IllegalAction("heal requires adjacent ally")
    
        heal_amt = min(healer.stats.heal_amount, target.stats.hp_max - target.hp)
        target.hp += heal_amt
        healer.status = UnitStatus.DONE
        return {
            "type": "heal",
            "unit_id": healer.id,
            "target_id": target.id,
            "heal_amount": heal_amt,
        }
  • Tool registration entry for 'heal' in TOOL_REGISTRY, mapping to `heal` function with input_schema (healer_id, target_id).
    "heal": {
        "fn": heal,
        "description": "Heal an adjacent ally (Mage only). Unit becomes 'done'.",
        "input_schema": {
            "type": "object",
            "properties": {
                "healer_id": {"type": "string"},
                "target_id": {"type": "string"},
            },
            "required": ["healer_id", "target_id"],
        },
    },
  • HealAction dataclass definition with healer_id and target_id fields.
    class HealAction:
        healer_id: str
        target_id: str
  • `_enrich_heal_error` helper that provides actionable hints on heal failures (no can_heal, not adjacent, enemy target, self-heal).
    def _enrich_heal_error(
        state: GameState, healer_id: str, target_id: str, e: IllegalAction
    ) -> str:
        """Hint on heal failures. The most frequent miss is picking a
        non-adjacent target -- name the adjacent wounded friendlies so the
        agent doesn't burn a get_state + distance calc to recover."""
        msg = str(e)
        healer = state.units.get(healer_id)
        if healer is None:
            return msg
        if "cannot heal" in msg and "enemy" not in msg and "self" not in msg:
            # Class lacks can_heal.
            healers = [
                u.id for u in state.units_of(healer.owner)
                if u.alive and u.stats.can_heal
            ]
            return (
                f"{msg}. Your healers are: "
                f"[{', '.join(healers) or '(none -- no can_heal class fielded)'}]."
            )
        if "requires adjacent ally" in msg:
            adjacent_wounded = [
                u.id for u in state.units_of(healer.owner)
                if u.alive and u.id != healer.id
                and healer.pos.manhattan(u.pos) == 1
                and u.hp < u.stats.hp_max
            ]
            return (
                f"{msg}. Healer {healer_id} at ({healer.pos.x},"
                f"{healer.pos.y}); wounded friendly units adjacent right "
                f"now: [{', '.join(adjacent_wounded) or '(none)'}]."
            )
        if "cannot heal enemy" in msg:
            return (
                f"{msg}. Target {target_id} is on the opposing team. "
                f"Heal targets your own team only."
            )
        if "cannot self-heal" in msg:
            return (
                f"{msg}. Pick a wounded teammate at Manhattan distance 1."
            )
        return msg
Behavior5/5

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

No annotations, but description fully discloses effects: mutating, healer becomes DONE, HP restoration based on magic stat, return values. No contradictions.

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?

Five efficient sentences, front-loaded with 'Mutating.', each sentence adds necessary detail without redundancy.

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?

No output schema, but description mentions return values. References get_legal_actions for target validation. Covers prerequisites and consequences fully.

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?

0% schema coverage; description explains healer_id and target_id conditions thoroughly. connection_id is not explained but likely contextually understood.

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 description clearly states the tool heals an adjacent allied unit, specific to units with heal ability. It distinguishes from attack (damages enemies) and move (repositioning).

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?

Explicit guidance: healer must be READY or MOVED, target must be adjacent and damaged. Recommends get_legal_actions to find valid targets. Lacks explicit when-not-to-use, but context is clear.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/haoyifan/Silicon-Pantheon'

If you have feedback or need assistance with the MCP directory API, please join our Discord server