Skip to main content
Glama

sync_base

DestructiveIdempotent

Compare and synchronize Airtable base schemas and records between source and destination bases, using plan, apply, and status modes to control schema and record changes.

Instructions

Base-to-base schema + record sync. IMPORTANT: BOTH mode="plan" and mode="apply" run as BACKGROUND JOBS — they return {jobId, planId, status:"running"} IMMEDIATELY (jobId === planId), NOT a synchronous result; poll mode="status" with that planId to get progress and the final result. mode="plan" (read-only, does NOT mutate): computes an ordered plan (tables/fields to create/update + orphans + warnings) by comparing source/dest schema; when the job finishes, mode="status" returns the plan digest in planDigest. mode="apply" (requires planId from a prior plan): executes the saved plan against the destination — creates tables, reconciles the primary, creates scalar/link/computed fields (source->dest reference remapping + formula validation), applies non-destructive field updates, then runs the RECORD sync (two-pass cells + links, attachments, view-filter restore); aborts if the destination drifted since the plan. mode="status" (poll a plan OR apply job by its planId): returns { phase: "planning"|"schema"|"records"|"done"|"failed", status, recordsMapped, summary, schemaResult?, recordsResult?, result?, planDigest? }. planDigest is human-only by default ({ human, machineOmitted: true }) — pass verbose:true for the full planDigest.machine. Field-mapping errors, APPLY_LOCKED, and DRIFT surface HERE (phase="failed" or an aborted schemaResult), not as a synchronous error. mode="reconcile" (SYNCHRONOUS): rebuild/repair the record map — existence-prune dead idmap entries, optional natural-key re-match per table. mode="diff" (SYNCHRONOUS): schema digest comparing source and destination WITHOUT saving a plan; returns a diffId and summary; pass detail= to drill into a section of a prior diff.

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": {
      "mode": "<mode>",
      "sourceAppId": "<sourceAppId>",
      "destAppId": "<destAppId>"
    },
    "name": "sync_base"
  }
}

Input Schema

NameRequiredDescriptionDefault
modeYes"plan" (BACKGROUND job: computes a plan and returns a jobId immediately — poll mode="status" for the digest), "apply" (BACKGROUND job: runs the schema phase then the record sync, returns a jobId immediately — poll mode="status"), "status" (poll a plan OR apply job by planId for its phase + result), "reconcile" (SYNCHRONOUS: rebuild/repair the record map — existence-prune dead entries, optional natural-key re-match), or "diff" (SYNCHRONOUS: schema digest comparing source and destination without saving a plan; optionally drill into a section with detail=<section>).
skipNoUsed only by mode="apply": list of changeIds to skip (actions with a matching changeId are counted as skipped but not applied). Use changeIds from the plan output.
debugNoWhen true, include raw Airtable response in output for diagnostics
limitNoUsed by mode="diff" with detail: maximum number of entries to return.
detailNoUsed only by mode="diff": section name to drill into (e.g. a table name or action key). Requires diffId.
diffIdNoUsed by mode="diff": ID of a prior diff to retrieve or drill into. If omitted on the initial call, one is generated automatically.
offsetNoUsed by mode="diff" with detail: skip this many entries before returning results.
planIdNoRequired for mode="apply" (the planId from a prior mode="plan" run) and mode="status" (the jobId returned by mode="plan" OR mode="apply" — jobId === planId).
policyNoUsed by mode="apply" for the record reconciliation preset. "mirror" = converge dest toward source (delete dest-only records, overwrite dest edits); "overlay" = keep dest-only records, source updates win on conflicts (default); "preserve" = keep dest-only records and never overwrite dest edits. Requires confirmDeletions=true to actually delete in mirror mode. NOTE: "mirror" does NOT make the destination byte-identical — two removals are deferred and are reported, not performed: dest-extra LINKED-RECORD entries are never unlinked (Pass 2 only adds), and a source row that CLEARED its attachments leaves the dest attachment cell untouched. Watch for RECORD_LINK_EXTRA / attachment warnings in the result.
verboseNoUsed only by mode="status": by default planDigest is projected to { human, machineOmitted: true } (the full machine payload can be tens of thousands of lines on a view-heavy base and pushes the useful result fields out of the response — it always stays on disk). Set verbose:true to get the full planDigest.machine back in the response.
destAppIdYesDestination base/application ID to copy schema TO
directionNoUsed only by mode="plan": direction of the changeset. "to-dest" (default) brings the destination base up to date with the source. "to-source" swaps the roles so the changeset targets the source base (makes the source match the destination).
naturalKeysNoMap of tableName → fieldName to use as a natural key for record identity matching (e.g. { "Projects": "Name" }). Applies to mode="reconcile" (repairs the record map via natural-key re-match after manual edits) AND mode="apply" (auto pre-pass before Pass 1: matches existing dest records by key so they are updated rather than duplicated; also protects real-but-unmapped dest records from mirror-policy deletion). Omit for existence-prune only (reconcile) or pure ID-based sync (apply). The key field MUST be stable across bases: autoNumber renumbers on creation (bad key); name/email/injected InjectID are good keys.
sourceAppIdYesSource base/application ID to copy schema FROM
strictDriftNoUsed by mode=plan: also hash live VIEW CONFIG (filters/sorts/groups/colors/column order) into the plan's drift fingerprint, so a collaborator editing a view between plan and apply is detected. Costs one extra ~1s read PER VIEW on every apply of this plan (minutes on a view-heavy base) — which is why it is off by default. Field types, options, choices, formulas and descriptions are ALWAYS covered regardless of this flag. Recorded on the plan; apply reuses the plan's setting.
fieldMappingsNoField mapping overrides: maps table name → { sourceField: destField } to inject a source field's value into a different (writable scalar) dest field during record sync. Example: { "Games": { "Title": "Name" } }. In mode="plan" and mode="diff", fieldMappings are validated against the two schemas (dry-run, no mutation) and errors are returned in fieldMappingErrors.
confirmRetypesNoUsed by mode=apply: required to apply a matched field's SCALAR type change to the destination (source-wins). Without it, a diverging scalar type reports RETYPE_GATED and the field is kept. Non-scalar retypes (to/from formula/rollup/lookup/count/autoNumber/link/attachment) stay RETYPE_DEFERRED.
policyOverridesNoUsed by mode="apply": per-table reconciliation preset overrides. Maps table name → preset (e.g. { "Games": "preserve" }). Overrides the global policy for the named tables.
confirmDeletionsNoUsed by mode="apply" with policy="mirror": must be set to true to actually delete dest-only RECORDS and dest-only FIELDS/VIEWS. Without it, mirror mode reports a DELETION_GATED count and deletes nothing for records; orphan fields/views are reported and kept.
resumeAfterDriftNoUsed by mode=apply: continue a partially-applied plan even though the destination no longer matches the plan's fingerprint. A plan with prior progress has already mutated the destination itself, so some divergence is expected — but a collaborator's edit is indistinguishable from here, and the remaining actions (including deletions) would overwrite it. Prefer re-running mode=plan. Without this flag such an apply aborts with RESUME_DRIFT instead of silently overwriting.
confirmTableDeletionsNoUsed by mode=apply with policy=mirror: required to delete whole dest-only TABLES. confirmDeletions alone never drops a table; without confirmTableDeletions, orphan tables report TABLE_DELETION_GATED and are kept.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv1.0.9

TDQS

A4.9/5.0
Behavior5/5

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

Beyond annotations, it discloses that plan and apply are asynchronous background jobs returning a jobId immediately, that status must be polled, and where errors like APPLY_LOCKED, DRIFT, and field-mapping failures surface. It details destructive behavior, deletion gating, drift detection, mirror-policy caveats, and verbose planDigest projection — far more than the annotations provide.

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

Conciseness5/5

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

The description is long but front-loads the critical background-job behavior and then organizes details by mode. Given 21 parameters and five modes, the density is warranted, with little wasted wording.

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 complex, destructive sync tool with no output schema, the description explains return shapes, phases, polling, and failure surfaces. It gives the agent enough to invoke and interpret the tool without needing an 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?

With 100% schema description coverage, individual parameters are already thoroughly documented. The main description adds cross-parameter workflow meaning: jobId === planId, planId reuse for status/apply, skip changeIds from plan output, and verbose affecting planDigest. This exceeds the baseline but largely complements rather than replaces the schema text.

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 description opens with a specific verb and resource — 'Base-to-base schema + record sync' — and then enumerates five modes, making the tool readily distinguishable from siblings like get_base_schema or create_field. An agent can identify this as the orchestrated sync operation rather than a single schema read or field mutation.

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?

It specifies when to use each mode: plan for read-only planning, apply for execution with a prior planId, status for polling background jobs, reconcile for repairing the record map, and diff for schema comparison without saving. It also explains prerequisites such as apply requiring planId and status requiring jobId/planId, making alternatives and sequencing explicit.

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