Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ Thanks for adding to the Cline Marketplace. Each contribution is a single new fo
Store the tokens exactly as a user would type them after the subcommand. The verb comes from `type`, so you never repeat `cline ... install` in the entry.

- plugin: `["goal"]`
- skill: `["owner/repo", "--skill", "name"]`
- skill (whole repo): `["owner/repo"]`
- skill (one skill from a repo): `["owner/repo", "--skill", "name"]`
- mcp (remote, OAuth): `["name", "--transport", "http", "https://host/mcp"]`
- mcp (remote, static header): `["name", "--transport", "http", "https://host/mcp", "--header", "Authorization: Bearer <token>"]`
- mcp (stdio): `["name", "--", "npx", "-y", "some-mcp-server"]`
Expand All @@ -51,7 +52,7 @@ If your entry needs a category that does not exist yet, add it to `tags.json` in
{ "id": "devops", "label": "DevOps" }
```

Order in `tags.json` is the display order in the website filter, so place new tags thoughtfully.
Order in `tags.json` is the display order for a filter UI, so place new tags thoughtfully.

## Review bar

Expand Down
174 changes: 101 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,144 @@
# Cline Marketplace

A curated catalog of high quality primitives for Cline: **plugins**, **skills**, and **MCP servers**. Each entry carries the metadata our website needs to display it, plus the exact one liner that installs it with the Cline CLI.
A curated catalog of high quality primitives for Cline: **plugins**, **skills**, and **MCP servers**. Each entry carries the metadata needed to display it, plus the exact one liner that installs it with the Cline CLI.

The published catalog is a single JSON file the website fetches at runtime:
This repo is data only (no UI). It is the source of truth for entries and the pipeline that publishes them as a single JSON file that any client can fetch.

```
https://cline.github.io/marketplace/catalog.json
```

## What this repo is (and is not)

This repo is **data only**. It is the source of truth for catalog entries plus the pipeline that publishes them. It contains **no UI**.

GitHub Pages here serves static files and nothing else:
## Catalog URL

- `https://cline.github.io/marketplace/catalog.json` the catalog
- `https://cline.github.io/marketplace/icons/...` the icon assets referenced by absolute URL in the JSON

The marketplace UI lives in a **separate project** (the Cline web app). It just fetches `catalog.json` and renders whatever it wants. The only coupling between the two is the JSON contract below.

Notes for the consuming app:

- **CORS works.** GitHub Pages sends `Access-Control-Allow-Origin: *`, so a browser `fetch` from any origin works without a proxy.
- **It is CDN cached** (Pages sits behind Fastly, roughly 10 minutes). Fine for a listing. If the app wants fresher data or no runtime dependency on GitHub, it can pull `catalog.json` at its own build or deploy time and bake it in. Nothing changes on this side.
- **The shape is stable.** Top level `version`, `generatedAt`, `counts`, `tags[]`, `entries[]`. The `tags[]` array is the full filter vocabulary with counts. Each entry exposes `tags` (filter), `install.command` (ready to display), and `install.args` / `install.env` (structured, if the app wants to build its own install UI).

## How it works
The published catalog is one JSON file that can be fetched by any client:

- **Source of truth** is one folder per entry under `registry/<type>/<slug>/entry.json`. Concurrent additions never conflict, and every entry is reviewed on its own.
- **CI generates** `dist/catalog.json` from those folders, validates them against the schemas, copies icons, and stamps a version and timestamp.
- **CI publishes** the generated catalog to GitHub Pages on every merge to `main`.

```
registry/
plugins/<slug>/entry.json (+ icon.svg)
skills/<slug>/entry.json
mcps/<slug>/entry.json
schemas/
common.schema.json shared fields + install block
plugin.schema.json | skill.schema.json | mcp.schema.json
scripts/generate.mjs validate + build dist/catalog.json
```

## The install model

Every entry stores the argv that comes after `cline <type> install`. The verb is derived from `type`, and the generator renders the full command for the website.

| Type | Verb | `install.args` example | Rendered command |
| --- | --- | --- | --- |
| `plugin` | `cline plugin install` | `["goal"]` | `cline plugin install goal` |
| `skill` | `cline skill install` | `["vercel-labs/agent-skills", "--skill", "web-design-guidelines"]` | `cline skill install vercel-labs/agent-skills --skill web-design-guidelines` |
| `mcp` | `cline mcp install` | `["context7", "--transport", "http", "https://mcp.context7.com/mcp"]` | `cline mcp install context7 --transport http https://mcp.context7.com/mcp` |

