Skip to main content
Glama

Update the Feature Map

update-feature-map
Read-onlyIdempotent

Applies one change to a feature map, such as adding, renaming or removing a feature or flow, setting the Main Quest and its initiatives, or linking a flow to an initiative, and returns the updated map.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mapYesThe exact contents of .better-design/feature-map.json.
changeYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / change / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "description": {
      -        "maxLength": 500,
      -        "type": "string"
      -      },
      -      "flows": {
      -        "items": {
      -          "properties": {
      -            "description": {
      -              "maxLength": 500,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "steps": {
      -              "items": {
      -                "properties": {
      -                  "action": {
      -                    "maxLength": 300,
      -                    "type": "string"
      -                  },
      -                  "components": {
      -                    "default": [],
      -                    "items": {
      -                      "maxLength": 500,
      -                      "minLength": 1,
      -                      "type": "string"
      -                    },
      -                    "maxItems": 200,
      -                    "type": "array"
      -                  },
      -                  "data": {
      -                    "default": [],
      -                    "items": {
      -                      "maxLength": 500,
      -                      "minLength": 1,
      -                      "type": "string"
      -                    },
      -                    "maxItems": 200,
      -                    "type": "array"
      -                  },
      -                  "name": {
      -                    "maxLength": 120,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "route": {
      -                    "maxLength": 300,
      -                    "type": "string"
      -                  },
      -                  "screen": {
      -                    "maxLength": 500,
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "name"
      -                ],
      -                "type": "object"
      -              },
      -              "maxItems": 50,
      -              "minItems": 1,
      -              "type": "array"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "steps"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 100,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "add-feature",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "feature": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "name": {
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "rename-feature",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "feature",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "feature": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "remove-feature",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "feature"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "feature": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "flow": {
      -        "properties": {
      -          "description": {
      -            "maxLength": 500,
      -            "type": "string"
      -          },
      -          "name": {
      -            "maxLength": 120,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "steps": {
      -            "items": {
      -              "properties": {
      -                "action": {
      -                  "maxLength": 300,
      -                  "type": "string"
      -                },
      -                "components": {
      -                  "default": [],
      -                  "items": {
      -                    "maxLength": 500,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "maxItems": 200,
      -                  "type": "array"
      -                },
      -                "data": {
      -                  "default": [],
      -                  "items": {
      -                    "maxLength": 500,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "maxItems": 200,
      -                  "type": "array"
      -                },
      -                "name": {
      -                  "maxLength": 120,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "route": {
      -                  "maxLength": 300,
      -                  "type": "string"
      -                },
      -                "screen": {
      -                  "maxLength": 500,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "name"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 50,
      -            "minItems": 1,
      -            "type": "array"
      -          }
      -        },
      -        "required": [
      -          "name",
      -          "steps"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "set-flow",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "feature",
      -      "flow"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "feature": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "flow": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "name": {
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "rename-flow",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "feature",
      -      "flow",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "feature": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "flow": {
      -        "description": "The id or exact name of an existing feature or flow.",
      -        "maxLength": 120,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "remove-flow",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "feature",
      -      "flow"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "description": {
      +        "maxLength": 500,
      +        "type": "string"
      +      },
      +      "flows": {
      +        "items": {
      +          "properties": {
      +            "description": {
      +              "maxLength": 500,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "steps": {
      +              "items": {
      +                "properties": {
      +                  "action": {
      +                    "maxLength": 300,
      +                    "type": "string"
      +                  },
      +                  "components": {
      +                    "default": [],
      +                    "items": {
      +                      "maxLength": 500,
      +                      "minLength": 1,
      +                      "type": "string"
      +                    },
      +                    "maxItems": 200,
      +                    "type": "array"
      +                  },
      +                  "data": {
      +                    "default": [],
      +                    "items": {
      +                      "maxLength": 500,
      +                      "minLength": 1,
      +                      "type": "string"
      +                    },
      +                    "maxItems": 200,
      +                    "type": "array"
      +                  },
      +                  "name": {
      +                    "maxLength": 120,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "route": {
      +                    "maxLength": 300,
      +                    "type": "string"
      +                  },
      +                  "screen": {
      +                    "maxLength": 500,
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "name"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 50,
      +              "minItems": 1,
      +              "type": "array"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "steps"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 100,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "add-feature",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "name": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "rename-feature",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "remove-feature",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "flow": {
      +        "properties": {
      +          "description": {
      +            "maxLength": 500,
      +            "type": "string"
      +          },
      +          "name": {
      +            "maxLength": 120,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "steps": {
      +            "items": {
      +              "properties": {
      +                "action": {
      +                  "maxLength": 300,
      +                  "type": "string"
      +                },
      +                "components": {
      +                  "default": [],
      +                  "items": {
      +                    "maxLength": 500,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "maxItems": 200,
      +                  "type": "array"
      +                },
      +                "data": {
      +                  "default": [],
      +                  "items": {
      +                    "maxLength": 500,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "maxItems": 200,
      +                  "type": "array"
      +                },
      +                "name": {
      +                  "maxLength": 120,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "route": {
      +                  "maxLength": 300,
      +                  "type": "string"
      +                },
      +                "screen": {
      +                  "maxLength": 500,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "name"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 50,
      +            "minItems": 1,
      +            "type": "array"
      +          }
      +        },
      +        "required": [
      +          "name",
      +          "steps"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "set-flow",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature",
      +      "flow"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "flow": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "name": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "rename-flow",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature",
      +      "flow",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "flow": {
      +        "description": "The id or exact name of an existing feature or flow.",
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "remove-flow",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature",
      +      "flow"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "ends": {
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      },
      +      "goal": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "initiatives": {
      +        "items": {
      +          "properties": {
      +            "name": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "outcome": {
      +              "description": "One sentence that is true when the initiative is done.",
      +              "maxLength": 300,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "outcome"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "op": {
      +        "const": "set-main-quest",
      +        "type": "string"
      +      },
      +      "starts": {
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "goal",
      +      "ends"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "end-main-quest",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "name": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "add-initiative",
      +        "type": "string"
      +      },
      +      "outcome": {
      +        "description": "One sentence that is true when the initiative is done.",
      +        "maxLength": 300,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name",
      +      "outcome"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "initiative": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "remove-initiative",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "initiative"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "feature": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "flow": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "initiative": {
      +        "anyOf": [
      +          {
      +            "maxLength": 120,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "An initiative id or name, \"foundation\", or null to remove the link."
      +      },
      +      "op": {
      +        "const": "set-initiative",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "feature",
      +      "initiative"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. First observed

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, and the description is consistent with that by framing the tool as a transform that 'returns the updated map' rather than a side-effecting write. It usefully adds the single-change atomicity constraint, but leaves the persistence question open — an agent cannot tell from the description whether the returned map must be written back to .better-design/feature-map.json or what happens on an invalid op.

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

Conciseness4/5

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

A single front-loaded sentence with the verb first and no filler; every clause maps to real functionality. It is dense with a long enumerated list, but nothing is redundant or wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-complexity, 10-variant oneOf tool with no output schema and a readOnly annotation, the description covers the op space broadly and states the return value. The critical gap is the write-back/persistence model and error behavior on malformed ops, which an agent needs before composing a call.

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?

Schema description coverage is 50%: the 'map' param is documented as 'the exact contents of .better-design/feature-map.json' while the large 'change' oneOf is self-describing via const ops. The description adds a prose summary of the op set, which helps an agent skim the union, but it neither enumerates every op (end-main-quest, add/remove-initiative, set-initiative are only loosely implied) nor clarifies required fields per op. Baseline 3 is appropriate given the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb ('Applies one change') and resource ('feature map') and enumerates the operation space (add/rename/remove feature or flow, set Main Quest and initiatives, link flow to initiative), so the agent knows exactly what the tool covers. It never names the obvious siblings read-feature-map or build-feature-map, so the boundary against those is left implicit rather than stated.

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 phrase 'Applies one change' implies an incremental workflow (repeated calls for multiple edits), which is a weak usage signal distinguishing it from a from-scratch builder. There is no explicit when-to-use/when-not, no named alternative, and no prerequisites such as needing to read the map first.

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.