Skip to main content
Glama

Plan a city

city_plan

Makes a city from a seed number and a size (the side of a square, 300 to 2000 metres, 800 by default): streets at varied spacing, closer together toward the centre, some of them curving, some ending at a cross street so blocks vary in size, an avenue every few, one or two diagonal avenues and usually a ring road. The town does not fill the square: it thins toward an outline of its own (answered as outline), lots grow and houses scatter toward the edge, most streets stop short of it and a few avenues run on out of the square, and the ground beyond the town holds fields, pastures and copses (answered as fields, each clear of every road, hedged by trees). Between the dense core and the outskirts lies a suburban ring: residential streets that curve and branch (crescents that leave a street and return to it, cul-de-sacs ending in turning circles), small lots marked suburban, each with a house of one or two floors turned to its street and set back from it (a building's kind says house, semi for a pair, shop on a corner or school on a large lot, and the view, the obj and the glb roof them with pitched roofs), the houses lining both sides of narrow residential streets (about seven metres wide, with lanes running into deep blocks) and a garden with trees round every house, and a few local parks. The blocks the streets leave, with a plaza near the centre and parks; the lots each block divides into; and the buildings, each a footprint with a height and a floor count, rising toward the centre. Footprints are cut along the roads' own lines (a building beside a diagonal avenue is a trapezoid or a wedge, never a staircase), a block the buildings would leave mostly empty becomes a park, a lot left unbuilt is a yard with trees (a paddock, hedged, in the outskirts), and every park carries footpaths from street to street, benches beside them and trees kept clear of them. formats picks the files (json, png, obj, glb; json, png and glb by default): city.json is the plan, every street as a polyline with its kind and width and every block, park (with its trees), lot and building footprint as an outline, in metres with x east and z south from the middle of the square; city.png is the plan seen from above, north up, px pixels a side (256 to 2048, 1024 by default), buildings shaded by height; city.obj and city.glb are the massing model, the ground, streets, parks and every building extruded to its height, in metres with y up. terrain (a seed word, as terrain_heightmap takes) stands the city on that country's ground instead of a plane, centred at origin {x, z} in metres (0, 0 by default) with relief 0 to 40 as terrainAmp: every lot is levelled to a terrace and its buildings stand on it, every road point carries a height (y, held to a 12 percent grade by cutting and filling), a building whose corners would be more than 2.5 metres off its terrace stands in steps (its footprint is cut across the fall into pieces, each on its own base, and the answer counts those buildings as stepped) and is left out only where even that cannot hold the ground (counted as tooSteep, with the ground's low and high), two roads that meet carry one height at the junction, the terraces fade into the country over a fifty metre apron whose edge heights are listed under terrain.apron, the picture is shaded by the relief, and the obj and glb carry the terraced ground, apron included, with the streets lying on it. view (a list of cameras from aerial, a high oblique over the whole square, corner, a low oblique from the south-east, and skyline, a low view from the south across the roofs) also draws the massing model lit, with an afternoon sun, shadows and sky, as city-view-.png at viewPx pixels wide (320 to 1600, 960 by default, two thirds as tall), country shown round the square: it is the picture of what the other files hold, for when there is no model viewer to open them in. Where a stepped building's pieces meet on a slope, each uphill piece lists its seam (the shared edge and the drop) and the obj and glb carry a retaining wall there; a park on the edge of a hill follows the ground instead of a terrace (graded), the city's surface at its edge is held within three metres of the country's, and the picture shows the apron's fifty metres past the square. The answer carries the counts, the tallest building, the mean heights of the core and of the edge and the plan's sha256. The same seed and size give the same city. Costs 1 unit; views add to it (three wide views of the largest city cost 2).

Input Schema

NameRequiredDescriptionDefault
pxNoWidth in pixels of the plan picture, 256 to 2048.
seedYesA whole number that makes the city; the same seed and options give the same plan.
sizeNoThe side of the city square in metres, 300 to 2000 (default 800).
viewNoCamera views of the massing to render: aerial, corner or skyline. Each adds to the cost.
originNoWhere on that terrain the city sits, as {x, z} in metres.
reliefNoHow far the ground may rise and fall under the city, in metres, 0 to 40.
viewPxNoWidth in pixels of each view, 320 to 1600 (the height is two thirds).
formatsNoFiles to return: json, png, obj or glb.
terrainNoA terrain seed word to build the city on, so it sits on that country.

