Skip to main content
Glama

sim_bind

Destructive

Record a checked connection between two stored models' declared ports, fromModel's fromPort (a place tagged port.output) feeding toModel's toPort (a transition tagged port.input), as a content-addressed Binding (ROADMAP.md Phase 9/11f). Checked now, by the same binds-port-v1 rule sim_run_pipeline applies: both ports exist with the right direction and element kind, the output is a token place, the input is not a delayed transition, the declared kinds are equal, port.unit agrees exactly where both ends declare one (a unit missing on either end is reported unchecked, never agreed), and a numeric transform is at most 1000000. Differing units bind only with a declared conversion, never inferred from the unit names ("order" and "orders" are two units): pass convertFrom, convertTo and convertFactor together (1 convertFrom = convertFactor convertTo), checked by binds-port-v2 — both ports declare port.unit, the two differ, convertFrom and convertTo are exactly those units, the factor is between 1e-06 and 1000000, and the transform times the factor is at most 1000000; sim_run_pipeline multiplies the resampled rate by the transform and then by the factor. A binding without a conversion is checked by binds-port-v1 exactly as before and keeps its id. A delay (hours, in (0, 10000]) is checked by binds-port-v3 (v2 plus check 12: a finite number in range; 0 is no delay and keeps the binding's id): the target receives the source's flow that many hours later and runs on its own declared rate before then, and a loop between models runs only through a binding that declares one. A self-binding is refused, with or without a delay: a model driving its own input is a loop inside one net, built with sim_extend. Set-level checks (a loop with no delayed binding, two bindings into one input, the schedule-segment cap, a loop over 4 models) belong to sim_run_pipeline and sim_create_system; a binding that closes a loop with bindings already stored is not refused here, since a loop exists only in a set someone runs or defines. A refusal stores nothing. It records binding→fromModel "from", binding→toModel "to" and fromModel→toModel "feeds"; storing the same binding twice returns the same id. A recorded binding passes every run's per-binding check; a run still applies the set-level checks to the set it is given and can stop on what only the run decides (a resampled rate that overflows at a very short horizon, the step budget, the deadline). Costs 1 compute token (it stores a Binding).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
delayNohours after the source's flow that toPort receives it, in (0, 10000]; default unset, no delay. Before the delay ends toPort runs on its own declared rate. A loop between models runs only through a binding with a delay (binds-port-v3)
toPortYeselement id of the declared input port on toModel: a rated transition tagged port.input
toModelYesid of the model receiving the connection
fromPortYeselement id of the declared output port on fromModel: a token place tagged port.output (see GET /api/models/{id}/ports)
convertToNoa declared unit conversion's target unit: exactly toPort's port.unit, which must differ from fromPort's
fromModelYesid of the model supplying the connection's output
transformNohow fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; it scales, never converts a unit. Any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1
convertFromNoa declared unit conversion's source unit: exactly fromPort's port.unit. Pass convertFrom, convertTo and convertFactor together or none of them
convertFactorNohow many convertTo one convertFrom is (1 convertFrom = convertFactor convertTo), between 1e-06 and 1000000; sim_run_pipeline multiplies the resampled rate by it, after any numeric transform

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / delay
      Added value: +{
      +  "description": "hours after the source's flow that toPort receives it, in (0, 10000]; default unset, no delay. Before the delay ends toPort runs on its own declared rate. A loop between models runs only through a binding with a delay (binds-port-v3)",
      +  "type": "number"
      +}
  2. Changed3 schema fields changed
    • addedInput schema / properties / convertFactor
      Added value: +{
      +  "description": "how many convertTo one convertFrom is (1 convertFrom = convertFactor convertTo), between 1e-06 and 1000000; sim_run_pipeline multiplies the resampled rate by it, after any numeric transform",
      +  "type": "number"
      +}
    • addedInput schema / properties / convertFrom
      Added value: +{
      +  "description": "a declared unit conversion's source unit: exactly fromPort's port.unit. Pass convertFrom, convertTo and convertFactor together or none of them",
      +  "type": "string"
      +}
    • addedInput schema / properties / convertTo
      Added value: +{
      +  "description": "a declared unit conversion's target unit: exactly toPort's port.unit, which must differ from fromPort's",
      +  "type": "string"
      +}
  3. Changed3 schema fields changed
    • changedInput schema / properties / fromPort / description
      Previous value: -"element id of the declared output port on fromModel (see GET /api/models/{id}/ports)"New value: +"element id of the declared output port on fromModel: a token place tagged port.output (see GET /api/models/{id}/ports)"
    • changedInput schema / properties / toPort / description
      Previous value: -"element id of the declared input port on toModel"New value: +"element id of the declared input port on toModel: a rated transition tagged port.input"
    • changedInput schema / properties / transform / description
      Previous value: -"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"New value: +"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; it scales, never converts a unit. Any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"
  4. Changed1 schema field changed
    • changedInput schema / properties / transform / description
      Previous value: -"free-text account of how fromPort's value becomes toPort's — a unit scale, a resample window, an aggregation. Not yet interpreted by anything; recorded for whoever builds the pipeline runner"New value: +"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"
  5. First observed

TDQS

A4/5.0
Behavior4/5

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

Without relying on the schema, it discloses cost (1 compute token), refusal semantics ('a refusal stores nothing'), and exactly what edges get stored (binding->fromModel 'from', etc.). It broadly matches the annotations (destructive, not read-only), but 'storing the same binding twice returns the same id' reads as de-facto idempotent while the annotation sets idempotentHint=false, a mild tension rather than a flat contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first clause, but the body is a very dense wall of parenthetical validation clauses, several of which duplicate parameter-schema text (conversion triples, transform semantics, delay range). Much of the volume does not earn its place against the 100%-covered schema.

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?

For a complex 9-parameter mutation tool with no output schema, the description is thorough: validation rules, conversion requirements, delay behavior, what is returned (same id on re-store), refusal behavior, and cost are all covered, so an agent has enough to invoke it correctly.

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

Parameters3/5

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

With schema description coverage at 100%, the schema already documents all nine parameters in detail (delay, transform, convertFactor, etc.). The description largely restates those same rules for unit conversions, transform scaling and delay, adding little syntax or meaning beyond the structured fields.

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 specific verb and resource: it records a checked connection between two models' declared ports as a content-addressed Binding. It also distinguishes scope from siblings by assigning set-level checks to sim_run_pipeline and sim_create_system, and self-loops to sim_extend.

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?

It routes several boundary cases explicitly (set-level checks belong to sim_run_pipeline/sim_create_system; a self-binding is refused and loops inside one net are built with sim_extend), and explains when a refusal occurs. However, it never addresses the obvious alternative sim_link or states a plain 'use this when' condition for the primary record-a-connection case.

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