Back to Docs
MCP

Authentication & Scopes

Personal Access Token format, scope semantics, rate limits, credit charging, error codes, and lifecycle.

Updated 2026-06-10

Personal Access Tokens (PATs)

PATs are long-lived, per-organization bearer tokens. Every MCP request carries one in the Authorization header:

plaintext
Authorization: Bearer vbl_pat_live_<32 urlsafe chars>

Token Format

ComponentExampleMeaning
Prefixvbl_pat_live_Production. Registered with GitHub secret scanning.
Prefixvbl_pat_test_Non-production environments.
Body32 URL-safe characters24 bytes of entropy from secrets.token_urlsafe().

At creation the full token is shown once. Only a SHA256 hash of the raw value is persisted — a stolen database row cannot be replayed as a token.

Lifecycle

Step

Create

Dashboard → Settings → MCP → Create token. Choose a label and scopes. Up to ten active PATs per user per organization.

Step

Rotate

Create a new token, swap your client config over, then revoke the old one. Tokens have no expiry — rotation is entirely on your schedule.

Step

Revoke

Any row in the Settings list can be revoked. Rejection is immediate; in-flight requests that already passed auth complete normally.

Where To Store Tokens

Use one canonical local secret: VAYBEL_PAT.

For Claude Code, prefer storing the token in Claude Code settings so it is available to both the Vaybel MCP server and the official Vaybel Skills plugin:

