plugin.market

API & MCP docs

Everything the marketplace shows is available programmatically: a read-only REST API for scripts and services, and an MCP endpoint so agents can search the registry directly.

Overview

  • Base URL — the API lives on the same origin as this site; all paths below are relative. The curl examples use https://plugin.market — swap in your own origin if you self-host.
  • No auth, no rate limits yet — every endpoint is public and read-only. Be reasonable; limits may come later.
  • CORS — every response sends Access-Control-Allow-Origin: *, so you can call the API from browser code. Responses are cacheable for 60 seconds.
  • Errors — JSON body { "error": { "code", "message" } } with status 400 or 404. Unlike the web UI, which ignores invalid filter values, the API rejects them with 400 bad_request naming the valid values.
  • Dates — all timestamps are ISO 8601 strings (JSON Schema format date-time).
  • OpenAPI — a machine-readable OpenAPI 3.1 description is served at /api/openapi.json.

Indexed content (names, descriptions, manifests, URLs) comes from third-party GitHub repositories. Treat it as untrusted input in your own applications.

/api/v1/plugins

List plugins

GET/api/v1/plugins

Paginated plugin summaries. All parameters are optional; filters combine with AND.

Query parameters

ParamTypeDescription
qstringFree-text query over name, description, keywords, and author (max 200 chars).
categorystringExact keyword match. Categories are manifest keywords — see /api/v1/categories.
typeskills | mcpOnly plugins containing this component type.
transportstdio | streamable-http | sseOnly plugins with at least one MCP server using this transport.
sortstars | updated | recentstars = repo stars (default), updated = repo push date, recent = first indexed.
pageinteger1-based page number. Clamped to >= 1. Default 1.
per_pageintegerResults per page, clamped to 1..50. Default 24.

An unknown value for type, transport, or sort returns 400 bad_request listing the valid values.

Example request

curl "https://plugin.market/api/v1/plugins?q=github&type=mcp&sort=stars&per_page=1"

Example response

{
  "data": [
    {
      "slug": "acme-github-tools",
      "name": "github-tools",
      "version": "1.2.0",
      "description": "Skills and an MCP server for triaging GitHub issues.",
      "authorName": "Acme Labs",
      "license": "MIT",
      "keywords": ["github", "issues", "automation"],
      "repoUrl": "https://github.com/acme/github-tools",
      "repoStars": 412,
      "skillCount": 3,
      "mcpCount": 1,
      "transports": ["stdio"],
      "indexedAt": "2026-08-07T09:14:00.000Z"
    }
  ],
  "meta": { "page": 1, "per_page": 1, "total": 42, "total_pages": 42 }
}
/api/v1/plugins/{slug}

Get a plugin

GET/api/v1/plugins/{slug}

Full detail for one plugin: every summary field plus homepage, repository, plugin path, the raw manifest, skills, and MCP server configs. Returns 404 not_found for unknown slugs.

Path parameters

ParamTypeDescription
slugstringRegistry slug, as returned by the list endpoint.

Example request

curl https://plugin.market/api/v1/plugins/acme-github-tools

Example response

{
  "data": {
    "slug": "acme-github-tools",
    "name": "github-tools",
    "version": "1.2.0",
    "description": "Skills and an MCP server for triaging GitHub issues.",
    "authorName": "Acme Labs",
    "license": "MIT",
    "keywords": ["github", "issues", "automation"],
    "repoUrl": "https://github.com/acme/github-tools",
    "repoStars": 412,
    "skillCount": 3,
    "mcpCount": 1,
    "transports": ["stdio"],
    "indexedAt": "2026-08-07T09:14:00.000Z",
    "homepage": "https://acme.dev/github-tools",
    "repository": "https://github.com/acme/github-tools",
    "pluginPath": "plugins/github-tools",
    "repoPushedAt": "2026-08-05T17:42:11.000Z",
    "manifest": "{ \"name\": \"github-tools\", \"version\": \"1.2.0\", … }",
    "skills": [
      {
        "dirName": "triage-issue",
        "name": "triage-issue",
        "description": "Label and route a new GitHub issue."
      }
    ],
    "mcpServers": [
      {
        "serverId": "github",
        "transport": "stdio",
        "config": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "@acme/github-mcp"]
        }
      }
    ]
  }
}

Not found

{
  "error": { "code": "not_found", "message": "No plugin with slug \"nope\"." }
}
/api/v1/stats

Stats

GET/api/v1/stats

Registry totals: indexed plugins, skills, MCP servers, and distinct categories.

Example request

curl https://plugin.market/api/v1/stats

Example response

{
  "data": { "plugins": 137, "skills": 402, "mcpServers": 168, "categories": 54 }
}
/api/v1/categories

Categories

GET/api/v1/categories

Categories are derived from manifest keywords, lowercased and ranked by how many plugins carry them (top 100). Use a category name as the category filter on the list endpoint.

Example request

curl https://plugin.market/api/v1/categories

Example response

{
  "data": [
    { "name": "github", "count": 21 },
    { "name": "productivity", "count": 17 },
    { "name": "search", "count": 12 }
  ]
}
/api/mcp

MCP endpoint

POST/api/mcp

The registry is also an MCP server, so agents can search it as a tool. Transport is streamable-http and the server is stateless: each POST carries one JSON-RPC 2.0 message, there are no sessions, and the protocol version is 2025-06-18. No authentication.

Connect a client

Add the endpoint to your client's mcp.json:

{
  "mcpServers": {
    "plugin-market": {
      "type": "streamable-http",
      "url": "https://plugin.market/api/mcp"
    }
  }
}

Tools

ToolArgumentsDescription
search_pluginsquery?, category?, type? (skills | mcp), transport? (stdio | streamable-http | sse), sort? (stars | updated | recent), page?, per_page?Search the plugin index. Same filter semantics and clamping as GET /api/v1/plugins; the result JSON is paginated as items, total, page, perPage, totalPages.
get_pluginslug (required)Full detail for one plugin, like GET /api/v1/plugins/{slug}.
get_statsnoneRegistry totals, like GET /api/v1/stats.

Example: initialize

curl -X POST https://plugin.market/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "curl", "version": "0.0.0" }
    }
  }'

Example: call search_plugins

curl -X POST https://plugin.market/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "search_plugins",
      "arguments": { "query": "github", "type": "mcp", "per_page": 5 }
    }
  }'