Skip to main content
Glama

sheet_graph

Indexes every plan-set sheet to classify roles, merge continued schedules, corroborate room numbers with names, and flag non-room tags and revisions so agents can decide what to measure.

Instructions

The plan-set INDEX (#87): every sheet's role (plan / schedule / legend / …, with confidence and the title evidence), the schedule tables found (kind, row count, region — a schedule CONTINUED across sheets ("… SCHEDULE — CONT'D") reads as ONE table, the continuation fragment naming its base in "continues"; rotated column headers are read at their quarter-turn and flagged), every number CORROBORATED as a room (with the stacked room NAME when one exists, the room's BUILDING on multi-building sets, and "corroboration" saying why it counts as a room) plus "unmatched_tags" — the numbers that are NOT rooms (keynote hexagons, detail markers, dimension fragments, legend rows), each with a reason, listed and never dropped; READ those reasons, one of them may be a room the schedule left out, the detail callouts (3/A-601 → sheet edges), the set's building designators, every REVISION marker the set carries (text markers "Δ2"/"REV 2" AND drawn deltas — a bare digit inside a triangle of linework, proven from vector geometry and flagged drawn — in "revisions", and attached to the schedule row / room tag they sit on), and named indexing gaps in "notes". Built once per document from the text layer and cached. This is how an agent decides WHAT to measure without a human enumerating the rooms: list the rooms here, resolve each with resolve_tag, then measure with measure_polygon on its wall faces. A scanned set (no text layer) returns available: false — unavailable, never half-populated. Coordinates are image px at render scale 2.0: PDF pt × 2, origin top-left, y down (the browser canvas's native space). Sheet payloads carry dims in both px and pt.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "sheet_graph"
  }
}

Input Schema

NameRequiredDescriptionDefault

No arguments

Output Schema