json
{
  "env": {
    "VAYBEL_PAT": "vbl_pat_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}

Then reference it from MCP config instead of pasting the token into the config file:

json
{
  "mcpServers": {
    "vaybel": {
      "type": "http",
      "url": "https://mcp.vaybel.com/",
      "headers": {
        "Authorization": "Bearer ${VAYBEL_PAT}"
      }
    }
  }
}

Do Not Commit Tokens

Do not put raw vbl_pat_live_... values in project .mcp.json, example repos, screenshots, issue comments, or chat transcripts. Avoid putting long-lived Vaybel tokens in broad shell startup files like .zshrc unless you intentionally want every terminal process to inherit them.

Scopes

Every tool declares the scope(s) it requires. A PAT missing the scope gets a missing_scope tool error. The dashboard token creator selects all public scopes by default — uncheck only what you want to deny. Scopes added to the platform after a token was minted are not retroactively granted: create a fresh token to pick up new scopes.

Read scopes

ScopeTools
brand_dna:readbrand_dna.get, brand_dna.list_audience_presets
catalog:readcatalog.list_blanks
credits:readcredits.check, credits.list_costs, credits.list_usage
design:readdesign.get_generation, design.list, design.get, design.get_history
insight:readinsight.get_overview, insight.list_design_performance, insight.get_guidance (all Growth plan)
mockup:readmockup.get_generation, mockup.list, mockup.get
virtual_model:readvirtual_model.list, virtual_model.get_generation
product_video:readproduct_video.get_generation
listing:readlisting.get, listing.list, listing.get_generation, listing.list_warehouses
content:readcontent.get, content.list
social_post:readsocial_post.get, social_post.list
trend:readtrend.list, trend.get, trend.list_keywords, trend.get_keyword, trend.get_generation, trend.list_seasonal_events
optimize:readoptimize.list_providers, optimize.list_provider_products, optimize.check_duplicate, optimize.get_generation

Write scopes

ScopeTools
brand_dna:writebrand_dna.set
design:writedesign.generate
mockup:writemockup.generate, mockup.update_selection, mockup.submit_feedback, mockup.retry
virtual_model:writevirtual_model.generate
product_video:writeproduct_video.generate
listing:writelisting.create, listing.update, listing.regenerate_field, listing.publish, listing.delete
content:writecontent.generate, content.delete
social_post:writesocial_post.generate, social_post.update, social_post.publish
trend:writetrend.generate_concept, trend.submit_feedback
optimize:writeoptimize.run, optimize.refresh_listing

Principle of Least Privilege

A monitoring agent that polls status doesn't need any :write scope — give it the :read set and nothing more. A trend-discovery agent that proposes drafts can have all reads plus design:write + mockup:write, but not listing:write or content:write. Build narrow tokens.

Plan gates

The MCP surface is a paid capability. Every tool requires Starter or higher, with the Growth-plan feature areas gated at Growth:

TierTools
Open (any plan)ping, credits.check — verify your connection and balance before upgrading
Starter+design.*, mockup.*, virtual_model.*, product_video.* (listing showcase videos), listing.*, trend.*, catalog.*, brand_dna.*, credits.list_costs / list_usage
Growthoptimize.* (AI Product Optimizer), content.* + social_post.* (social videos, slideshows, carousels & publishing), insight.* (Shop Insights)

Gated calls fail with a clear plan_required: ... error rather than returning empty data, so agents can surface the upgrade path. Each tool's tier is shown as a Plan chip in the Tool Reference.

Rate Limits

Rate limits apply per-PAT, per-tool, on a fixed 60-second window. Hitting one raises a rate_limited error carrying a retry after Ns hint.

ToolLimit
design.generate10 / min
mockup.generate20 / min
mockup.update_selection, mockup.submit_feedback60 / min
mockup.retry20 / min
virtual_model.generate10 / min
product_video.generate10 / min
brand_dna.set10 / min
listing.create10 / min
listing.update, listing.delete20 / min
listing.regenerate_field10 / min
listing.publish5 / min
listing.list_warehouses10 / min
content.generate5 / min
content.delete20 / min
social_post.generate10 / min
social_post.publish10 / min
trend.generate_concept10 / min
trend.submit_feedback60 / min
optimize.list_provider_products30 / min
optimize.run10 / min
optimize.refresh_listing20 / min
All other public toolsNo explicit MCP-layer limit (platform-level limits still apply)

Credit balance provides the finer gating for billable tools — you'll hit insufficient_credits before a rate limit on a real workload.

Credit Charging

Most tools are free. A handful charge from the same credit balance your dashboard uses — no separate developer meter.

ToolCostBilled
design.generate10 creditsOn successful completion (failed generations aren't charged)
mockup.generate (quality="pro")2 credits per mockupBy the worker per successful render (failed renders aren't charged)
mockup.generate (quality="standard")Free
virtual_model.generate1 credit per modelAt dispatch
product_video.generate20 credits per videoBy the worker on success
listing.create2 creditsAt dispatch
trend.generate_concept2 credits — only on first dispatchAt dispatch (cached concepts are free)
content.generate (format="video")40 creditsBy the worker on success
content.generate (format="slideshow")12 creditsBy the worker on success
content.generate (format="carousel")4 creditsBy the worker on success
content.generate (format="single")1 creditBy the worker on success

Three pre-flight gates prevent surprises:

  1. Out-of-credit calls fail fast — billable tools run a balance check before dispatching any background work.
  2. Billable tools accept an idempotency_key; sending the same key on a retry returns the cached result, so a flaky-network loop doesn't double-bill (or double-publish).
  3. trend.generate_concept short-circuits to free when the concept is already cached.

Read tools and status polls are always free.

Errors You Might See

Tool errors arrive as MCP tool results (not HTTP status codes — only authentication failures are HTTP 401). Machine-readable errors are prefixed with a stable code:

ErrorCauseFix
HTTP 401 missing bearer tokenNo Authorization headerRe-check your client config; restart after changes
HTTP 401 unknown tokenRevoked or typo'd PATRevoke from Settings, create a fresh one
missing_scope: ...PAT lacks the scope the tool needsRe-create the PAT with the missing scope
rate_limited: ... retry after NsPer-tool per-PAT limit hitWait the indicated seconds; batch where possible
insufficient_credits: requires N, available MBalance below costTop up credits, or use quality="standard" for mockups
plan_required: ...Tool needs a higher plan (trends → Starter+, insights → Growth)Upgrade the org's plan
not_found: ...Unknown id — or a UUID belonging to another orgEach PAT is pinned to one org; re-check the id
budget_exceeded: ...Session budget cap reached (internal session tokens)Raise the session budget

Errors without a code prefix are plain validation messages (e.g. prompt is required).