Skip to main content
Glama

create_product

Idempotent

Create a new product listing on Partle.

Authenticated. Prefer **OAuth**: connect once via the consent flow on
claude.ai (or any MCP client that supports OAuth) and the bearer token
is attached automatically — no `api_key` parameter needed. **Fallback**:
pass an `api_key` (prefix `pk_`, generate at /account) for programmatic
or non-OAuth clients.

Required OAuth scope: `products:write`.

Use when the user wants to add an item for sale. For edits to an
existing product, use `update_product` instead.

**Images.** This tool creates text fields only — no image arg. Do
**not** try to pass image bytes through a tool argument; phone-sized
payloads blow past conversation context limits.

The response includes a one-shot ``upload_url`` (signed, ~15 min TTL,
bound to this product and your authenticated user). To attach an
image from your code-execution sandbox, do **one** PUT request — no
auth headers needed, the URL itself carries the credential:

  requests.put(result["upload_url"],
               data=open("/path/to/photo.jpg", "rb").read(),
               headers={"Content-Type": "image/jpeg"})

The bytes flow Python → HTTP body → Partle, never through the
conversation. The URL works once and expires fast.

Alternative if you don't have local bytes but have a public image URL:
call ``upload_product_image(product_id, image_url=...)`` instead.

**Duplicate prevention.** Same user, same product name (case- and
whitespace-insensitive) returns 409 with `existing.id`, `existing.url`,
**and a fresh `upload_url`** for that existing product — so if the
user is just retrying with a photo, you can attach it directly to the
existing listing without having to create or pick anything new. You
can also call `update_product` to change fields. Don't retry blindly.

**Idempotency.** Pass `idempotency_key` (any unique string per logical
create — UUID or hash of the source listing) and a retry after a
network failure returns the original response instead of creating a
duplicate. Reusing a key with a different payload is a 422.

Args:
    name: Product name. Required, 1–200 chars.
    description: Long-form product description. Optional.
    price: Price in whole currency units, **not** cents (e.g. ``15.99``
        means €15.99). Max 100000. Omit for "ask the seller".
    currency: Currency symbol. Defaults to `€`. Use `$`, `£`, etc.
    url: Link to the merchant's product page. Optional but recommended.
    store_id: ID of the store this product belongs to. Omit for a
        personal listing not tied to any store.
    listing_type: ``in_stock`` (default) when the seller has the item
        and it can be bought now. ``tentative`` when they do not stock
        it and want to measure interest first — such a listing is kept
        out of normal search results and instead collects "I need this"
        presses. Only use ``tentative`` if the user explicitly said they
        are gauging demand; an item that is merely out of stock today is
        still ``in_stock``. If the user is looking to *buy* something
        nobody sells, use `create_buy_request` instead — that is the
        demand side and it is a different tool.
    idempotency_key: Optional retry-safety token. Unique per logical
        create. Send the same key on retries to get the same response.
    api_key: Optional API key (`pk_*`, generate at /account).
        Used when there is no OAuth token, and also when the OAuth
        token lacks the required scope — an explicitly passed key
        overrides an ambient token that is scoped too narrowly.
        An invalid or revoked token still fails regardless. Omit when using OAuth.

Returns:
    The created product record including its new `id` and canonical
    `partle_url`. Share `partle_url` with the user. Returns
    ``{"error": ...}`` on auth, dedup, or validation failure (dedup
    also returns ``{"existing": {"id", "name", "url"}}``).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlNo
nameYes
priceNo
api_keyNo
currencyNo
store_idNo
descriptionNo
listing_typeNoin_stock
idempotency_keyNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / listing_type
      Added value: +{
      +  "default": "in_stock",
      +  "title": "Listing Type",
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • removedInput schema / properties / image_base64
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "title": "Image Base64"
      -}
  3. Changed2 schema fields changed
    • addedInput schema / properties / idempotency_key
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Idempotency Key"
      +}
    • addedInput schema / properties / image_base64
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Image Base64"
      +}
  4. Changed4 schema fields changed
    • addedInput schema / properties / api_key / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / api_key / default
      Added value: +null
    • removedInput schema / properties / api_key / type
      Removed value: -"string"
    • changedInput schema / required
      Previous value: -[
      -  "api_key",
      -  "name"
      -]New value: +[
      +  "name"
      +]
  5. First observed

TDQS

A4.9/5.0
Behavior5/5

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

The description goes far beyond the annotations. It explains the image upload mechanism (separate upload_url, PUT request, not through conversation), duplicate prevention (409 with existing.id and fresh upload_url), idempotency (idempotency_key behavior), listing_type semantics (in_stock vs tentative vs create_buy_request), and api_key override behavior. It also describes the response format and error handling. Annotations already provide idempotentHint=true and readOnlyHint=false, and the description fully aligns and adds rich context.

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

Conciseness4/5

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

The description is long but well-structured with section headers and bold text. It is front-loaded with the purpose. Every sentence adds value, and for a tool with 9 parameters plus complex behaviors, the length is justified. It could be slightly more concise, but it earns its place.

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 (9 parameters, no output schema, complex auth, image upload, dedup, idempotency), the description covers all aspects. It explains the return value, error handling, provides a code example for image upload, and mentions alternative tools. It is fully self-contained and complete.

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 description coverage is 0%, so the description must fully compensate, and it does. Every parameter is explained with constraints, defaults, and usage notes. For example, price: 'Price in whole currency units, not cents (e.g. 15.99 means €15.99). Max 100000. Omit for ask the seller.' listing_type: detailed explanation of in_stock vs tentative. idempotency_key: purpose and uniqueness. api_key: override behavior. This is exemplary.

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 starts with a clear verb-resource-platform statement: 'Create a new product listing on Partle.' It explicitly distinguishes from sibling tools: 'For edits to an existing product, use update_product instead' and 'If the user is looking to buy something nobody sells, use create_buy_request instead.' This provides excellent purpose clarity.

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?

The description explicitly states when to use: 'Use when the user wants to add an item for sale.' It gives clear alternatives for edits (update_product), demand-side (create_buy_request), and image upload (upload_product_image). It also includes authentication guidance (OAuth vs api_key) and scope requirements. No gaps.

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