Skip to main content
Glama

data_patch_schema

Change a datastore's schema BY KEY, without rewriting the whole field list. Prefer this over data_set_schema for any EDIT: set REPLACES, so rebuilding the list from what you know silently drops the per-field settings you did not restate (labels, help, max_length, pattern, width, options) — same call, same success, no way to tell. fields merges by key: listed properties overwrite, unlisted ones are PRESERVED, unknown keys are appended. remove: ["key", …] is the explicit deletion (a wrong key is refused, never silently ignored) — it takes the field out of the SCHEMA; to erase the column from the rows' DATA, that is data_drop_column. remove_attrs: {"column": ["attr", …]} takes attributes off columns that STAY — merging only completes, so this is the only way to drop one declaration without reposting the whole schema; an unknown column or attribute is refused, and key cannot be dropped. key/new_rows change the head keys, untouched when omitted — key names the BUSINESS KEY: A write that DESIGNATES by the key — key= passed to the call (a batch, or a single row naming this key), or any write without id on a CLOSED table — modifies the row of an existing key value and creates a new one. A write that ADDS (neither id nor key=) with a key value already present is REFUSED unless it passes upsert=true, which merges onto that row — data_write, REST and oto_upload_url alike. The key never duplicates: its UNIQUE index guarantees it. new_rows: "reject" CLOSES the table (a write designating no existing row is refused), "create" reopens it. ⚠️ A column the schema does NOT declare is REFUSED at write, on EVERY table: declaring a column (data_patch_schema(fields=[{"key": …}])) is the ONLY way to add one. ⚠️ The declared format is a CONTRACT on every table: top-level options are enforced, the SHAPE of text/url/object/list/enum values is checked, an unknown layer is refused and a declared sub-record refuses an attribute it does not declare. There is NO head setting for it any more: unknown_columns was REMOVED on 2026-10-05 and is refused — columns and values are always checked. To ADD a column, list it in fields ({"key": …, "type": …}): it is appended, the others are untouched; to ACCEPT a value its options refuse, list the column again with the full options. key_required was REPLACED by new_rows on 2026-10-02 (refused with its exact equivalent); strict, unknown_fields and unknown_columns are refused: no head setting decides what is checked any more. Per field, readonly: true locks a value once SET (layers such as .comment stay open); a cell with NO value — key absent, null or "" — can still be filled once, so a column locked after its import is not empty for good, while @empty counts as set — the table's OWNER, or whoever GOVERNS it, can still replace such a value with data_write(readonly_override=true), for that one call and journaled, so locking a column never means nobody can correct it again. On the field that carries lifecycle, the block merges KEY BY KEY and its transitions merge STATE BY STATE: naming one state leaves the others alone, so declaring a way OUT of a terminal state is one line and costs nothing else. Each state maps to a LIST, even for one destination — transitions: {"won": ["lost"]}; a bare string is refused. Taking one out is explicit — transitions: {"lost": null} drops that state's exits, lifecycle: {transitions: null} drops the whole table. labels (the displayed name of each state) merges STATE BY STATE too: lifecycle: {labels: {"lost": "Lost"}} names that step and keeps the others' labels, {"lost": null} drops that one label. A key that its level does not admit (head, column, sub-field, of, lifecycle) is REFUSED when the patch posts or changes it — the refusal names the path, the key and the closest known one; an unknown key ALREADY stored and left untouched does not block a patch of another column, and remove_attrs takes it off. Your own annotations go in meta (an object, at every level, carried as is, never read, at most 4096 bytes as JSON; a patch replaces it whole); help text goes in description (note, help, hint, placeholder are refused). Field ORDER is never reshuffled. Returns the resulting schema plus {added, updated, removed} and any warning the schema raises, and existing_violations: per path (contacts[].email), how many rows ALREADY IN PLACE break the resulting schema, a sample of their ids and the consequence (blocking_rows accept no write at all until fixed) — clean them before arming the guard. existing_violations_scope.complete: false means the row cap was hit: the counts are floors.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "datastore": "<datastore>"
    },
    "name": "data_patch_schema"
  }
}

Input Schema

NameRequiredDescriptionDefault
keyNo
_orgNo
_groupNoÉquipe (id) de CET APPEL, sous son org parente.
fieldsNoMerges BY `key`: the properties you list overwrite, the ones you omit are PRESERVED, an unknown key is appended. Send only what changes.
removeNoKeys to take out of the SCHEMA (a key that is not there is refused, never silently ignored). It does not touch the rows' DATA — that is `data_drop_column`.
_run_idNoOBLIGATOIRE à chaque appel dès `run_start` ou `data_claim_next` : sans lui, l'écriture sur une ligne réservée est refusée. Hérité seulement si le serveur tient un run actif — n'y compte pas.
_projectNoProjet (id) de CET APPEL — jeton PRIMAIRE. `oto_project(op='list')`.
new_rowsNoWhether a NEW row may be born: `"create"` (the default) or `"reject"` — CLOSES the table: a write designating no existing row (no `id`, no key value the table already carries) is refused; needs `key`. Omitted leaves it untouched.
datastoreYes
remove_attrsNoAttributes to take off columns that STAY: `{"column": ["attr", …]}`. Merging only completes, and `remove` drops a whole column — without this, taking one attribute off meant reposting the entire schema, which silently drops every declaration you did not resend. An unknown column or attribute is refused, never silently ignored. `key` cannot be taken off: it is the column's identity, not one of its properties.

Schema Changelog

Changes observed during successful MCP inspections.

No schema history has been recorded yet.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations supplied, the description carries the full burden and does so: merge-by-key semantics, refusals for unknown keys/columns/attributes with the error naming the closest known key, `key` non-removability, `new_rows` closing/opening the table, `upsert` requirements, UNIQUE-index guarantees, readonly locking and `readonly_override`, lifecycle transitions merge granularity, and the `existing_violations` return payload including `complete: false` as a floor. This is far beyond what any annotation would have declared.

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 leading sentence is front-loaded and the paragraph is internally organized (fields → remove → remove_attrs → head keys → format contract → lifecycle → meta → returns), but it is a single very long block dense with historical migration notes (`unknown_columns` removed 2026-10-05, `key_required` replaced 2026-10-02, `strict`/`unknown_fields` refused). That deprecation archaeology is tangential to invoking the tool correctly and inflates length considerably.

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 10-parameter schema-mutation tool with no annotations and no output schema, the description covers merge semantics, refusal modes, key/uniqueness rules, readonly behavior, lifecycle granularity, and even the return payload shape including `added`/`updated`/`removed`, `warning`, and `existing_violations_scope.complete: false`. Nothing an agent needs in order to call this safely is missing.

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 70%, so the description must compensate and does: it defines `fields` merge behavior, `remove` as schema-only deletion, `remove_attrs` as the only way to drop a single attribute, `new_rows` as `"create"`/`"reject"` with the table-closing consequence, and `key` as the BUSINESS KEY governing designation-vs-append writes. That adds substantial meaning beyond the terse schema property descriptions.

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 — 'Change a datastore's schema BY KEY, without rewriting the whole field list' — and immediately names `data_set_schema` as the alternative it is not. An agent can distinguish this from `data_get_schema`, `data_set_schema`, `data_drop_column`, and `data_write` without opening any schema.

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

Usage Guidelines5/5

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

Explicit routing is given: prefer this over `data_set_schema` for any EDIT, because `set` REPLACES and silently drops un-restated per-field settings. It also states that `remove` takes the field out of the schema while erasing the column's data is `data_drop_column`, and that `remove_attrs` is the only way to drop one attribute from a column that stays. When-to-use and when-not-to-use are both covered.

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