Output Schema

NameRequiredDescriptionDefault
msNoMilliseconds the run took.
jobYesThe job id; the job tool reads it.
verbNoThe tool that made it.
filesNoFiles made, each with a name, type, size and a signed URL.
unitsNoUnits this call cost.
resultNoThe engine's own answer, a JSON document.
statusNoqueued when the job runs in the background.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed10 schema fields changed
    • addedInput schema / properties / formats / description
      Added value: +"Files to return: json, png, obj or glb."
    • addedInput schema / properties / origin / description
      Added value: +"Where on that terrain the city sits, as {x, z} in metres."
    • addedInput schema / properties / px / description
      Added value: +"Width in pixels of the plan picture, 256 to 2048."
    • addedInput schema / properties / relief / description
      Added value: +"How far the ground may rise and fall under the city, in metres, 0 to 40."
    • addedInput schema / properties / seed / description
      Added value: +"A whole number that makes the city; the same seed and options give the same plan."
    • addedInput schema / properties / size / description
      Added value: +"The side of the city square in metres, 300 to 2000 (default 800)."
    • addedInput schema / properties / terrain / description
      Added value: +"A terrain seed word to build the city on, so it sits on that country."
    • addedInput schema / properties / view / description
      Added value: +"Camera views of the massing to render: aerial, corner or skyline. Each adds to the cost."
    • addedInput schema / properties / viewPx / description
      Added value: +"Width in pixels of each view, 320 to 1600 (the height is two thirds)."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": true,
      +  "properties": {
      +    "files": {
      +      "description": "Files made, each with a name, type, size and a signed URL.",
      +      "items": {
      +        "additionalProperties": {},
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "job": {
      +      "description": "The job id; the job tool reads it.",
      +      "type": "string"
      +    },
      +    "ms": {
      +      "description": "Milliseconds the run took.",
      +      "type": "number"
      +    },
      +    "result": {
      +      "description": "The engine's own answer, a JSON document."
      +    },
      +    "status": {
      +      "description": "queued when the job runs in the background.",
      +      "type": "string"
      +    },
      +    "units": {
      +      "description": "Units this call cost.",
      +      "type": "number"
      +    },
      +    "verb": {
      +      "description": "The tool that made it.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "job"
      +  ],
      +  "type": "object"
      +}
  2. First observed

TDQS

A4.1/5.0
Behavior5/5

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

Annotations only give a generic safety profile (readOnlyHint=false, destructiveHint=false), yet the description discloses determinism ('The same seed and size give the same city'), the cost model ('Costs 1 unit; views add to it'), what each output file contains, and how terrain/relief alters geometry (terracing, stepped buildings, retaining walls, apron). This is far beyond what the annotations convey.

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 content is dense but delivered as one enormous run-on block riddled with nested parentheticals, so it is neither front-loaded beyond the first clause nor scannable. Much of the detail (every park/bench/hedge rule) is over-specified for a tool-selection decision and would be better in documentation.

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 complex 9-parameter procedural generator with an output schema, the description is thorough enough that an agent could invoke it correctly, including cost and determinism caveats. It is slightly redundant in re-describing return values already covered by the output schema.

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?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning the schema lacks: default formats ('json, png and glb by default'), the content of each file type, what terrain/relief/origin do geometrically, and the camera meanings behind view. It stops short of explaining every parameter interaction, so not a 5.

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 clause states a specific verb and resource — 'Makes a city from a seed number and a size' — and then enumerates exactly what the output contains (streets, blocks, lots, buildings, terrain). An agent can tell this is a procedural city generator distinct from terrain_heightmap, raster_render or world_apply without opening the schema.

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?

Usage is only implied. The description explains what view is 'for when there is no model viewer to open them in' and cross-references terrain_heightmap for terrain seed words, but never states when to choose city_plan over a sibling generator or what the prerequisites are. No explicit when/when-not guidance.

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