Skip to main content
Glama

Simple House Planner

Edit plan

edit_project

Changes a plan with a short script of plan operations, which the person's open editors show at once. Returns the IDs that changed, the warnings and a description of every floor. A change is never final: undo_change takes it back and restores what it removed, for the last 50 changes.

JavaScript that changes the plan through the global object plan, run as one transaction: when any call fails, nothing changes and the error names the line. return a value to see it in the result. There is no network, clock or randomness.

plan.brief() → the answers the person gave when starting the project, or null: {floors, bedrooms, bathrooms, area (living area in m²), kitchen (open or separate), office, roof, plot ([width along the street, depth] in mm), street (the compass side the street runs along), site (flat, slope or water), slope (percent), downhill (the compass side the ground falls toward, where water lies), patio, pool, beds, fence, parking (garage or carport, when they want one), basement, roofTerrace, notes (wishes in their own words)} plan.floors() → [{floor, name, height}] plan.elements(floor) → elements in the file shape plan.get(id) → the element in the file shape, with its floor plan.describe(floor) → rooms with areas and sizes, what each door connects, window directions, routes and warnings plan.warnings() → warnings on every floor plan.check(rules) → [{floor, ids, message}]: the plan checked against a rule set beyond the layout warnings, each warning naming its part of the rules: "din18040-2" (DIN 18040-2, barrier-free dwellings without the wheelchair requirements: door widths and heights without thresholds, bathroom doors that open outward, hallways 1200 wide, 1200 × 1200 free in every room and in front of toilets, basins and showers, 1200 in front of kitchen fittings and 900 in front of cupboards, 1200 along one long side of a bed and 900 along the other, level showers 1200 × 1200, a window sill of 600 or lower in living rooms and bedrooms, straight stairs with handrails on both sides) or "irc2021" (IRC 2021 in part: room areas, widths and ceiling heights, glazing, emergency escape openings from sleeping rooms, the egress door, hallway widths, stair widths, risers, treads, headroom and handrails, spiral stairs, and guards). Rooms are known by their names, such as bedroom, bathroom, kitchen and hall plan.search(words) → catalog items {item, name, category, width, length, height} plan.addFloor(name, height?) → the new top floor's index plan.setFloor(floor, {name?, height?}) plan.wall(floor, from, to, {thickness?, height?, material?, curve?}) → wall id; curve bends the wall into an arc whose middle lies that far from the straight line, to the left of from → to (negative bends it right), at most the wall's length. material Glass makes a wall of glass in a slim metal frame with a mullion at least every 3000, for meeting rooms and offices or a glazed facade plan.walls(floor, points, {closed?, thickness?, height?, material?, curve?}) → wall ids, joined at every corner; curve bends every wall alike plan.circle(floor, center, radius, {thickness?, height?, material?}) → wall ids: four curved walls that close a round room or tower, radius to their centerline; doors and windows fit on them like on straight walls plan.room(floor, name, min, max, {thickness?, floorFinish?, floorColor?, wallFinish?, wallColor?, storeys?}) → {room, walls}: a room of its own with four walls around the inside corners min and max plan.marker(floor, name, at, {floorFinish?, floorColor?, wallFinish?, wallColor?, storeys?}) → room id: names the walled area around at. storeys (1) makes a room two or more storeys high, such as a great room or an entrance hall open to the floor above: the floors above leave its area open as a void, so give the floor above walls or a railing along the void's edge plan.door(wall, offset, {kind?, width?, height?, elevation?, hingeAtEnd?, opensOutward?, head?, open?}) → door id; offset is from the wall's from point to the door's center. kind is standard, glass (a glass leaf in a metal frame, as for a meeting room in a glass partition, where a standard door also has a glass leaf), sliding, pocket, barn, bifold, garage (a sectional garage door, 2500 wide) or open. open is how far a standard or glass door's leaf stands open, up to 180 degrees, or a bifold door's panels fold, up to 90, and how far a sliding, pocket or barn door slides open or a garage door rolls up, in percent of its travel up to 100, as the 3D view and renders show it. head is flat (the default), round, segment or pointed for an arched top, whose crown is at the height; on a curved wall the door follows the curve. plan.set(id, {frameColor}) colors its frame, lining and casings in a #rrggbb color, as for black steel doors plan.window(wall, offset, {kind?, width?, height?, elevation?, hingeAtEnd?, opensOutward?, head?, open?}) → window id; elevation is the sill height, head an arched top as for a door, and open how far its sashes stand open, up to 90 degrees. plan.set(id, {frameColor}) colors its frame and sashes in a #rrggbb color, as for black steel windows plan.furniture(floor, item, at, rotation?) → id; rotation in degrees counterclockwise, and at 0 the item's back, or a bed's head, faces +y. An item that hangs under the ceiling, such as a ceiling lamp or an AC cassette, starts there, and one that hangs on a wall at its usual height; plan.set(id, {elevation}) moves it up or down. A car shows a detailed 3D model in its paint, and plan.set(id, {paint}) repaints it in a #rrggbb color. plan.set(id, {finishes}) dresses the stuffs of a catalog item's model: wood, fabric (upholstery), linen (bedding and cushions), ceramic, metal and rug, each as {finish?, color?}: a finish, which color tints when it is tinted, or a plain #rrggbb color, such as {wood: {finish: 'black-marble'}, fabric: {finish: 'leather', color: '#5b3a29'}}. Lamps light the 3D view at sunset and at night: downlights, spotlights, track lights, LED panels, cove and under-cabinet strips, chandeliers, pendants and sconces (search lighting), and wall lanterns, up and down wall lights, step lights, bollards, path lights, garden spotlights, in-ground uplights, pool lights, string lights and lantern posts (search outdoor lighting). A wall light's back goes against the wall, a garden spotlight shines up and a little toward its back, and a pool light goes inside a pool, where it stands on the bottom and makes the water glow plan.against(wall, offset, item, room) → id: the item's back, or a bed's head, against the wall's face inside the room plan.stair(floor, from, to, width?) or (floor, points, {width?, style?, railing?, elevation?, height?, treads?, stringers?, beam?, balustrade?}) → id, or the ids of its flights: a stair that climbs from from to to, or flights that climb through the points in order and meet at a landing as deep as the stair is wide at each point between them, in line for a long stair broken by a landing or at a turn for an L or U stair. plan.set(id, {curve}) bends a flight into an arc whose middle lies that far to the left of from → to (negative bends it right), as a wall's curve, with winder treads that narrow toward the inside; a curved flight runs on into the flights joined to its ends without a landing where they meet in line, so a quarter-circle flight between two straight ones turns a corner on winders, and one curved flight makes a sweeping curved stair. style is solid, stringers, floating or spine, and railing left, right or both; the railings run on round the landings. A stair climbs from the floor (elevation 0) to the floor above (height, the floor's height + 200) unless elevation and height say otherwise: a half-floor stair to a terrace or deck ends at its top, and one down to a jetty starts below the floor at a negative elevation. Where a stair arrives at a platform's edge, the platform's railing leaves a gap for it. Its parts each take a material, Wood (oak), Steel, Glass, Concrete or Stone (travertine), and sizes in millimeters: treads {material, thickness} (50 on stringers, 80 floating, 60 on a beam; a solid stair's treads are its body, without a thickness), stringers {material, width, depth} (50 × 280, on stringers only), beam {material, width, depth} (160 × 220, on a center beam only) and balustrade {material, height} (the handrail's top above the treads' noses, 900; with a railing only): a balustrade of Steel or Wood is a handrail on balusters, of Glass a handrail on glass panes, and of Concrete or Stone a solid wall; all are Wood but the Steel balustrade unless given, such as {treads: {material: Glass, thickness: 40}, stringers: {material: Steel, width: 15, depth: 300}, balustrade: {material: Glass}}. plan.set gives a flight these fields too plan.spiral(floor, at, diameter?) → id: a spiral stair centered at at that climbs to the floor above in one counterclockwise turn from its -y side; plan.set changes its turn in degrees, clockwise, steps, rotation, railing (outer), elevation to start above the floor, its style, column (wedge treads on the center column), solid (solid steps stacked round the column) or stringers (treads between two stringers that wind up along its inner and outer edges), and its parts as plan.stair's: treads {material, thickness} (60; none when solid), column {material, diameter} (Steel, 120), where the treads start, stringers {material, width, depth} (Steel, 20 × 300) and balustrade {material, height} plan.builtIn(floor, style, from, to, {depth?, height?, elevation?}) → id: a built-in centered on the line from from to to; style is counter, upper (wall cabinets), tall (tall cabinets such as a pantry), closet (a built-in wardrobe), shelves, bench or desk, and each has its own depth, height and elevation unless given. plan.set(id, {finish, color, worktop}) dresses it: finish (any finish, such as oak or rustic-planks) or color (a #rrggbb paint, such as a dark kitchen island) for its fronts and sides, and worktop for the top of a counter or desk or a bench's seat, such as granite, marble, black-marble, terrazzo or concrete plan.alongWall(wall, start, end, style, room, {depth?, height?, elevation?}) → id: a built-in with its back against the wall's face inside the room, from offset start to offset end along the wall; keep the offsets clear of the walls at its ends plan.roof(floor, {shape?, pitch?, overhang?, eaveHeight?, finish?, color?, gutters?, rafters?, parapet?, followWalls?, trimColor?, gableFinish?, gableColor?, glazedGables?, at?, from?, to?, width?, min?, max?}) → id: a roof fitted to the walls around at (the middle of the floor's walls), or placed by its ridge from from to to with width its span across the ridge, overhang left out, or over the rectangle from min to max with its ridge along the longer side, as for a wing, a porch or a dormer; eaveHeight is the height of its eaves above the floor (the floor's height). Roofs on one floor meet in valleys: a dormer, a roof over the dormer's own walls with its eaves higher than the main roof, opens the main roof behind its glass, and a wing's roof joins the main roof. shape is Gable, Hip, Shed or Flat; gutters (true) hang along the eaves with downpipes that end on the roof, platform, floor or ground below them, rafters (false) shows a pitched roof's rafter tails under its eaves, parapet is the wall height around a flat roof's edge, followWalls (true) makes a flat roof trace the outer faces of the walls under it, curves and angles included, and stay open over courtyards (walled areas with no room marker), instead of its rectangle, and trimColor colors the fascia, gutters, coping and the frames of glazed gables. A gable or shed roof closes its gable ends: a wall under a gable end that is taller than the eaves (plan.set(wall, {height})) rises into the gable and closes it with its own finish, glass, doors and windows, so a window can sit high in the gable; gableFinish is a wall finish for the rest of the gables (the finish of most of the floor's outer walls), gableColor tints a tinted one, and glazedGables (false) makes them framed glass, as for a chalet plan.surface(floor, kind, min, max, {level?, depth?, infinity?, round?, water?, flow?, grassLength?, grassDensity?, plants?, edging?}) or (floor, kind, outline, {curves?, level?, depth?, water?, flow?, grassLength?, grassDensity?, plants?, edging?}) → id: an outdoor surface (lawn, path, driveway, road, sidewalk, patio, deck, gravel, bed, planter, terrace, sunken, court, pool or water) between the corners min and max, round ({round: true}, the ellipse that fills that rectangle, as for a round bed or pond), or with an outline of any shape through its corners in order, as [[x, y], …], whose edges curves bends: for each corner, how far the edge from it to the next corner bulges out at its middle in millimeters (0 straight, negative bulges in, at most the edge's length), for curved paths, kidney pools, and lakes and rivers with winding shores; plan.set(id, {outline, curves}) changes them. A road, a court, sunken seating and a pool with a vanishing edge keep their rectangle. A court is a sports court painted for basketball, a full court when 26000 or longer and a half court from its first end when shorter; put a basketball_hoop at each baseline. A road is asphalt with white edge lines and, when 4500 or wider, a dashed middle line along its longer side; plan.road lays a road along a path, and roads join where they meet (see road); a sidewalk is a 150 high concrete walk whose sides are its curbs. A lawn takes {grassLength (110 mm, 10 to 2000, such as 40 for a mown lawn or 400 for a meadow), grassDensity (10 tufts on a square meter, 1 to 100)}; a bed or a planter takes {plants: the plants that grow mixed in it, from flowers, shrub, agave, bamboo and cactus ([flowers]; [] for bare soil), edging: none, stone (the bed's), brick, steel (corten, the planter's) or timber}; grass and plants sway in the breeze in 3D. A planter is a raised bed, 450 high; a terrace is a raised paved area, 450 high; sunken is sunken seating: a pit depth (700) deep with a bench round its walls and steps down at the min end of its longer side. Water is {water: lake (the default), sea or river}, whose surface lies level millimeters above the floor (-1500) and whose ground sinks to depth (2500) below it, with shores that slope up from it; in the 3D view a lake ripples, the sea rolls in waves, and a river flows along its banks in the direction flow, [dx, dy] on the plan, which runs along the longer side of a river between two corners and toward max without one, and toward +y for an outline without one; and a pool takes a depth. A patio, deck, driveway, terrace, sunken seating, court or pool sits level at level millimeters above the floor (0), and the ground slopes up or down to it at 1 in 2; on an upper floor, such a surface and any other that the ground rises to, as at the street level of a house that steps down a hill, becomes part of the terrain at its floor's level the same way; {infinity: true} makes the pool's short end nearest max a vanishing edge, with its water running over a low wall there, for a pool at the edge of a terrace with a view plan.surfaceAt(floor, kind, from, to, width, {level?, depth?, infinity?, curve?}) → id: a surface of any kind that runs from from, the middle of one edge, to to, the middle of the opposite edge, and is width across, at any angle; a pool's vanishing edge is its edge at to, so plan.surfaceAt(0, "pool", [5000, 4000], [5000, 0], 10000, {infinity: true}) makes a pool 10000 long and 4000 wide whose long side at y 0 is the vanishing edge; curve bends a road into an arc whose middle lies that far to the left of from → to (negative bends it right), at most the distance between them plan.road(floor, points, {width?, curves?}) → ids: a road through the points in order, a stretch width (7000) wide from each point to the next whose middle bulges curves[i] to the left of points[i] → points[i + 1] (negative to the right, 0 or left out for a straight stretch), the stretches meeting end to end with the outside of each bend rounded. Roads join wherever an end of one lies on another, at a T, a corner or a shared end, and where they cross; there the curbs round the corners with a 6000 radius, the edge lines follow the curbs round into the other road, and the dashed middle lines stop short of the junction. plan.set(id, {curve}) bends one stretch plan.fence(floor, from, to, style?) → id: a fence of style rails, boards (the default), pickets, panels or hedge plan.run(floor, kind, points, {width?, height?, elevation?, drop?}) → ids: a duct or cable tray along points [[x, y], …], one run between each two; kind is round (a round duct 250 across, width its diameter), rect (a rectangular duct 500 wide and 300 high) or tray (a cable tray 300 wide with sides 80 high). elevation is its underside above the floor (200 under the ceiling). Runs of a kind join where they end: two on an elbow, three or more, or one that ends on another's middle, on a tee, a larger run narrowing to a smaller one on a reducer, and runs where one reaches above or below the other through an upright piece. drop turns the last run down that far below its underside at its end, where a duct ends in a grille; plan.set(id, {drop}) gives any run one at its to end plan.platform(floor, kind, min, max, {elevation?, railing?, supports?, finish?}) or (floor, kind, outline, {…}) → id: a platform between the corners min and max, or with an outline of any shape through its corners in order, as [[x, y], …], such as an L-shaped deck or one that wraps round a corner of the house, which plan.set(id, {outline}) changes (a rectangle takes {outline, at: null, width: null, length: null}); kind is balcony, deck (a deck on posts), walkway or pier, and each has its own elevation (its top above the floor, negative for a jetty down at the water below the floor), railing (none, bars or frameless glass, along every edge that no wall, other platform, arriving stair or, at the floor's level, pool runs along), supports (none, posts, piles, or caissons: concrete piers 1000 across that hold a platform out from a steep slope, down to the ground) and ground finish unless given plan.balcony(wall, start, end, depth?, {elevation?, railing?, supports?, finish?}) → id: a balcony against the wall's outside face, from offset start to offset end along it and depth (1500) deep; put a door in the wall to reach it plan.plot(points) → plot line ids around the plot on floor 0 plan.spot(at, level) → id: a spot height on floor 0 where the surveyed ground lies level millimeters above the floor; three or more shape the terrain, which keeps the site's slope far from them and stays level under patios, decks, driveways, terraces, sunken seating and pools, and under the house unless the grading is natural; a plan.wall that encloses nothing retains the ground behind it, and an upper floor that reaches past the floors under it into ground as high as its own level is dug into the slope, so that a house steps down a hill floor by floor plan.breakline(points) → ids: a breakline of the existing ground on floor 0 through points [x, y, level] in order, such as the top or the toe of a bank or the bottom of a ditch; the terrain between the spot heights and the breaklines follows each breakline as a straight edge from level to level plan.slope(percent, downhill, {at?, level?, size?}) → spot ids: replaces the spot heights with a site that falls percent in a hundred toward the plan direction downhill, such as [0, -1], and lies at level (0) at at (the middle of the bottom floor's walls), over a square size (60000) wide plan.site({grading?, ground?, winter?, banks?, surroundings?, contourInterval?}) → {grading, ground, winter, banks, surroundings, contourInterval}: grading level (the default) levels the ground around the house to the bottom floor; natural keeps the ground's shape, so that a house on a hillside is set into the slope, its walls holding back the ground uphill and reaching down to it downhill. ground is the finish that covers the site: grass (the default), sand, desert-sand, dry-earth, rock, forest-floor, moss, fallen-leaves, soil, gravel or another ground finish, or none for no ground at all, as for an apartment. winter is what winter brings to everything outdoors when the date of the 3D view's sun falls in winter: frost (the default), snow on every face that looks up, or mild for neither. On sand, desert-sand and dry-earth lawns are dry all year and no snow or frost falls; rock follows winter, so a mountain site can be snowy. Ground steeper than about 32° shows scree, and steeper than about 45° rock; banks, scree or rock, covers the slopes of cut and fill, and surroundings, a ground finish, the ground beyond a closed plot, each null for the ground cover. contourInterval is the height in millimeters between the contour lines of the plan, or null for one that suits the range of heights plan.info({title?, client?, address?, author?, north?, latitude?, longitude?, mapOrigin?, mapSystem?}) → {title, client, address, author, mapOrigin, mapSystem, latitude, longitude, zone, north}: the project information for title blocks, and where the site is. latitude and longitude are the site's place in degrees, north and east positive, set together (null removes them); they place the 3D view's sun and its shadows, on the clock of the site's time zone (zone), which follows from them. north is the degrees counterclockwise from the plan's +y axis to true north (0). mapOrigin is where the plan lies on the map: [east, north, height] in millimeters, the map coordinates of the plan's origin at the bottom floor's level, and mapSystem names the map's coordinate system, such as EPSG:25832; each null removes it. Survey imports place their points by them, and DXF, DWG and IFC exports place the plan on the map plan.finishes(use?) → [{key, name, uses, tint}]: the finish library, or the finishes for one use: wall, floor, roof, ground or object (furniture, built-ins, railings and the parts of shapes and items). A tinted finish takes a color plan.defineItem(key, {name, category?, keywords?, mount?, elevation?, lumens?, beam?, up?, kelvin?, parts} or {name, category?, keywords?, mount?, elevation?, lumens?, beam?, up?, kelvin?, children}) → key: adds or replaces a furnishing item of the project's own, which plan.furniture, plan.against and plan.search then use like a catalog item, and which people find in the Furnish tab. Make an item of anything placed more than once, such as a custom chair, a planter box or a light fitting. parts are as plan.shape's; the item is the box around them, and at rotation 0 its back faces +y. mount is floor (the default), wall, ceiling or roof: a ceiling item is placed under the ceiling, a wall item snaps to walls when people move it, and a roof item, such as a rooftop unit, stands on the highest roof of its floor under it, or on the floor where no roof is; elevation is the height of a floor or wall item's underside when placed (0), and of a roof item's above the roof; lumens makes the item a lamp whose parts with look glow give off its light, all round from their middle unless beam (degrees) makes each glowing part a spotlight along its own -z axis, which points down until the part turns (rotation [180, 0, 0] points it up), and beam 180 a panel, as for an LED strip; up (degrees, with a beam under 180) makes each glowing part also shine up in that cone along its +z axis, as the shade of a table lamp or a sconce open at both ends does; kelvin is the lamp's usual color temperature (2700). children combine items: [{furnishing, x, y, angle?, width?, length?}]. key is lowercase letters, digits, - and _. Replacing an item changes every furnishing that uses it plan.items() → the project's own items with their keys and sizes plan.removeItem(key) → removes an item that no furnishing uses plan.shape(floor, at, parts, {name?, rotation?, elevation?, draft?}) → id: any form, made of parts measured from at in the shape's own frame (x across, y along, z up from elevation), turned rotation degrees counterclockwise. It stands on the ground under its middle on any slope, so elevation counts from that ground and not from the floor: leave it out for a shed or a sculpture on a hillside, and make it negative only to sink the shape into the ground. With a draft it floats, as a boat, a buoy or a raft does: over a lake, the sea or a river its base lies draft millimeters under the water's surface, and on land it stands on the ground; plan.set(id, {draft}) makes a furnishing float the same way. Each part is {name?, solid, at? [x, y, z], rotation? [x, y, z] degrees, finish?, color?, look?} with the solid's fields: box {size: [x, y, z]} and pyramid {size: [x, y], top?: [x, y] (0 for a point), height} stand on at; cylinder {radius, top? (its top radius, 0 for a cone), height, segments?}; sphere {radius} around at; prism {outline, holes?, height} lifts a plan outline; lathe {profile: [[radius, z], …], segments?} turns a profile round the vertical axis; loft {sections: [{outline, z}, …]} joins outlines of equal point counts; mesh {vertices, faces} is any solid of triangles or polygons counterclockwise from outside. A radius is a number or [x, y] (sphere [x, y, z]). finish is any finish of the library, color a #rrggbb tint or plain color, look matte, metal, glass, water or glow. Write a loop to build towers, roofs, stairs or ornaments from many parts; plan.get returns the parts as written, with at, rotation and the size of the shape's box when it was stretched plan.finishFace(wall, side, finish, color?) → wall: finishes one whole face of a wall, as for an accent wall, in place of the finish of the room it looks into or of the wall's outside; side is left or right, looking from the wall's from to its to, or a room id for the face that looks into that room; finish is a wall finish, and color a #rrggbb tint for a tinted finish such as paint. null for the finish gives the face back its room's or outside finish. plan.get(wall).faces lists them. Coverings lie over a face's finish plan.cover(wall, side, {finish, color?, from?, to?, bottom?, top?}) → wall: covers part of one face of a wall with a finish, such as tiles up to 1200 in a bathroom, a splashback over a kitchen counter or a stone plinth outside. side is left or right, looking from the wall's from to its to, or a room id for the face that looks into that room. from and to are millimeters along the wall (its whole length, or the stretch that borders the room), bottom and top heights above the floor (the whole height); doors and windows stay open. plan.get(wall).coverings lists them, and plan.set(wall, {coverings}) changes them plan.section(floor, from, to, name?) → id: a section line, named A, B and so on unless name is given; its section cuts the whole house along the line, through walls, slabs, roofs, stairs and the ground, looks to the left of from → to and spans the line's length. The Elevations and sections dialog shows it, and PDF and DXF exports put the sections on a sheet of their own plan.label(floor, text, at) → id plan.set(id, fields) → changes fields in the file shape; null removes an optional field plan.remove(id) → deletes the element and the openings in it