Secrets and environment variables that are not part of the command (for example `EXA_API_KEY`) go in `install.env` so the website can prompt for them.

## Tags

There is a single canonical tag vocabulary in [`tags.json`](./tags.json). Every entry's `tags` array must use only the `id`s from that file (lowercase), and each entry needs at least one tag. The build fails on an unknown tag, so the vocabulary stays the single source of truth.

```json
{ "id": "productivity", "label": "Productivity" }
https://cline.github.io/marketplace/catalog.json
```

The generator publishes the full vocabulary into `catalog.json` as a top-level `tags` array, each with a `count` of how many entries use it, in `tags.json` order. The website filter component can render this list directly (and grey out or hide `count: 0` tags as it likes) without scanning every entry.

```json
"tags": [
{ "id": "productivity", "label": "Productivity", "count": 1 },
{ "id": "software", "label": "Software", "count": 3 }
]
```js
const catalog = await fetch("https://cline.github.io/marketplace/catalog.json").then((r) => r.json());
```

To add a new category, add an entry to `tags.json`. Order in that file defines display order in the filter.

## Published catalog shape
## Catalog format

```json
{
"version": 1,
"generatedAt": "2026-06-16T00:00:00.000Z",
"baseUrl": "https://cline.github.io/marketplace",
"counts": { "total": 3, "plugins": 1, "skills": 1, "mcps": 1 },
"counts": { "total": 5, "plugins": 2, "skills": 2, "mcps": 1 },
"tags": [
{ "id": "productivity", "label": "Productivity", "count": 1 },
{ "id": "software", "label": "Software", "count": 3 }
{ "id": "software", "label": "Software Development", "count": 4 },
{ "id": "research", "label": "Research & Docs", "count": 3 }
],
"entries": [
{
"id": "context7",
"type": "mcp",
"name": "Context7",
"tagline": "Up-to-date code docs for any library, fetched on demand",
"description": "A remote MCP server that pulls version-accurate docs into context.",
"author": { "name": "Upstash", "url": "https://upstash.com" },
"homepage": "https://context7.com",
"repo": "https://github.com/upstash/context7",
"icon": "https://cline.github.io/marketplace/icons/mcp/context7.svg",
"tags": ["software", "research"],
"license": "MIT",
"verified": false,
"featured": true,
"install": {
"args": ["context7", "--transport", "http", "https://mcp.context7.com/mcp"],
"command": "cline mcp install context7 --transport http https://mcp.context7.com/mcp"
"command": "cline mcp install context7 --transport http https://mcp.context7.com/mcp",
"env": [
{ "name": "CONTEXT7_API_KEY", "required": false, "description": "Higher rate limits", "url": "https://context7.com/dashboard" }
]
}
}
]
}
```

## Contributing
Top level: `version`, `generatedAt`, `baseUrl`, `counts`, `tags[]` (full filter vocabulary with counts), and `entries[]`. Each entry exposes `tags` (filter), `icon` (absolute URL), `install.command` (ready to display), and `install.args` / `install.env` (structured, if a client builds its own install UI).

## Entries

Each entry is one folder under `registry/<type>/<slug>/entry.json`, where `<type>` is `plugins`, `skills`, or `mcps`. The folder name is the entry `id`. Co-located assets (like `icon.svg`) live next to `entry.json`. This keeps every entry independently reviewable and avoids merge conflicts when many are added at once.

## Install commands

See [CONTRIBUTING.md](./CONTRIBUTING.md). Validate locally before opening a PR:
Every entry stores the argv that comes after `cline <type> install`. The verb is derived from `type`, and the generator renders the full `install.command` for any client to display.

| Type | Verb | `install.args` example | Rendered command |
| --- | --- | --- | --- |
| `plugin` | `cline plugin install` | `["goal"]` | `cline plugin install goal` |
| `skill` | `cline skill install` | `["cline/sdk-skill"]` | `cline skill install cline/sdk-skill` |
| `skill` | `cline skill install` | `["vercel-labs/agent-skills", "--skill", "web-design-guidelines"]` | `cline skill install vercel-labs/agent-skills --skill web-design-guidelines` |
| `mcp` | `cline mcp install` | `["context7", "--transport", "http", "https://mcp.context7.com/mcp"]` | `cline mcp install context7 --transport http https://mcp.context7.com/mcp` |

Skills resolve sources the same way `npx skills add` does (`cline skill install` aliases it): pass `owner/repo` to install a whole repo, or add `--skill <name>` to pick one skill from a multi-skill repo.

Secrets and environment variables that are not part of the command (for example `EXA_API_KEY`) go in `install.env` so a client can prompt for them.

