Skip to main content
Glama

update_metaobject

Update an existing metaobject's handle, field values, or publishable status. Upserts fields by key; omitted fields remain unchanged. Clear a field by passing an empty string.

Instructions

Update an existing metaobject's handle, field values, or publishable status. Fields are upserted by key — pass only the fields you want to change; omitted fields keep their current values. To clear a field, pass an empty string or null-ish value matching the field type. If you change the handle, set redirectNewHandle=true to have Shopify redirect from the old handle on the storefront. The type cannot be changed by this tool — delete and recreate to change type.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesGID of the metaobject to update.
handleNoNew handle. Changes the storefront URL slug. Pair with redirectNewHandle=true to keep old links working.
fieldsNoField-level upserts: only the keys present here are written; other fields keep their current values. Pass empty string to clear a field.
statusNoNew publishable status (only for publishable types). Omit to leave unchanged.
redirectNewHandleNoIf true and `handle` is being changed, Shopify creates a 301 redirect from the old handle to the new one on the storefront.

Implementation Reference

  • Registration of the update_metaobject tool using server.tool(), registering the tool name, description, schema, and handler on the MCP server.
    server.tool(
      "update_metaobject",
      "Update an existing metaobject's handle, field values, or publishable status. Fields are upserted by key — pass only the fields you want to change; omitted fields keep their current values. To clear a field, pass an empty string or null-ish value matching the field type. If you change the handle, set redirectNewHandle=true to have Shopify redirect from the old handle on the storefront. The `type` cannot be changed by this tool — delete and recreate to change type.",
      updateMetaobjectSchema,
      async (args) => {
        const metaobject: Record<string, unknown> = {};
        if (args.handle !== undefined) metaobject.handle = args.handle;
        if (args.fields) metaobject.fields = args.fields;
        if (args.redirectNewHandle !== undefined) {
          metaobject.redirectNewHandle = args.redirectNewHandle;
        }
        if (args.status) {
          metaobject.capabilities = {
            publishable: { status: args.status },
          };
        }
        const data = await client.graphql<{
          metaobjectUpdate: {
            metaobject: MetaobjectNode | null;
            userErrors: ShopifyUserError[];
          };
        }>(METAOBJECT_UPDATE_MUTATION, { id: args.id, metaobject });
        throwIfUserErrors(data.metaobjectUpdate.userErrors, "metaobjectUpdate");
        const m = data.metaobjectUpdate.metaobject;
        if (!m) {
          return {
            content: [
              { type: "text" as const, text: "metaobjectUpdate returned no metaobject." },
            ],
          };
        }
        return {
          content: [
            {
              type: "text" as const,
              text: `Updated metaobject ${m.displayName ?? m.handle} (${m.type}) — ${m.id}`,
            },
          ],
        };
      },
    );
  • Handler function for the update_metaobject tool. Builds the metaobject payload from args (handle, fields, redirectNewHandle, status), calls the Shopify GraphQL API with METAOBJECT_UPDATE_MUTATION, throws on user errors, and returns a success message with the updated metaobject's display name, type, and GID.
    async (args) => {
      const metaobject: Record<string, unknown> = {};
      if (args.handle !== undefined) metaobject.handle = args.handle;
      if (args.fields) metaobject.fields = args.fields;
      if (args.redirectNewHandle !== undefined) {
        metaobject.redirectNewHandle = args.redirectNewHandle;
      }
      if (args.status) {
        metaobject.capabilities = {
          publishable: { status: args.status },
        };
      }
      const data = await client.graphql<{
        metaobjectUpdate: {
          metaobject: MetaobjectNode | null;
          userErrors: ShopifyUserError[];
        };
      }>(METAOBJECT_UPDATE_MUTATION, { id: args.id, metaobject });
      throwIfUserErrors(data.metaobjectUpdate.userErrors, "metaobjectUpdate");
      const m = data.metaobjectUpdate.metaobject;
      if (!m) {
        return {
          content: [
            { type: "text" as const, text: "metaobjectUpdate returned no metaobject." },
          ],
        };
      }
      return {
        content: [
          {
            type: "text" as const,
            text: `Updated metaobject ${m.displayName ?? m.handle} (${m.type}) — ${m.id}`,
          },
        ],
      };
    },
  • Input schema for update_metaobject using Zod. Defines the 'id' (required), 'handle', 'fields', 'status', and 'redirectNewHandle' (all optional) parameters with descriptions.
    const updateMetaobjectSchema = {
      id: z
        .string()
        .describe("GID of the metaobject to update."),
      handle: z
        .string()
        .optional()
        .describe(
          "New handle. Changes the storefront URL slug. Pair with redirectNewHandle=true to keep old links working.",
        ),
      fields: z
        .array(fieldInputSchema)
        .optional()
        .describe(
          "Field-level upserts: only the keys present here are written; other fields keep their current values. Pass empty string to clear a field.",
        ),
      status: z
        .enum(["ACTIVE", "DRAFT"])
        .optional()
        .describe(
          "New publishable status (only for publishable types). Omit to leave unchanged.",
        ),
      redirectNewHandle: z
        .boolean()
        .optional()
        .describe(
          "If true and `handle` is being changed, Shopify creates a 301 redirect from the old handle to the new one on the storefront.",
        ),
    };
  • GraphQL mutation used by the update_metaobject handler. Sends 'id' and 'metaobject' (MetaobjectUpdateInput) to Shopify's metaobjectUpdate endpoint and returns the updated metaobject with fields and capabilities.
    const METAOBJECT_UPDATE_MUTATION = /* GraphQL */ `
      mutation MetaobjectUpdate($id: ID!, $metaobject: MetaobjectUpdateInput!) {
        metaobjectUpdate(id: $id, metaobject: $metaobject) {
          metaobject {
            id
            type
            handle
            displayName
            fields { key type value }
            capabilities { publishable { status } }
          }
          userErrors { field message code }
        }
      }
    `;
  • The exported registration function that wires all metaobject tools (including update_metaobject) into the MCP server instance.
    export function registerMetaobjectTools(
      server: McpServer,
      client: ShopifyClient,
Behavior4/5

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

With no annotations, the description fully carries the burden of behavioral disclosure. It reveals that the tool performs upserts, allows clearing fields, and that the type is immutable. It also mentions the handle redirection behavior. However, it does not touch on authentication requirements, rate limits, or potential error scenarios.

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 at three sentences, front-loaded with the main purpose, and each sentence adds essential information without redundancy. The structure flows logically from general update behavior to specific details about handles and type immutability.

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?

Given the tool's complexity (5 parameters, no output schema), the description covers all key aspects: the scope of updates, field upsert semantics, clearing fields, handle change redirect, and type immutability. It is fully sufficient for an agent to use the tool correctly.

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?

Although the input schema already has 100% coverage, the description adds valuable context beyond the schema. It explains that fields are upserted (not replaced wholesale), how to clear a field, and the conditional redirect behavior. This adds meaning that the field descriptions alone do not convey.

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 begins with a clear verb ('Update') and resource ('existing metaobject'), and specifies the exact fields that can be modified (handle, field values, publishable status). This distinguishes it from sibling tools like create_metaobject, delete_metaobject, and get_metaobject.

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 explains that fields are upserted by key and that omitted fields keep their current values, providing clear guidance on partial updates. It also advises on clearing fields and using redirectNewHandle when changing the handle. However, it does not explicitly state when NOT to use this tool versus other metaobject tools.

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/miller-joe/shopify-mcp'

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