Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Langgenius Dify Marketplace Contracts

From Leeroopedia
Knowledge Sources Dify
Domains Plugin_System, Marketplace, Frontend
Last Updated 2026-02-12 00:00 GMT

Overview

Description

The Marketplace Contracts module defines three oRPC typed contracts that form the complete API surface for plugin and bundle discovery against the Dify Marketplace. Each contract specifies its HTTP route, method, input type, and output type using the @orpc/contract library's type<T>() utility, producing zero-runtime-overhead type constraints that are enforced at compile time.

The three contracts are:

  • collectionsContract -- Lists marketplace collections with optional search and pagination.
  • collectionPluginsContract -- Retrieves plugins within a specific collection by collectionId.
  • searchAdvancedContract -- Performs advanced search across plugins or bundles with full filtering capabilities.

All contracts extend a shared base contract imported from web/contract/base.ts, which provides the marketplace base URL and common configuration.

Usage

These contracts are consumed by the React Query hooks in web/service/use-plugins.ts and by direct marketplace API calls. The contracts serve as the type-safe interface layer between the frontend and the marketplace backend.

Code Reference

Source Location

web/contract/marketplace.ts (Lines 6--56)

Signature

export const collectionsContract = base
  .route({ path: '/collections', method: 'GET' })
  .input(
    type<{
      query?: CollectionsAndPluginsSearchParams & { page?: number; page_size?: number }
    }>(),
  )
  .output(
    type<{
      data?: { collections?: MarketplaceCollection[] }
    }>(),
  )

export const collectionPluginsContract = base
  .route({ path: '/collections/{collectionId}/plugins', method: 'POST' })
  .input(
    type<{
      params: { collectionId: string }
      body?: CollectionsAndPluginsSearchParams
    }>(),
  )
  .output(
    type<{
      data?: { plugins?: Plugin[] }
    }>(),
  )

export const searchAdvancedContract = base
  .route({ path: '/{kind}/search/advanced', method: 'POST' })
  .input(
    type<{
      params: { kind: 'plugins' | 'bundles' }
      body: Omit<PluginsSearchParams, 'type'>
    }>(),
  )
  .output(type<{ data: PluginsFromMarketplaceResponse }>())

Import

import { collectionsContract, collectionPluginsContract, searchAdvancedContract } from '@/contract/marketplace'

I/O Contract

collectionsContract

Direction Field Type Description
Input query CollectionsAndPluginsSearchParams & { page?: number; page_size?: number } Optional search parameters and pagination
Output data.collections MarketplaceCollection[] Array of curated marketplace collections

collectionPluginsContract

Direction Field Type Description
Input params.collectionId string The unique identifier of the collection
Input body CollectionsAndPluginsSearchParams Optional search/filter parameters
Output data.plugins Plugin[] Array of plugins belonging to the collection

searchAdvancedContract

Direction Field Type Description
Input params.kind 'bundles' The type of resource to search
Input body Omit<PluginsSearchParams, 'type'> Search parameters (query, sort_by, sort_order, category, tags, exclude, page, page_size)
Output data PluginsFromMarketplaceResponse Search results with plugins/bundles and pagination metadata

Usage Examples

Browsing marketplace collections

// The collectionsContract is consumed by hooks that fetch paginated collections
const { data } = useQuery({
  queryKey: ['marketplace', 'collections'],
  queryFn: () => getMarketplace<{ data: { collections: MarketplaceCollection[] } }>(
    '/collections',
    { params: { page: 1, page_size: 20 } }
  ),
})

Searching for plugins with advanced filters

// The searchAdvancedContract types the advanced search mutation
const { mutateAsync } = useMutationPluginsFromMarketplace()
const results = await mutateAsync({
  query: 'openai',
  sort_by: 'install_count',
  sort_order: 'desc',
  category: 'model',
  tags: ['llm'],
  page: 1,
  page_size: 40,
  type: 'plugin',
})

Fetching plugins in a specific collection

// The collectionPluginsContract types the collection plugins endpoint
const response = await postMarketplace<{ data: { plugins: Plugin[] } }>(
  `/collections/${collectionId}/plugins`,
  { body: { limit: 15 } }
)

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment