Skip to main content
Glama

set_form_metadata

Idempotent

Update form view metadata—such as description, submit confirmation, and redirect URL—in a single call, modifying only specified properties.

Instructions

Update one or more legacy-form-view metadata properties in a single call. Unset properties are not touched. Each property fans out to its own atomic Airtable endpoint.

Supported properties: description — intro text shown above the form afterSubmitMessage — "thank you" text after submission redirectUrl — URL to redirect to after submit refreshAfterSubmit — post-submit behavior (e.g. "REFRESH_BUTTON") shouldAllowRequestCopyOfResponse — boolean: show "send me a copy" toggle to respondents shouldAttributeResponses — boolean: track which user submitted (for signed-in respondents) isAirtableBrandingRemoved — boolean: hide Airtable branding (paid plans only)

Note: "form title" is the view name itself — use rename_view to change it. "Field labels on the form" use a per-field endpoint that has not been captured yet.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appIdYesThe Airtable base/application ID
viewIdYesThe form view ID
descriptionNoIntro text shown above the form (omit to leave unchanged)
afterSubmitMessageNoConfirmation text shown after submission
redirectUrlNoURL to redirect to after submit
refreshAfterSubmitNoPost-submit behavior (e.g. "REFRESH_BUTTON")
shouldAllowRequestCopyOfResponseNoAllow respondents to request a copy of their submission
shouldAttributeResponsesNoTrack which signed-in user submitted each response
isAirtableBrandingRemovedNoHide the Airtable branding on the form (paid plans)
debugNoWhen true, include raw Airtable response in output for diagnostics