## Icons

Icons are published per entry. Every entry's `icon` field in `catalog.json` is already the absolute URL, so a client renders `entry.icon` directly and never has to build a URL. The underlying pattern is:

```
https://cline.github.io/marketplace/icons/<type>/<slug>.<ext>
```

`<type>` is singular (`plugin`, `skill`, `mcp`), `<slug>` is the entry id, `<ext>` is whatever the source icon used (usually `svg`). Current examples:

| Entry | Type | Icon URL |
| --- | --- | --- |
| `goal` | plugin | `https://cline.github.io/marketplace/icons/plugin/goal.svg` |
| `web-search` | plugin | `https://cline.github.io/marketplace/icons/plugin/web-search.svg` |
| `cline-sdk` | skill | `https://cline.github.io/marketplace/icons/skill/cline-sdk.svg` |
| `web-design-guidelines` | skill | `https://cline.github.io/marketplace/icons/skill/web-design-guidelines.svg` |
| `context7` | mcp | `https://cline.github.io/marketplace/icons/mcp/context7.svg` |

The `baseUrl` field at the top of `catalog.json` always tells a client which host the icons resolve against, so the host is never hardcoded on the consuming side.

## Tags

A single canonical tag vocabulary lives in [`tags.json`](./tags.json). Every entry's `tags` array must use only the `id`s from that file (lowercase), and each entry needs at least one tag. The build fails on an unknown tag, so the vocabulary stays the single source of truth.

```json
{ "id": "data", "label": "Data & Analytics" }
```

The generator publishes the full vocabulary into `catalog.json` as a top-level `tags` array, each with a `count` of how many entries use it, in `tags.json` order. A filter UI can render this list directly (and grey out or hide `count: 0` tags). To add a category, add it to `tags.json`; order there is the display order.

## How it works

- **Source of truth** is one folder per entry under `registry/`, validated against the schemas in `schemas/` and the tag vocabulary in `tags.json`.
- **`scripts/generate.mjs`** validates every entry, renders each `install.command`, copies icons, rewrites icon URLs to absolute, and writes `dist/catalog.json`. It has zero dependencies so CI runs it without an install step.
- **CI validates** on every PR and **publishes** `dist/` (the catalog plus icons) to GitHub Pages on merge to `main`.

Hosting facts for consumers:

- **Static + CORS open.** Pages serves static files and sends `Access-Control-Allow-Origin: *`, so a browser `fetch` from any origin works without a proxy.
- **CDN cached** (Pages sits behind Fastly, roughly 10 minutes). For fresher data or no runtime dependency on GitHub, a client can fetch `catalog.json` at its own build or deploy time and bake it in.
- **Custom domain:** set the `MARKETPLACE_BASE_URL` repo variable and the generator rewrites `baseUrl` and every icon URL to it. Paths stay the same; only the host changes.

```
registry/
plugins/<slug>/entry.json (+ icon.svg)
skills/<slug>/entry.json
mcps/<slug>/entry.json
schemas/
common.schema.json shared fields + install block
plugin.schema.json | skill.schema.json | mcp.schema.json
tags.json canonical tag vocabulary
scripts/generate.mjs validate + build dist/catalog.json
```

## Local development

```bash
npm run validate # validate every entry against the schemas
npm run generate # also write dist/catalog.json to inspect the output
npm run validate # validate every entry (used in CI on PRs)
npm run generate # also write dist/catalog.json + dist/icons to inspect output
```

See [CONTRIBUTING.md](./CONTRIBUTING.md) to add an entry.

## License

[Apache 2.0 (c) 2026 Cline Bot Inc.](./LICENSE)
19 changes: 19 additions & 0 deletions registry/skills/cline-sdk/entry.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "../../../schemas/skill.schema.json",
"id": "cline-sdk",
"type": "skill",
"name": "Cline SDK",
"tagline": "Cline SDK reference docs for AI coding assistants",
"description": "Reference documentation for the Cline SDK: the Agent runtime, ClineCore sessions, custom tools, plugins, events, LLM providers, scheduling, multi-agent teams, and production deployment. Installs the whole skill from its GitHub repo.",
"author": { "name": "Cline", "url": "https://cline.bot" },
"homepage": "https://docs.cline.bot/sdk",
"repo": "https://github.com/cline/sdk-skill",
"icon": "./icon.svg",
"tags": ["software", "research"],
"license": "Apache-2.0",
"verified": true,
"featured": false,
"install": {
"args": ["cline/sdk-skill"]
}
}
1 change: 1 addition & 0 deletions registry/skills/cline-sdk/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading