create_metaobject
Create a metaobject instance by providing its type and field values. Optionally set a handle or publish status. Returns the GID for linking to products or other entities via metafields.
Instructions
Create a new metaobject (instance) of an existing type. The type must match a registered metaobject definition — call list_metaobject_definitions first if you're unsure. fields is an array of {key, value} pairs; values are always strings (JSON/reference fields take a JSON-encoded string, primitives take literal text). handle is optional; Shopify generates one from the displayName field if present. status only applies to types that have the publishable capability — passing it for non-publishable types is silently ignored. Returns the new metaobject's GID for use in subsequent set_metafield calls (e.g. linking the metaobject to a product via a metaobject_reference metafield).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Type handle from a registered metaobject definition. The definition must already exist; this tool does not create new types/schemas. | |
| handle | No | Optional URL-safe handle. If the type has a 'displayName' field, Shopify generates a handle from it; otherwise pass one here. | |
| fields | Yes | Field values. Provide at least the required fields from the type's definition. Required fields without values cause a validation error. | |
| status | No | Publish status. Only applies to types that declared the `publishable` capability — passing this for non-publishable types is silently ignored. ACTIVE = visible on storefront, DRAFT = hidden. |
Implementation Reference
- src/tools/metaobjects.ts:380-419 (handler)Handler for the create_metaobject tool. Calls the Shopify GraphQL metaobjectCreate mutation with type, fields, optional handle, and optional publishable status.
server.tool( "create_metaobject", "Create a new metaobject (instance) of an existing type. The `type` must match a registered metaobject definition — call list_metaobject_definitions first if you're unsure. `fields` is an array of {key, value} pairs; values are always strings (JSON/reference fields take a JSON-encoded string, primitives take literal text). `handle` is optional; Shopify generates one from the displayName field if present. `status` only applies to types that have the `publishable` capability — passing it for non-publishable types is silently ignored. Returns the new metaobject's GID for use in subsequent set_metafield calls (e.g. linking the metaobject to a product via a metaobject_reference metafield).", createMetaobjectSchema, async (args) => { const metaobject: Record<string, unknown> = { type: args.type, fields: args.fields, }; if (args.handle) metaobject.handle = args.handle; if (args.status) { metaobject.capabilities = { publishable: { status: args.status }, }; } const data = await client.graphql<{ metaobjectCreate: { metaobject: MetaobjectNode | null; userErrors: ShopifyUserError[]; }; }>(METAOBJECT_CREATE_MUTATION, { metaobject }); throwIfUserErrors(data.metaobjectCreate.userErrors, "metaobjectCreate"); const m = data.metaobjectCreate.metaobject; if (!m) { return { content: [ { type: "text" as const, text: "metaobjectCreate returned no metaobject." }, ], }; } return { content: [ { type: "text" as const, text: `Created metaobject ${m.displayName ?? m.handle} (${m.type}) — ${m.id}`, }, ], }; }, - src/tools/metaobjects.ts:195-219 (schema)Zod schema defining the input parameters for create_metaobject: type (required), handle (optional), fields (array of {key, value}), and status (ACTIVE/DRAFT, optional).
const createMetaobjectSchema = { type: z .string() .describe( "Type handle from a registered metaobject definition. The definition must already exist; this tool does not create new types/schemas.", ), handle: z .string() .optional() .describe( "Optional URL-safe handle. If the type has a 'displayName' field, Shopify generates a handle from it; otherwise pass one here.", ), fields: z .array(fieldInputSchema) .min(1) .describe( "Field values. Provide at least the required fields from the type's definition. Required fields without values cause a validation error.", ), status: z .enum(["ACTIVE", "DRAFT"]) .optional() .describe( "Publish status. Only applies to types that declared the `publishable` capability — passing this for non-publishable types is silently ignored. ACTIVE = visible on storefront, DRAFT = hidden.", ), }; - src/tools/metaobjects.ts:380-420 (registration)Registration of the create_metaobject tool via server.tool() inside registerMetaobjectTools, which is called from src/server.ts (line 67).
server.tool( "create_metaobject", "Create a new metaobject (instance) of an existing type. The `type` must match a registered metaobject definition — call list_metaobject_definitions first if you're unsure. `fields` is an array of {key, value} pairs; values are always strings (JSON/reference fields take a JSON-encoded string, primitives take literal text). `handle` is optional; Shopify generates one from the displayName field if present. `status` only applies to types that have the `publishable` capability — passing it for non-publishable types is silently ignored. Returns the new metaobject's GID for use in subsequent set_metafield calls (e.g. linking the metaobject to a product via a metaobject_reference metafield).", createMetaobjectSchema, async (args) => { const metaobject: Record<string, unknown> = { type: args.type, fields: args.fields, }; if (args.handle) metaobject.handle = args.handle; if (args.status) { metaobject.capabilities = { publishable: { status: args.status }, }; } const data = await client.graphql<{ metaobjectCreate: { metaobject: MetaobjectNode | null; userErrors: ShopifyUserError[]; }; }>(METAOBJECT_CREATE_MUTATION, { metaobject }); throwIfUserErrors(data.metaobjectCreate.userErrors, "metaobjectCreate"); const m = data.metaobjectCreate.metaobject; if (!m) { return { content: [ { type: "text" as const, text: "metaobjectCreate returned no metaobject." }, ], }; } return { content: [ { type: "text" as const, text: `Created metaobject ${m.displayName ?? m.handle} (${m.type}) — ${m.id}`, }, ], }; }, ); - src/tools/metaobjects.ts:141-152 (helper)Reusable helper schema for a single field input (key + value), used by createMetaobjectSchema's fields array.
const fieldInputSchema = z.object({ key: z .string() .describe( "Field key as declared in the metaobject definition (case-sensitive). Get the list of valid keys from list_metaobject_definitions.", ), value: z .string() .describe( "Field value, always serialized as a string. Primitive types take literal strings ('hello', '42', 'true'). JSON, list, and reference types take JSON-encoded strings (e.g. '\"gid://shopify/Product/123\"' for a product reference, '[1,2,3]' for a list).", ), }); - src/tools/metaobjects.ts:100-114 (helper)GraphQL mutation string used by the create_metaobject handler to call Shopify's metaobjectCreate.
const METAOBJECT_CREATE_MUTATION = /* GraphQL */ ` mutation MetaobjectCreate($metaobject: MetaobjectCreateInput!) { metaobjectCreate(metaobject: $metaobject) { metaobject { id type handle displayName fields { key type value } capabilities { publishable { status } } } userErrors { field message code } } } `;