Implementation Reference

  • The tool handler function for set_form_metadata. Destructures appId, viewId, debug, and ...props (the remaining form metadata properties), calls client.setFormMetadata(), and returns the result.
    async set_form_metadata({ appId, viewId, debug, ...props }) {
      const result = await client.setFormMetadata(appId, viewId, props);
      return ok(result, result, debug);
    },
  • Tool definition (inputSchema) for set_form_metadata. Defines the tool name, description of supported properties (description, afterSubmitMessage, redirectUrl, refreshAfterSubmit, shouldAllowRequestCopyOfResponse, shouldAttributeResponses, isAirtableBrandingRemoved), and the required params (appId, viewId).
      // ── Form metadata (legacy form views only — Interfaces / "builder forms" are out of scope) ──
      {
        name: 'set_form_metadata',
        description: `Update one or more legacy-form-view metadata properties in a single call. Unset properties are not touched. Each property fans out to its own atomic Airtable endpoint.
    
    Supported properties:
      description                       — intro text shown above the form
      afterSubmitMessage                — "thank you" text after submission
      redirectUrl                       — URL to redirect to after submit
      refreshAfterSubmit                — post-submit behavior (e.g. "REFRESH_BUTTON")
      shouldAllowRequestCopyOfResponse  — boolean: show "send me a copy" toggle to respondents
      shouldAttributeResponses          — boolean: track which user submitted (for signed-in respondents)
      isAirtableBrandingRemoved         — boolean: hide Airtable branding (paid plans only)
    
    Note: "form title" is the view name itself — use rename_view to change it. "Field labels on the form" use a per-field endpoint that has not been captured yet.`,
        annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
        inputSchema: {
          type: 'object',
          properties: {
            appId: { type: 'string', description: 'The Airtable base/application ID' },
            viewId: { type: 'string', description: 'The form view ID' },
            description: { type: 'string', description: 'Intro text shown above the form (omit to leave unchanged)' },
            afterSubmitMessage: { type: 'string', description: 'Confirmation text shown after submission' },
            redirectUrl: { type: 'string', description: 'URL to redirect to after submit' },
            refreshAfterSubmit: { type: 'string', description: 'Post-submit behavior (e.g. "REFRESH_BUTTON")' },
            shouldAllowRequestCopyOfResponse: { type: 'boolean', description: 'Allow respondents to request a copy of their submission' },
            shouldAttributeResponses: { type: 'boolean', description: 'Track which signed-in user submitted each response' },
            isAirtableBrandingRemoved: { type: 'boolean', description: 'Hide the Airtable branding on the form (paid plans)' },
            debug: debugProp,
          },
          required: ['appId', 'viewId'],
        },
      },
  • The AirtableClient.setFormMetadata() method that fans out each property to its own Airtable internal API endpoint (e.g., updateFormDescription, updateFormAfterSubmitMessage, etc.).
    async setFormMetadata(appId, viewId, props = {}) {
      assertAirtableId(appId, 'appId');
      assertAirtableId(viewId, 'viewId');
      const ops = [];
      if (props.description !== undefined)
        ops.push(['updateFormDescription', { description: props.description }]);
      if (props.afterSubmitMessage !== undefined)
        ops.push(['updateFormAfterSubmitMessage', { afterSubmitMessage: props.afterSubmitMessage }]);
      if (props.redirectUrl !== undefined)
        ops.push(['updateFormRedirectUrl', { redirectUrl: props.redirectUrl }]);
      if (props.refreshAfterSubmit !== undefined)
        ops.push(['updateFormRefreshAfterSubmit', { refreshAfterSubmit: props.refreshAfterSubmit }]);
      if (props.shouldAllowRequestCopyOfResponse !== undefined)
        ops.push(['updateFormShouldAllowRequestCopyOfResponse', { shouldAllowRequestCopyOfResponse: !!props.shouldAllowRequestCopyOfResponse }]);
      if (props.shouldAttributeResponses !== undefined)
        ops.push(['updateFormShouldAttributeResponses', { shouldAttributeResponses: !!props.shouldAttributeResponses }]);
      if (props.isAirtableBrandingRemoved !== undefined)
        ops.push(['updateFormIsAirtableBrandingRemoved', { isAirtableBrandingRemoved: !!props.isAirtableBrandingRemoved }]);
    
      if (ops.length === 0) {
        throw new Error('setFormMetadata requires at least one property to update');
      }
    
      const applied = {};
      for (const [endpoint, payload] of ops) {
        const url = `https://airtable.com/v0.3/view/${viewId}/${endpoint}`;
        const res = await this.auth.postForm(url, this._mutationParams(payload, appId), appId);
        if (!res.ok) {
          const errBody = await res.text().catch(() => '');
          throw new Error(`${endpoint} failed (${res.status}): ${errBody}`);
        }
        Object.assign(applied, payload);
      }
      return { updated: true, viewId, applied };
    }
  • Registration of set_form_metadata in the TOOL_CATEGORIES map, assigning it to the 'form-write' category for profile-based enable/disable control.
    set_form_metadata:                'form-write',
  • Duplicate registration in the VS Code extension's TOOL_CATEGORIES map (must mirror the server-side map), also assigning set_form_metadata to 'form-write'.
    set_form_metadata:                'form-write',
Behavior4/5

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

Annotations provide idempotentHint=true and destructiveHint=false. The description adds detail about fan-out to atomic endpoints and that unset properties remain unchanged, aligning with idempotency. No contradictions.

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 concise, front-loaded with the main purpose, and uses a clear bullet list for properties. Every sentence adds value without redundancy.

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?

All parameters are covered, no output schema needed, and the description notes limitations (form title, field labels). The tool is well-specified for its purpose.

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 100%; the description repeats the schema's parameter descriptions without adding significant new meaning beyond formatting and a note about unsupported fields. Baseline 3 is appropriate.

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 clearly states it updates 'legacy-form-view metadata properties' and lists specific properties. It distinguishes from siblings like rename_view by explicitly noting that form title is handled elsewhere.

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

Usage Guidelines4/5

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

The description mentions that unset properties are not touched and excludes some alternatives (rename_view for title, separate endpoint for field labels). However, it does not explicitly state when to prefer this tool over others.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Automations-Project/VSCode-Airtable-Formula'

If you have feedback or need assistance with the MCP directory API, please join our Discord server