NameRequiredDescriptionDefault
notesNoNamed gaps found while indexing (e.g. a continuation whose rows could not be aligned) — the graph refuses silently dropping anything
roomsYesNumbers CORROBORATED as rooms — a room-finish row answers for them, or (where the set carries no room-finish schedule) a room name is drawn with them. Each says which in `corroboration`. Schedule sheets contribute rows, never phantom rooms
countsYes
sheetsYes
calloutsYesDetail callouts (3/A-601) — edges to their target sheets
availableYesfalse = the set has no text layer (a scan) — the graph degrades to unavailable, never half-populates
buildingsNoEvery building designator the set names (sorted) — present only on multi-building-aware sets. Room numbers reused across these need qualified tags ('A-134')
revisionsNoEvery delta-triangle / REV-tag marker the set carries — text markers ('Δ2', 'REV 2') and DRAWN deltas (a bare digit inside a triangle of linework, drawn: true) — where one sits, the ink changed under that revision. Markers on a schedule row or room bubble also attach there (and ride resolve_tag). A revision CLOUD is arc-chain linework these detectors do not read — absence here is not absence of revisions
unmatched_tagsNoNumbered tags on plan sheets that are NOT counted as rooms — keynote hexagons, detail markers, dimension fragments, legend rows. Listed with a reason, never dropped. A real finish plan is covered in 2–3 digit numbers that are not rooms; counting them as rooms makes every one come back "no schedule row", which reads exactly like the lost-bid case and buries it

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed41 schema fields changedv0.1.31
    • removedOutput schema / properties / callouts / items / properties / bbox / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence/properties/bbox"
    • addedOutput schema / properties / callouts / items / properties / bbox / additionalProperties
      Added value: +false
    • addedOutput schema / properties / callouts / items / properties / bbox / properties
      Added value: +{
      +  "x0": {
      +    "type": "number"
      +  },
      +  "x1": {
      +    "type": "number"
      +  },
      +  "y0": {
      +    "type": "number"
      +  },
      +  "y1": {
      +    "type": "number"
      +  }
      +}
    • addedOutput schema / properties / callouts / items / properties / bbox / required
      Added value: +[
      +  "x0",
      +  "y0",
      +  "x1",
      +  "y1"
      +]
    • addedOutput schema / properties / callouts / items / properties / bbox / type
      Added value: +"object"
    • addedOutput schema / properties / counts / properties / callouts / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / counts / properties / callouts / minimum
      Added value: +-9007199254740991
    • addedOutput schema / properties / counts / properties / rooms / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / counts / properties / rooms / minimum
      Added value: +-9007199254740991
    • addedOutput schema / properties / counts / properties / schedules / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / counts / properties / schedules / minimum
      Added value: +-9007199254740991
    • addedOutput schema / properties / counts / properties / unmatched_tags / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / counts / properties / unmatched_tags / minimum
      Added value: +-9007199254740991
    • removedOutput schema / properties / revisions / items / properties / bbox / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence/properties/bbox"
    • addedOutput schema / properties / revisions / items / properties / bbox / additionalProperties
      Added value: +false
    • addedOutput schema / properties / revisions / items / properties / bbox / properties
      Added value: +{
      +  "x0": {
      +    "type": "number"
      +  },
      +  "x1": {
      +    "type": "number"
      +  },
      +  "y0": {
      +    "type": "number"
      +  },
      +  "y1": {
      +    "type": "number"
      +  }
      +}
    • addedOutput schema / properties / revisions / items / properties / bbox / required
      Added value: +[
      +  "x0",
      +  "y0",
      +  "x1",
      +  "y1"
      +]
    • addedOutput schema / properties / revisions / items / properties / bbox / type
      Added value: +"object"
    • removedOutput schema / properties / rooms / items / properties / bbox / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence/properties/bbox"
    • addedOutput schema / properties / rooms / items / properties / bbox / additionalProperties
      Added value: +false
    • addedOutput schema / properties / rooms / items / properties / bbox / properties
      Added value: +{
      +  "x0": {
      +    "type": "number"
      +  },
      +  "x1": {
      +    "type": "number"
      +  },
      +  "y0": {
      +    "type": "number"
      +  },
      +  "y1": {
      +    "type": "number"
      +  }
      +}
    • addedOutput schema / properties / rooms / items / properties / bbox / required
      Added value: +[
      +  "x0",
      +  "y0",
      +  "x1",
      +  "y1"
      +]
    • addedOutput schema / properties / rooms / items / properties / bbox / type
      Added value: +"object"
    • removedOutput schema / properties / rooms / items / properties / revision / properties / source / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence"
    • addedOutput schema / properties / rooms / items / properties / revision / properties / source / additionalProperties
      Added value: +false
    • addedOutput schema / properties / rooms / items / properties / revision / properties / source / description
      Added value: +"An evidence pointer — the sheet, the literal text, and where it sits (image px). Every edge in the graph carries one; pass the bbox to view_sheet to LOOK at the source."
    • addedOutput schema / properties / rooms / items / properties / revision / properties / source / properties
      Added value: +{
      +  "bbox": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "x0": {
      +        "type": "number"
      +      },
      +      "x1": {
      +        "type": "number"
      +      },
      +      "y0": {
      +        "type": "number"
      +      },
      +      "y1": {
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "x0",
      +      "y0",
      +      "x1",
      +      "y1"
      +    ],
      +    "type": "object"
      +  },
      +  "sheet": {
      +    "type": "string"
      +  },
      +  "text": {
      +    "type": "string"
      +  }
      +}
    • addedOutput schema / properties / rooms / items / properties / revision / properties / source / required
      Added value: +[
      +  "sheet",
      +  "text",
      +  "bbox"
      +]
    • addedOutput schema / properties / rooms / items / properties / revision / properties / source / type
      Added value: +"object"
    • removedOutput schema / properties / sheets / items / properties / schedules / items / properties / region / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence/properties/bbox"
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / region / additionalProperties
      Added value: +false
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / region / properties
      Added value: +{
      +  "x0": {
      +    "type": "number"
      +  },
      +  "x1": {
      +    "type": "number"
      +  },
      +  "y0": {
      +    "type": "number"
      +  },
      +  "y1": {
      +    "type": "number"
      +  }
      +}
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / region / required
      Added value: +[
      +  "x0",
      +  "y0",
      +  "x1",
      +  "y1"
      +]
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / region / type
      Added value: +"object"
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / rows / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / rows / minimum
      Added value: +-9007199254740991
    • removedOutput schema / properties / unmatched_tags / items / properties / bbox / $ref
      Removed value: -"#/properties/sheets/items/properties/evidence/properties/bbox"
    • addedOutput schema / properties / unmatched_tags / items / properties / bbox / additionalProperties
      Added value: +false
    • addedOutput schema / properties / unmatched_tags / items / properties / bbox / properties
      Added value: +{
      +  "x0": {
      +    "type": "number"
      +  },
      +  "x1": {
      +    "type": "number"
      +  },
      +  "y0": {
      +    "type": "number"
      +  },
      +  "y1": {
      +    "type": "number"
      +  }
      +}
    • addedOutput schema / properties / unmatched_tags / items / properties / bbox / required
      Added value: +[
      +  "x0",
      +  "y0",
      +  "x1",
      +  "y1"
      +]
    • addedOutput schema / properties / unmatched_tags / items / properties / bbox / type
      Added value: +"object"
  2. Changed6 schema fields changedv0.1.18
    • addedOutput schema / properties / counts / properties / unmatched_tags
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / revisions
      Added value: +{
      +  "description": "Every delta-triangle / REV-tag marker the set carries — text markers ('Δ2', 'REV 2') and DRAWN deltas (a bare digit inside a triangle of linework, drawn: true) — where one sits, the ink changed under that revision. Markers on a schedule row or room bubble also attach there (and ride resolve_tag). A revision CLOUD is arc-chain linework these detectors do not read — absence here is not absence of revisions",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "bbox": {
      +        "$ref": "#/properties/sheets/items/properties/evidence/properties/bbox"
      +      },
      +      "drawn": {
      +        "type": "boolean"
      +      },
      +      "rev": {
      +        "type": "string"
      +      },
      +      "sheet": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "rev",
      +      "sheet",
      +      "bbox"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / rooms / description
      Previous value: -"Room tags read off plan-role sheets — schedule sheets contribute rows, never phantom rooms"New value: +"Numbers CORROBORATED as rooms — a room-finish row answers for them, or (where the set carries no room-finish schedule) a room name is drawn with them. Each says which in `corroboration`. Schedule sheets contribute rows, never phantom rooms"
    • addedOutput schema / properties / rooms / items / properties / corroboration
      Added value: +{
      +  "description": "Why this number is believed to be a room: \"schedule\" (a room-finish row answers for it), \"name\" (a name is drawn with it and the set has no room-finish schedule), or \"name+schedule\"",
      +  "type": "string"
      +}
    • addedOutput schema / properties / rooms / items / properties / revision
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "A revision marker (delta triangle / 'REV 2' tag) attached to this item: the ink CHANGED under that revision. The value read is the post-revision answer — view_sheet the marker's bbox and check the addendum before pricing",
      +  "properties": {
      +    "drawn": {
      +      "description": "true = a DRAWN delta: a bare digit inside a triangle of linework (the common CAD convention — the text layer carries only the digit; the geometry proved the triangle). The evidence bbox spans digit and triangle",
      +      "type": "boolean"
      +    },
      +    "rev": {
      +      "type": "string"
      +    },
      +    "source": {
      +      "$ref": "#/properties/sheets/items/properties/evidence"
      +    }
      +  },
      +  "required": [
      +    "rev",
      +    "source"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / unmatched_tags
      Added value: +{
      +  "description": "Numbered tags on plan sheets that are NOT counted as rooms — keynote hexagons, detail markers, dimension fragments, legend rows. Listed with a reason, never dropped. A real finish plan is covered in 2–3 digit numbers that are not rooms; counting them as rooms makes every one come back \"no schedule row\", which reads exactly like the lost-bid case and buries it",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "bbox": {
      +        "$ref": "#/properties/sheets/items/properties/evidence/properties/bbox"
      +      },
      +      "building": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "description": "Text drawn with the number, when there is any — on a keynote legend this is the accessory description, not a room name",
      +        "type": "string"
      +      },
      +      "reason": {
      +        "description": "WHY this number is not counted as a room. Read these: one of them may be a room the schedule left out, which is a hole in the bid",
      +        "type": "string"
      +      },
      +      "sheet": {
      +        "type": "string"
      +      },
      +      "tag": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "tag",
      +      "sheet",
      +      "bbox",
      +      "reason"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  3. Changed7 schema fields changedv0.1.12
    • addedOutput schema / properties / buildings
      Added value: +{
      +  "description": "Every building designator the set names (sorted) — present only on multi-building-aware sets. Room numbers reused across these need qualified tags ('A-134')",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / counts / properties / schedules / description
      Added value: +"LOGICAL tables — a schedule continued across sheets counts once"
    • addedOutput schema / properties / notes
      Added value: +{
      +  "description": "Named gaps found while indexing (e.g. a continuation whose rows could not be aligned) — the graph refuses silently dropping anything",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / rooms / items / properties / building
      Added value: +{
      +  "description": "The building the room belongs to, when the set names one — its plan sheet's BUILDING/BLDG context, or the tag's own qualifier ('A-134')",
      +  "type": "string"
      +}
    • addedOutput schema / properties / sheets / items / properties / building
      Added value: +{
      +  "description": "The sheet's building context, when it names exactly one (BUILDING A / BLDG 2)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / continues
      Added value: +{
      +  "description": "Present on a continuation fragment ('… SCHEDULE — CONT'D'): the sheet carrying the table's base fragment. The fragments read as ONE table — resolve_tag and find_schedule already see the union",
      +  "type": "string"
      +}
    • addedOutput schema / properties / sheets / items / properties / schedules / items / properties / rotated_headers
      Added value: +{
      +  "description": "true when the column headers were read at a quarter-turn",
      +  "type": "boolean"
      +}
  4. Addedv0.1.9

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses caching ("built once per document from the text layer and cached"), the failure mode for scanned sets ("available: false — unavailable, never half-populated"), the source of truth (text layer, vector geometry for drawn deltas), and the exact coordinate space (image px at render scale 2.0, PDF pt × 2, top-left origin, y down).

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

Conciseness3/5

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

The lead ("The plan-set INDEX") is front-loaded and the content largely earns its place, but it is delivered as one enormous run-on sentence with nested parentheticals, ALL-CAPS emphasis, and quoted field names. Splitting into a purpose sentence, a payload sentence, and a behavior/coordinates sentence would preserve every fact while making it scannable.

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 cached, zero-parameter, complex indexing tool with an output schema, the description covers purpose, failure mode, coordinate conventions, and downstream workflow — everything an agent needs to decide whether and how to call it. It arguably over-explains return fields the output schema already carries, but nothing required 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?

The tool takes zero parameters, so the baseline of 4 applies; there is no parameter meaning for the description to add or omit.

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 plan-set INDEX (#87)" plus an exhaustive enumeration of the payload (sheet roles with confidence, schedule tables with continuation handling, corroborated room numbers, unmatched_tags, detail callouts, revisions, notes) leaves no doubt what the tool returns. It also implicitly separates itself from siblings by naming resolve_tag and measure_polygon as the downstream tools rather than duplicating their jobs.

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 a concrete workflow: "list the rooms here, resolve each with resolve_tag, then measure with measure_polygon" and states the agent's decision point (deciding WHAT to measure without human enumeration). It does not explicitly contrast with the closest overlapping siblings (sheet_context, find_schedule, read_sheet_text), which is the only missing piece.

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