Skip to main content
Glama

ot_cross_river

Select a river crossing method—ford, caulk, ferry, or wait—balancing risk, speed, and cost, then narrate the crossing dramatically.

Instructions

Choose how to cross the current river. Ford=fast but risky. Caulk=float the wagon, medium risk. Ferry=safe but costs $15. Wait=lose 2 days and food but calmer water. Narrate the crossing dramatically.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
methodYesCrossing method

Implementation Reference

  • The actual implementation of the ot_cross_river tool handler. It implements four crossing methods: ford (fast but risky, up to 28% chance of disaster), caulk (float the wagon, medium risk with 22% failure chance), ferry (safe, costs $15), and wait (costs 2 days and food). The handler modifies OtState accordingly and returns a dramatic narrative.
    server.tool(
      "ot_cross_river",
      "Choose how to cross the current river. Ford=fast but risky. Caulk=float the wagon, medium risk. Ferry=safe but costs $15. Wait=lose 2 days and food but calmer water. Narrate the crossing dramatically.",
      {
        method: z.enum(["ford", "caulk", "ferry", "wait"]).describe("Crossing method"),
      },
      async ({ method }) => {
        if (!otGame) return { content: [{ type: "text", text: "No journey in progress." }], isError: true };
        if (!otGame.pendingRiver) return { content: [{ type: "text", text: `You're not at a river crossing.\n\n${renderState(otGame)}` }], isError: true };
    
        const stop = otGame.trailStops[otGame.currentStopIndex];
        let text: string;
    
        if (method === "ford") {
          const roll = Math.random();
          if (roll < 0.28) {
            if (Math.random() < 0.4) otGame.supplies.oxen  = Math.max(1, otGame.supplies.oxen - 1);
            if (Math.random() < 0.5) otGame.supplies.parts = Math.max(0, otGame.supplies.parts - 1);
            otGame.player.health    = clamp(otGame.player.health - 22, 0, 100);
            otGame.companion.health = clamp(otGame.companion.health - 15, 0, 100);
            otGame.supplies.food    = Math.max(0, otGame.supplies.food - 4);
            if (otGame.pet.alive) {
              otGame.pet.health = clamp(otGame.pet.health - 30, 0, 100);
              if (otGame.pet.health <= 0) otGame.pet.alive = false;
            }
            text = `The ford goes badly. The current grabs the wagon and for a terrifying moment everything is chaos — water, shouting, supplies spilling downstream. You make it across, but not without cost.`;
          } else if (roll < 0.55) {
            otGame.player.health = clamp(otGame.player.health - 8, 0, 100);
            otGame.supplies.food = Math.max(0, otGame.supplies.food - 1);
            text = `The ford is rough but survivable. Everyone gets soaked. ${otGame.player.name} takes a knock from a submerged rock. You're across.`;
          } else {
            text = `The ford goes better than expected. You pick a good line through the current. Everyone across, mostly dry.`;
          }
        } else if (method === "caulk") {
          // Caulking always costs something — it's a full day of cold, exhausting work.
          otGame.player.health    = clamp(otGame.player.health    - 8, 0, 100);
          otGame.companion.health = clamp(otGame.companion.health - 8, 0, 100);
          otGame.supplies.food    = Math.max(0, otGame.supplies.food - 1);
          if (Math.random() < 0.22) {
            // Water got into the wagon — something went wrong mid-float.
            otGame.supplies.parts  = Math.max(0, otGame.supplies.parts - 1);
            otGame.supplies.food   = Math.max(0, otGame.supplies.food - 2);
            otGame.player.health   = clamp(otGame.player.health - 10, 0, 100);
            if (otGame.pet.alive) {
              otGame.pet.health = clamp(otGame.pet.health - 15, 0, 100);
              if (otGame.pet.health <= 0) otGame.pet.alive = false;
            }
            text = `The float goes wrong mid-crossing. The wagon lists, water pours in, and for a long terrible minute everything is chaos. You make it across, but the wagon took damage and the supplies got wet. Everyone is shaking.`;
          } else {
            text = `You spend the better part of a day sealing the wagon and coaxing it across. The current is stronger than it looked from the bank. Everyone arrives soaked, cold, and exhausted — but across.`;
          }
        } else if (method === "ferry") {
          if (otGame.supplies.money < 15) return { content: [{ type: "text", text: `The ferryman wants $15. You only have $${otGame.supplies.money}. Find another way.\n\n${renderState(otGame)}` }], isError: true };
          otGame.supplies.money -= 15;
          text = `You pay the ferryman $15 and cross without incident. ${otGame.companion.name} watches the water the entire way. "${stop.name} lives up to its reputation," they say quietly.`;
        } else {
          otGame.day += 2;
          otGame.supplies.food = Math.max(0, otGame.supplies.food - 4);
          text = `You make camp and wait two days for the water to settle. It does, slightly. The crossing is uneventful. The delay stings, but you're across.`;
        }
    
        otGame.pendingRiver = false;
        otGame.status = "traveling";
        log(otGame, `Crossed ${stop.name} by ${method}.`);
    
        return {
          content: [{ type: "text", text: `${text}\n\n${renderState(otGame)}` }],
        };
      }
    );
  • Input schema for ot_cross_river — uses Zod enum for crossing method (ford/caulk/ferry/wait) with a descriptive string explaining each option.
    server.tool(
      "ot_cross_river",
      "Choose how to cross the current river. Ford=fast but risky. Caulk=float the wagon, medium risk. Ferry=safe but costs $15. Wait=lose 2 days and food but calmer water. Narrate the crossing dramatically.",
      {
        method: z.enum(["ford", "caulk", "ferry", "wait"]).describe("Crossing method"),
      },
  • src/index.ts:7-7 (registration)
    Import of registerOregonTrailTools from the oregontrail module.
    import { registerOregonTrailTools } from "./games/oregontrail.js";
  • src/index.ts:19-19 (registration)
    Registration call — registerOregonTrailTools is called with the server instance, which registers all Oregon Trail tools including ot_cross_river.
    registerOregonTrailTools(server);
  • In the renderState helper, when pendingRiver is true it renders a prompt telling the user to call ot_cross_river with one of four methods: ford, caulk, ferry, or wait.
    if (state.pendingRiver) {
      lines.push(`⚠  RIVER CROSSING — choose a method with ot_cross_river before traveling further`);
      lines.push(`   ford (fast, risky)  |  caulk (medium risk)  |  ferry (safe, costs $15)  |  wait (costs food + 2 days)`);
    }
Behavior3/5

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

The description discloses consequences like cost, time, and risk levels, and includes the behavioral note 'Narrate the crossing dramatically.' However, it lacks details on what 'risky' means in terms of failure rates or game state changes, and does not reveal side effects or permissions needed.

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?

The description is extremely concise—only three sentences—and effectively front-loads the purpose. Each sentence adds value: first sets context, second explains options, third adds narrative instruction. No wasted words.

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?

For a simple tool with one parameter and no output schema, the description covers the essential choices and consequences. It could mention that crossing is triggered by the game state or that this is used when a river is encountered, but it is largely complete for the game context.

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?

The schema has one parameter 'method' with enum values but only generic description 'Crossing method.' The description adds critical semantics by explaining each enum value's effect (e.g., 'Ford=fast but risky'), which goes beyond the schema's minimal info.

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's purpose: to choose a river crossing method. It lists each option with specific outcomes (fast/risky, medium risk, safe but costs, lose time/food), making the purpose distinct from sibling tools like ot_travel or ot_buy.

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?

The description provides explicit trade-offs for each method (e.g., ford is fast but risky), guiding the agent on when to use each option. However, it does not explicitly state when not to use the tool or mention alternative tools for crossing.

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/SrmTech-git/MCPArcade'

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