Points are [x, y] in millimeters. Floors count from 0 at the bottom. Furniture items are keys from plan.search or search_furniture. Lamps (search "lighting" or "outdoor lighting") light the 3D view: plan.against puts a wall lamp on a wall, ceiling lamps hang from the ceiling, and plan.set(id, {lumens, kelvin, on}) sets a lamp's output, its color temperature and whether it is on.

Input Schema

NameRequiredDescriptionDefault
labelYesA few words for the plan's history, such as Add a garage.
scriptYes
project_idYesThe project's ID from list_projects or create_project. Never show it to the person.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare that this is a non-read-only, non-open-world operation, but the description adds substantial behavior beyond them: changes appear immediately in open editors, the script runs as a transaction where a failure leaves everything unchanged and names the failing line, there is no network, clock or randomness, and undo_change restores removed work for the last 50 changes. It also discloses deletion behavior via plan.remove while explaining that it is undoable.

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 definition is front-loaded with purpose, return values, undo behavior and transaction semantics before the API reference, which gives it useful structure. However, it is extremely long and reads like a full reference manual embedded in a tool description, with many low-level defaults and material details that make it heavy for an agent to scan during tool selection.

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?

Given the tool's complexity and the absence of an output schema, the description is unusually complete: it explains the return values, the atomic transaction behavior, the undo window, the immediate editor update, and the full scripting surface. There are no material omissions for an agent that needs to invoke this tool correctly.

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?

Schema coverage is only 67% because the script parameter has no schema description, but the description fully compensates by documenting the JavaScript execution model, the global plan object, transaction semantics, and an extensive list of operations with their arguments and return shapes. The remaining two parameters are documented in the schema itself.

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 opening sentence states a specific verb and resource ('Changes a plan') and the exact mechanism ('a short script of plan operations'), plus the immediate effect on the person's open editors. It also names undo_change as the revert path, distinguishing normal editing from undo.

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

Usage Guidelines3/5

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

The description makes clear that this tool is for changing a plan, and it mentions undo_change as the way to take a change back. However, it does not explicitly say when to choose this over read-oriented siblings such as describe_plan or query_project, nor does it state any exclusions or prerequisites for editing.

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