Marketplace V2 — find sections by intent
The classic content_list_marketplace_components filters by category (hero, features, pricing, …). Marketplace V2 turns the same catalog into something an agent searches by what they actually want — "calm cinematic for a luxury hotel," "energetic conversion-focused for ecommerce" — across all three marketplace tables (bg-videos / components / site-templates) in one query.
Live since 2026-05-05. Available in @spideriq/cli@1.5.0+, @spideriq/mcp-publish@1.5.0+, and the public Starter Kit.
Why this exists
Categories tell you the shape ("it's a hero"); they don't tell you whether the hero matches a luxury hotel brief or a fintech dashboard brief. Four universal axes do:
| Axis | Vocabulary (subset) | What it picks |
|---|---|---|
mood | calm, energetic, bold, dreamy, futuristic, urban, minimal, warm, editorial, professional, friendly, clear, technical, credible | The emotional register |
palette | monochrome, deep-blue, cream, neutral-warm, nature-green, neon-accent, cinematic | The visual signature |
brand_fit_tags | saas, agency, ecommerce, fintech, hospitality, restaurant, wellness, blog, publication, real-estate | The industry vertical |
scene_type | hero-bold, conversion-cta, social-proof (components); city-aerial, nature-landscape (bg-videos); marketing-site, docs-site (site-templates) | The semantic shape |
marketplace_search matches any-of within an axis ("mood includes calm OR editorial") and and-of across axes ("calm-mood AND saas-brand-fit"). For tighter narrowing, pass single values per axis.
Quick start — find a calm bg-video, insert it as hero
# 1. Search
spideriq marketplace search --mood calm --asset-types bg_video --limit 5
# → results: [{
# slug: "alpine-wildflowers",
# asset_type: "bg_video",
# video_url: "https://media.cdn.spideriq.ai/bg-videos/alpine-wildflowers.mp4",
# mood: ["calm","dreamy"],
# scene_type: "nature-landscape",
# ...
# }, ...]
# 2. Insert as the first block on the homepage
spideriq content insert-section \
--page-id <homepage-uuid> \
--component-slug sys-bg-video \
--props '{"video_slug": "alpine-wildflowers"}' \
--position start \
--confirm
Same flow via MCP (marketplace_search → content_insert_section) — see the Starter Kit recipe for the full preview-token + confirm dance.
The 6 Marketplace V2 tools
Available in CLI (spideriq marketplace …), MCP (@spideriq/mcp-publish), opvsHUB skill (content-platform v1.6.0+), and the public Starter Kit.
| Tool | Auth | Use case |
|---|---|---|
marketplace_search | public | Cross-table discovery by mood / palette / brand_fit / scene_type / agent_meta / asset_types |
list_data_sources | public | Discover internal source IDs for binding kind="dynamic" blocks (posts, authors, IDAP×4, idap.lead) |
set_component_kind | gated | Promote a custom component into the 4-class taxonomy (static / interactive / dynamic / extension) |
set_component_agent_meta | gated | Curate axes + ComponentAgentMeta on a component so other agents can find it |
set_bg_video_agent_meta | super_admin, gated | Curate bg-video discoverability (pace, time_of_day, weather, aspect_ratio, …) |
set_site_template_agent_meta | super_admin, gated | Curate site-template discoverability (page_count, has_blog, style_aesthetic, …) |
All four destructive set_* tools default dry_run=true — first call returns a preview envelope with confirm_token; second call (same args + confirm_token) actually mutates. See Deploy safely for the broader two-step flow.
The 4-class component taxonomy
marketplace_search filters across three asset tables, but components themselves split into four behavioural classes:
| Kind | Props? | Reads data? | Renders where? | Needs secrets? | Examples |
|---|---|---|---|---|---|
static | ✓ | – | component HTML | no | hero-headline, faq-accordion, pricing-3tier (44 existing) |
interactive | ✓ | – | component HTML + JS | no | sys-timer-fixed-date, sys-popup-exit-intent, sys-bar-promo |
dynamic | ✓ | ✓ | component HTML + fetch | no | List of posts, Item Details for IDAP business, sys-proof-recent-purchase |
extension | ✓ | ✓ | renderer / worker / hook | YES | sys-tracking-fb-capi, sys-geo-md-mirror, sys-geo-mcp-server |
Use set_component_kind to promote a custom component into the taxonomy. The kind drives the renderer (whether to fetch data, whether to ship JS, whether to require a worker route).
Per-asset agent_meta
Beyond the 4 universal axes, each table has its own JSONB agent_meta with extra filters:
# Calm bg-video, slow pace, night scene, no people
spideriq marketplace search \
--mood calm \
--asset-types bg_video \
--agent-meta '{"pace": "slow", "time_of_day": "night", "has_people": false}'
The full vocabulary lives in template_get_help (or GET /content/help) — search for BgVideoAgentMeta / ComponentAgentMeta / SiteTemplateAgentMeta.
BgVideoAgentMeta keys (subset)
pace, time_of_day, weather, has_people, aspect_ratio, has_audio, music_tempo_bpm, transcript
ComponentAgentMeta keys (subset)
interaction_pattern, trigger_kind, placement, motion_safety, accessibility_notes, conversion_strategy
SiteTemplateAgentMeta keys (subset)
page_count, has_blog, has_pricing, has_directory, has_booking, conversion_strategy, style_aesthetic, component_set
Anti-patterns
- Don't bind
idap.leadto a List block — it's a singleton (is_collection=false); only Item Details accepts it. - Don't pass
moodas a comma-string in the JSON body — it'sstring[]. The CLI accepts--mood calm,editorial, the API expects["calm","editorial"]. agent_metaisextra="forbid"— typos return 422. Usetemplate_get_helpif a key isn't in the table above.- Universal axes are NOT inside
agent_meta—mood/palette/brand_fit_tags/scene_typeare sibling top-level fields. Putting them insideagent_metasilently no-ops.
Internal data sources (for kind=dynamic components)
The 9 sources currently exposed via list_data_sources:
| Source ID | Shape | Notes |
|---|---|---|
posts | collection | Blog posts (status=published, ordered by published_at desc) |
authors | collection | Author profiles (active=true) |
categories | collection | Blog categories (hierarchical) |
tags | collection | Tags with post counts |
idap.countries | collection | IDAP geo — countries |
idap.cities | collection | IDAP geo — cities (parent: countries) |
idap.streets | collection | IDAP geo — streets (parent: cities) |
idap.businesses | collection | IDAP geo — businesses (parent: streets) |
idap.lead | singleton | Per-request lead (request-scoped, not a collection) |
Bind a List or Item Details component to any of these via block.data_binding:
{
"type": "component",
"component_slug": "list",
"layout": "stacked",
"data_binding": {
"source_id": "posts",
"filter": { "category": "tutorials" },
"sort": "-published_at",
"limit": 10,
"field_select": ["title", "excerpt", "cover_image"]
}
}
External connectors (Airtable, Postgres, custom URLs) plug into the same content_data_sources registry shape — deferred to a future initiative.
Coverage caveat
The seed migration (178) backfilled best-guess universal-axis defaults from the legacy marketplace_category field. agent_meta (the per-type keys above) is sparse on existing assets as of 2026-05-05. Search recall today is bounded by what's in the DB.
A "Fill the Bank" initiative is in flight to populate agent_meta on every existing asset via SpiderGate-powered inference + a Suggest agent_meta button in the dashboard editors + a CLI/MCP marketplace_suggest_agent_meta tool. Until that ships, narrow your search to universal axes for best results, and ask template_get_help to see which agent_meta keys are populated for the asset type you're searching.
See also
- Starter Kit recipe — runnable end-to-end with auth + page lookup
- agents.mdx — full agent integration guide (
@spideriq/cli,@spideriq/mcp-publish) - deploy-safely.mdx — preview → confirm pattern that gates every destructive
set_*tool - sessions.mdx — Phase 11+12 multi-tenant session binding
template_get_help(orGET /api/v1/content/help?format=yaml) — canonical vocabulary reference