From 45024f624439efea39ef65e3dc5c226bb97307ed Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 11:34:24 -0500 Subject: [PATCH 1/9] feat: prepare MCP server as stdio-only npm package Remove HTTP transport in favor of stdio-only for npm distribution. Migrate from deprecated server.tool() to server.registerTool(), bump SDK to ^1.26.0, and add bin/files/metadata for npm publishing. Co-Authored-By: Claude Opus 4.6 --- package.json | 22 ++++++++++--- pnpm-lock.yaml | 2 +- src/index.ts | 84 ++++++-------------------------------------------- src/server.ts | 58 ++++++++++++++++++---------------- 4 files changed, 60 insertions(+), 106 deletions(-) diff --git a/package.json b/package.json index a5f4d16..124e73c 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,32 @@ { "name": "claude-plugins", - "packageManager": "pnpm@10.6.2", "version": "1.0.0", + "description": "MCP server for discovering and serving Claude Code plugins", "type": "module", "main": "dist/index.js", + "bin": { + "claude-plugins": "dist/index.js" + }, + "files": [ + "dist", + "plugins" + ], + "keywords": [ + "mcp", + "claude", + "plugins", + "model-context-protocol" + ], + "license": "MIT", "scripts": { "build": "tsc", "start": "node dist/index.js", "dev": "tsx src/index.ts", - "serve": "PORT=3000 node dist/index.js", - "test": "vitest run" + "test": "vitest run", + "prepublishOnly": "pnpm run build" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.12.1", + "@modelcontextprotocol/sdk": "^1.26.0", "glob": "^11.0.1", "zod": "^3.24.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e68934b..8eccebd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,7 +9,7 @@ importers: .: dependencies: '@modelcontextprotocol/sdk': - specifier: ^1.12.1 + specifier: ^1.26.0 version: 1.26.0(zod@3.25.76) glob: specifier: ^11.0.1 diff --git a/src/index.ts b/src/index.ts index fc2aa7b..3923c30 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,83 +1,17 @@ +#!/usr/bin/env node + import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import { createServer as createHttpServer } from "http"; -import { join } from "path"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; import { loadPlugins } from "./loader.js"; import { createServer } from "./server.js"; -const pluginsDir = join(process.cwd(), "plugins"); +const __dirname = dirname(fileURLToPath(import.meta.url)); +const pluginsDir = join(__dirname, "..", "plugins"); const plugins = loadPlugins(pluginsDir); console.error(`Loaded ${plugins.length} plugins`); -const MAX_BODY_SIZE = 1024 * 1024; // 1 MB - -const portEnv = process.env.PORT; -let port: number | undefined; - -if (portEnv !== undefined) { - const parsed = Number(portEnv); - if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 0) { - console.error(`Invalid PORT value "${portEnv}". Expected a non-negative integer.`); - process.exit(1); - } - port = parsed; -} - -if (port !== undefined) { - const httpServer = createHttpServer(async (req, res) => { - if (req.url === "/mcp" && req.method === "POST") { - const server = createServer(plugins); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - try { - await server.connect(transport); - - const body = await new Promise((resolve, reject) => { - let data = ""; - let size = 0; - req.on("data", (chunk: Buffer) => { - size += chunk.length; - if (size > MAX_BODY_SIZE) { - req.destroy(); - reject(new Error("Request body too large")); - return; - } - data += chunk; - }); - req.on("end", () => resolve(data)); - req.on("error", reject); - }); - - await transport.handleRequest(req, res, JSON.parse(body)); - } catch (err) { - if (!res.headersSent) { - const status = err instanceof Error && err.message === "Request body too large" ? 413 : 400; - res.writeHead(status, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ error: status === 413 ? "Request body too large" : "Bad request" })); - } - } finally { - transport.close(); - server.close(); - } - } else { - res.writeHead(404, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ error: "Not found" })); - } - }); - - httpServer.listen(port, () => { - console.error(`MCP HTTP server listening on port ${port}`); - }); - - process.on("SIGINT", () => { - httpServer.close(); - process.exit(0); - }); -} else { - const server = createServer(plugins); - const transport = new StdioServerTransport(); - await server.connect(transport); -} +const server = createServer(plugins); +const transport = new StdioServerTransport(); +await server.connect(transport); diff --git a/src/server.ts b/src/server.ts index e7e7d2a..9fba5e9 100644 --- a/src/server.ts +++ b/src/server.ts @@ -19,18 +19,20 @@ export function createServer(plugins: Plugin[]): McpServer { version: "1.0.0", }); - server.tool( + server.registerTool( "list_plugins", - "List available plugins, optionally filtered by component type or tag", { - type: z - .enum(["skill", "agent", "prompt"]) - .optional() - .describe("Filter to plugins that have this component type"), - tag: z - .string() - .optional() - .describe("Filter to plugins that have this tag"), + description: "List available plugins, optionally filtered by component type or tag", + inputSchema: { + type: z + .enum(["skill", "agent", "prompt"]) + .optional() + .describe("Filter to plugins that have this component type"), + tag: z + .string() + .optional() + .describe("Filter to plugins that have this tag"), + }, }, async ({ type, tag }) => { let results = plugins; @@ -54,17 +56,19 @@ export function createServer(plugins: Plugin[]): McpServer { } ); - server.tool( + server.registerTool( "get_plugin", - "Get a plugin's full details or a specific component's content", { - name: z.string().describe("Plugin name"), - component: z - .enum(["skill", "agent", "prompt"]) - .optional() - .describe( - "If specified, return only this component's content" - ), + description: "Get a plugin's full details or a specific component's content", + inputSchema: { + name: z.string().describe("Plugin name"), + component: z + .enum(["skill", "agent", "prompt"]) + .optional() + .describe( + "If specified, return only this component's content" + ), + }, }, async ({ name, component }) => { const plugin = plugins.find( @@ -100,15 +104,17 @@ export function createServer(plugins: Plugin[]): McpServer { } ); - server.tool( + server.registerTool( "search_plugins", - "Search plugins by keyword across name, description, and tags", { - query: z.string().describe("Search query"), - type: z - .enum(["skill", "agent", "prompt"]) - .optional() - .describe("Filter to plugins that have this component type"), + description: "Search plugins by keyword across name, description, and tags", + inputSchema: { + query: z.string().describe("Search query"), + type: z + .enum(["skill", "agent", "prompt"]) + .optional() + .describe("Filter to plugins that have this component type"), + }, }, async ({ query, type }) => { const q = query.toLowerCase(); From 1195cfb2cdf1f4fda26a237e06e53c18e91c4c70 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 11:36:07 -0500 Subject: [PATCH 2/9] docs: update README for stdio-only npm package distribution Replace HTTP transport docs with npm/npx installation instructions, remove serve command reference, and add npm package link. Co-Authored-By: Claude Opus 4.6 --- README.md | 104 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 6af41df..df99b21 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Claude Plugins -A shared repository of plugins for Claude Code. Each plugin packages reusable expertise — agents, skills, prompts, and MCP server configs — into a standard format that can be discovered and consumed through the built-in MCP server. +A shared repository of plugins for Claude Code. Each plugin packages reusable expertise — agents, skills, prompts, and MCP server configs — into a standard format that can be discovered and consumed through the built-in MCP server. Available as an [npm package](https://www.npmjs.com/package/claude-plugins) for easy integration via `npx`. ## Philosophy @@ -63,11 +63,62 @@ Other commands: ```bash pnpm run build # Compile TypeScript (only needed if modifying src/) pnpm run start # Run the compiled MCP server (stdio) -pnpm run serve # Start HTTP server on port 3000 +pnpm run test # Run the test suite ``` If you are only adding or editing plugins (not modifying the MCP server source in `src/`), you do not need to run `pnpm run build`. +### Testing Locally + +#### Run the test suite + +```bash +pnpm run test +``` + +This runs integration tests that verify tool registration, plugin filtering, search, and error handling using an in-memory MCP transport. + +#### Test the server manually + +You can test the stdio server by piping JSON-RPC messages directly: + +```bash +# Build first (or use tsx for dev mode) +pnpm run build + +# Send an initialize + list_plugins request +echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}} +{"jsonrpc":"2.0","method":"notifications/initialized"} +{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_plugins","arguments":{}}}' | node dist/index.js +``` + +#### Test with Claude Code + +Add the local server to your project's `.mcp.json`: + +```json +{ + "mcpServers": { + "claude-plugins": { + "command": "npx", + "args": ["tsx", "/path/to/claude-plugins/src/index.ts"] + } + } +} +``` + +Then start a Claude Code session — the `list_plugins`, `get_plugin`, and `search_plugins` tools will be available. Try asking Claude to "list all available plugins" to verify the connection. + +#### Test the npm package before publishing + +```bash +# Simulate an npm install locally +pnpm pack + +# Test the packed tarball works as a CLI +npx ./claude-plugins-1.0.0.tgz +``` + ### Claude Code Commands These slash commands are available when working in this repo with Claude Code: @@ -88,16 +139,16 @@ Any agentic tooling that supports the [Model Context Protocol](https://modelcont | `get_plugin` | Get a plugin's full details or a single component's markdown | `name` (string), `component?` (`skill`, `agent`, `prompt`) | | `search_plugins` | Full-text search across name, description, and tags | `query` (string), `type?` (`skill`, `agent`, `prompt`) | -#### Connect from Claude Code Locally +#### Connect via npm (recommended) -Add the server to your project's `.mcp.json` (or `~/.claude/claude_mcp_settings.json` for global access): +The server is published as an npm package and uses stdio transport. Add it to your project's `.mcp.json` (or `~/.claude/claude_mcp_settings.json` for global access): ```json { "mcpServers": { "claude-plugins": { - "command": "node", - "args": ["/path/to/claude-plugins/dist/index.js"] + "command": "npx", + "args": ["-y", "claude-plugins"] } } } @@ -105,14 +156,19 @@ Add the server to your project's `.mcp.json` (or `~/.claude/claude_mcp_settings. Then in any Claude Code session the three tools above become available automatically. -#### Connect from other MCP clients +#### Connect from a local clone -The server supports both **stdio** and **HTTP** transports. +If you're developing plugins locally, point directly at the built server: -**stdio** (default) — for local MCP clients: - -```bash -node /path/to/claude-plugins/dist/index.js +```json +{ + "mcpServers": { + "claude-plugins": { + "command": "node", + "args": ["/path/to/claude-plugins/dist/index.js"] + } + } +} ``` Or in dev mode (no build step required): @@ -121,30 +177,6 @@ Or in dev mode (no build step required): npx tsx /path/to/claude-plugins/src/index.ts ``` -**HTTP** — for remote access (defaults to port 3000): - -```bash -pnpm run serve # port 3000 (all platforms) - -# Custom port: -# macOS/Linux (bash, zsh, etc.): -PORT=8080 pnpm run serve - -# Windows PowerShell: -$env:PORT=8080; pnpm run serve - -# Windows cmd.exe: -set PORT=8080&& pnpm run serve -``` - -This starts an HTTP server with the MCP Streamable HTTP transport at `POST /mcp`. Clients can connect using any MCP-compatible HTTP client: - -```bash -curl -X POST http://localhost:3000/mcp \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' -``` - #### Example workflow A typical agentic integration pattern: From 9a92659a42ccca80990f0f31543cdeaf7bc25266 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 11:49:30 -0500 Subject: [PATCH 3/9] docs: add Installation & Usage section for end users Add clear instructions for adding the MCP server to Claude Code (via CLI and manual config), example prompts showing how to use the tools, and setup instructions for other MCP clients. Co-Authored-By: Claude Opus 4.6 --- README.md | 80 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index df99b21..39de49c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,61 @@ A few principles guide the design: | `kotlin-expert` | Agent | Kotlin 2.0+, coroutines, Spring Boot, domain modeling | | `react-expert` | Agent | React 19+, concurrent rendering, Tailwind, accessibility | +## Installation & Usage + +### Add to Claude Code + +Run this command from your terminal to add the plugin server to your Claude Code configuration: + +```bash +claude mcp add claude-plugins -- npx -y claude-plugins +``` + +This registers the MCP server globally so it's available in every Claude Code session. + +Alternatively, add it manually to your project's `.mcp.json` (project-level) or `~/.claude/claude_mcp_settings.json` (global): + +```json +{ + "mcpServers": { + "claude-plugins": { + "command": "npx", + "args": ["-y", "claude-plugins"] + } + } +} +``` + +### Using the plugins + +Once connected, three tools become available in your Claude Code sessions: + +| Tool | What it does | Example prompt | +|------------------|------------------------------------------------|----------------------------------------------------| +| `list_plugins` | Browse all plugins, filter by type or tag | *"List all available plugins"* | +| `get_plugin` | Retrieve a plugin's full content | *"Get the python-expert agent prompt"* | +| `search_plugins` | Search plugins by keyword | *"Search for plugins related to code review"* | + +You can ask Claude naturally and it will call the right tool: + +- *"What plugins are available for Python?"* +- *"Show me the react-expert agent"* +- *"Find plugins tagged with 'git'"* + +Claude will use the retrieved plugin content (agent prompts, skills, etc.) to enhance its responses with specialized expertise. + +### Add to other MCP clients + +Any MCP-compatible client can connect to the server via stdio. The server binary is `claude-plugins`: + +```bash +npx -y claude-plugins +``` + +Configure your client to spawn this command and communicate over stdin/stdout using the [MCP protocol](https://modelcontextprotocol.io). + +--- + ## Current Repo This repository is both a collection of plugins and an MCP server. The server exposes tools that allow any MCP-compatible client — including other Claude Code sessions — to discover, search, and retrieve plugins programmatically. @@ -139,23 +194,6 @@ Any agentic tooling that supports the [Model Context Protocol](https://modelcont | `get_plugin` | Get a plugin's full details or a single component's markdown | `name` (string), `component?` (`skill`, `agent`, `prompt`) | | `search_plugins` | Full-text search across name, description, and tags | `query` (string), `type?` (`skill`, `agent`, `prompt`) | -#### Connect via npm (recommended) - -The server is published as an npm package and uses stdio transport. Add it to your project's `.mcp.json` (or `~/.claude/claude_mcp_settings.json` for global access): - -```json -{ - "mcpServers": { - "claude-plugins": { - "command": "npx", - "args": ["-y", "claude-plugins"] - } - } -} -``` - -Then in any Claude Code session the three tools above become available automatically. - #### Connect from a local clone If you're developing plugins locally, point directly at the built server: @@ -177,14 +215,6 @@ Or in dev mode (no build step required): npx tsx /path/to/claude-plugins/src/index.ts ``` -#### Example workflow - -A typical agentic integration pattern: - -1. Call `list_plugins` or `search_plugins` to discover relevant plugins -2. Call `get_plugin` with `component: "agent"` to retrieve the full markdown prompt -3. Use the returned markdown as a system prompt, agent instruction, or context injection - ### Contributing #### Adding a Plugin From 7055ec2455a7a590aa89ae93b238794515ddbf58 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 11:59:19 -0500 Subject: [PATCH 4/9] docs: update package references to @provectus scope --- .mcp.json | 2 +- README.md | 29 ++++++----------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/.mcp.json b/.mcp.json index f834812..618e7d9 100644 --- a/.mcp.json +++ b/.mcp.json @@ -1,6 +1,6 @@ { "mcpServers": { - "claude-plugins": { + "provectus-claude-plugins-finder": { "command": "node", "args": ["dist/index.js"] } diff --git a/README.md b/README.md index 39de49c..9e25b62 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,6 @@ A few principles guide the design: ### Add to Claude Code -Run this command from your terminal to add the plugin server to your Claude Code configuration: - -```bash -claude mcp add claude-plugins -- npx -y claude-plugins -``` - This registers the MCP server globally so it's available in every Claude Code session. Alternatively, add it manually to your project's `.mcp.json` (project-level) or `~/.claude/claude_mcp_settings.json` (global): @@ -40,7 +34,7 @@ Alternatively, add it manually to your project's `.mcp.json` (project-level) or "mcpServers": { "claude-plugins": { "command": "npx", - "args": ["-y", "claude-plugins"] + "args": ["-y", "@provectus/claude-plugins"] } } } @@ -50,11 +44,11 @@ Alternatively, add it manually to your project's `.mcp.json` (project-level) or Once connected, three tools become available in your Claude Code sessions: -| Tool | What it does | Example prompt | -|------------------|------------------------------------------------|----------------------------------------------------| -| `list_plugins` | Browse all plugins, filter by type or tag | *"List all available plugins"* | -| `get_plugin` | Retrieve a plugin's full content | *"Get the python-expert agent prompt"* | -| `search_plugins` | Search plugins by keyword | *"Search for plugins related to code review"* | +| Tool | What it does | Example prompt | +|------------------|-------------------------------------------|-----------------------------------------------| +| `list_plugins` | Browse all plugins, filter by type or tag | *"List all available plugins"* | +| `get_plugin` | Retrieve a plugin's full content | *"Get the python-expert agent prompt"* | +| `search_plugins` | Search plugins by keyword | *"Search for plugins related to code review"* | You can ask Claude naturally and it will call the right tool: @@ -198,17 +192,6 @@ Any agentic tooling that supports the [Model Context Protocol](https://modelcont If you're developing plugins locally, point directly at the built server: -```json -{ - "mcpServers": { - "claude-plugins": { - "command": "node", - "args": ["/path/to/claude-plugins/dist/index.js"] - } - } -} -``` - Or in dev mode (no build step required): ```bash From 00f19729c96f1f4fc8e85f5bbbcb74e20771e7fd Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 12:01:52 -0500 Subject: [PATCH 5/9] fix: add packageManager field to fix CI pnpm setup --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 124e73c..363a41a 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "model-context-protocol" ], "license": "MIT", + "packageManager": "pnpm@10.6.2", "scripts": { "build": "tsc", "start": "node dist/index.js", From c2e20da0e9d3cb2b5ac9429b0d1770df12466448 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 13:02:12 -0500 Subject: [PATCH 6/9] feat: add npm publishing with OIDC provenance --- .github/release-drafter.yml | 33 +++++++++++++ .github/workflows/publish.yml | 69 +++++++++++++++++++++++++++ .github/workflows/release-drafter.yml | 22 +++++++++ README.md | 4 +- package.json | 8 +++- 5 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 .github/release-drafter.yml create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/release-drafter.yml diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..a781abc --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,33 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + labels: + - 'chore' + - 'dependencies' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Changes + + $CHANGES diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..2a0a4ca --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,69 @@ +name: Publish Package + +on: + release: + types: [published] + workflow_dispatch: + inputs: + version: + description: 'Version to publish (e.g., 1.2.3 or 1.2.3-beta.1)' + required: true + type: string + tag: + description: 'npm tag (use "latest" for stable, or custom tag for prereleases)' + required: false + default: 'latest' + type: string + +permissions: + contents: read + id-token: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + # DO NOT use registry-url - it interferes with OIDC + + - name: Upgrade npm to 11.x (required for OIDC) + run: npm install -g npm@latest + + - name: Configure npm registry + run: npm config set registry https://registry.npmjs.org/ + + - name: Determine version and tag + id: version + run: | + if [ "${{ github.event_name }}" = "release" ]; then + # From release event - extract version from tag + release_tag="${{ github.event.release.tag_name }}" + version=$(echo "$release_tag" | sed 's/^v//') + tag="latest" + else + # From workflow_dispatch - use inputs + version="${{ inputs.version }}" + tag="${{ inputs.tag }}" + fi + echo "Version: $version" + echo "Tag: $tag" + echo "version=$version" >> $GITHUB_OUTPUT + echo "tag=$tag" >> $GITHUB_OUTPUT + + - name: Update package.json version + run: npm version ${{ steps.version.outputs.version }} --no-git-tag-version + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm run build + + - name: Publish to npm via OIDC + run: npm publish --access public --provenance --tag ${{ steps.version.outputs.tag }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..e3badf0 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,22 @@ +name: Release Drafter + +on: + push: + branches: + - main + pull_request: + types: [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: release-drafter/release-drafter@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 9e25b62..7fdabc6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Claude Plugins -A shared repository of plugins for Claude Code. Each plugin packages reusable expertise — agents, skills, prompts, and MCP server configs — into a standard format that can be discovered and consumed through the built-in MCP server. Available as an [npm package](https://www.npmjs.com/package/claude-plugins) for easy integration via `npx`. +A shared repository of plugins for Claude Code. Each plugin packages reusable expertise — agents, skills, prompts, and MCP server configs — into a standard format that can be discovered and consumed through the built-in MCP server. Available as an [npm package](https://www.npmjs.com/package/@provectusinc/claude-plugins) for easy integration via `npx`. ## Philosophy @@ -34,7 +34,7 @@ Alternatively, add it manually to your project's `.mcp.json` (project-level) or "mcpServers": { "claude-plugins": { "command": "npx", - "args": ["-y", "@provectus/claude-plugins"] + "args": ["-y", "@provectusinc/claude-plugins"] } } } diff --git a/package.json b/package.json index 363a41a..3778f74 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,11 @@ { - "name": "claude-plugins", - "version": "1.0.0", + "name": "@provectusinc/claude-plugins", + "version": "0.0.0-develop", "description": "MCP server for discovering and serving Claude Code plugins", + "repository": { + "type": "git", + "url": "https://github.com/provectus/claude-plugins.git" + }, "type": "module", "main": "dist/index.js", "bin": { From ffd9dd5eeac52b62d215d7c43f6f7a5d4e590e33 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 13:09:24 -0500 Subject: [PATCH 7/9] fix: address PR review comments --- README.md | 35 +++++++---------------------------- src/server.ts | 12 ++++++------ 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7fdabc6..36b49d7 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,12 @@ A few principles guide the design: ### Add to Claude Code -This registers the MCP server globally so it's available in every Claude Code session. - -Alternatively, add it manually to your project's `.mcp.json` (project-level) or `~/.claude/claude_mcp_settings.json` (global): +Add it to your project's `.mcp.json` (project-level) or `~/.claude/claude_mcp_settings.json` (global): ```json { "mcpServers": { - "claude-plugins": { + "provectus-claude-plugins-finder": { "command": "npx", "args": ["-y", "@provectusinc/claude-plugins"] } @@ -60,10 +58,10 @@ Claude will use the retrieved plugin content (agent prompts, skills, etc.) to en ### Add to other MCP clients -Any MCP-compatible client can connect to the server via stdio. The server binary is `claude-plugins`: +Any MCP-compatible client can connect to the server via stdio. The server package is `@provectusinc/claude-plugins` (binary name: `claude-plugins`): ```bash -npx -y claude-plugins +npx -y @provectusinc/claude-plugins ``` Configure your client to spawn this command and communicate over stdin/stdout using the [MCP protocol](https://modelcontextprotocol.io). @@ -143,20 +141,7 @@ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion": #### Test with Claude Code -Add the local server to your project's `.mcp.json`: - -```json -{ - "mcpServers": { - "claude-plugins": { - "command": "npx", - "args": ["tsx", "/path/to/claude-plugins/src/index.ts"] - } - } -} -``` - -Then start a Claude Code session — the `list_plugins`, `get_plugin`, and `search_plugins` tools will be available. Try asking Claude to "list all available plugins" to verify the connection. +The local server is already configured in `.mcp.json`. Start a Claude Code session and the `list_plugins`, `get_plugin`, and `search_plugins` tools will be available. Try asking Claude to "list all available plugins" to verify the connection. #### Test the npm package before publishing @@ -165,7 +150,7 @@ Then start a Claude Code session — the `list_plugins`, `get_plugin`, and `sear pnpm pack # Test the packed tarball works as a CLI -npx ./claude-plugins-1.0.0.tgz +npx ./provectusinc-claude-plugins-0.0.0-develop.tgz ``` ### Claude Code Commands @@ -190,13 +175,7 @@ Any agentic tooling that supports the [Model Context Protocol](https://modelcont #### Connect from a local clone -If you're developing plugins locally, point directly at the built server: - -Or in dev mode (no build step required): - -```bash -npx tsx /path/to/claude-plugins/src/index.ts -``` +The repo includes a `.mcp.json` that configures the local MCP server automatically. Just clone, install, build, and start a Claude Code session. ### Contributing diff --git a/src/server.ts b/src/server.ts index 9fba5e9..b4e0e54 100644 --- a/src/server.ts +++ b/src/server.ts @@ -23,7 +23,7 @@ export function createServer(plugins: Plugin[]): McpServer { "list_plugins", { description: "List available plugins, optionally filtered by component type or tag", - inputSchema: { + inputSchema: z.object({ type: z .enum(["skill", "agent", "prompt"]) .optional() @@ -32,7 +32,7 @@ export function createServer(plugins: Plugin[]): McpServer { .string() .optional() .describe("Filter to plugins that have this tag"), - }, + }), }, async ({ type, tag }) => { let results = plugins; @@ -60,7 +60,7 @@ export function createServer(plugins: Plugin[]): McpServer { "get_plugin", { description: "Get a plugin's full details or a specific component's content", - inputSchema: { + inputSchema: z.object({ name: z.string().describe("Plugin name"), component: z .enum(["skill", "agent", "prompt"]) @@ -68,7 +68,7 @@ export function createServer(plugins: Plugin[]): McpServer { .describe( "If specified, return only this component's content" ), - }, + }), }, async ({ name, component }) => { const plugin = plugins.find( @@ -108,13 +108,13 @@ export function createServer(plugins: Plugin[]): McpServer { "search_plugins", { description: "Search plugins by keyword across name, description, and tags", - inputSchema: { + inputSchema: z.object({ query: z.string().describe("Search query"), type: z .enum(["skill", "agent", "prompt"]) .optional() .describe("Filter to plugins that have this component type"), - }, + }), }, async ({ query, type }) => { const q = query.toLowerCase(); From 0c2eecdec35dfdaa6734d27e514a7c27ae80d7ec Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Thu, 19 Feb 2026 13:16:09 -0500 Subject: [PATCH 8/9] docs: pin npx install to @latest tag --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36b49d7..6706d14 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Add it to your project's `.mcp.json` (project-level) or `~/.claude/claude_mcp_se "mcpServers": { "provectus-claude-plugins-finder": { "command": "npx", - "args": ["-y", "@provectusinc/claude-plugins"] + "args": ["-y", "@provectusinc/claude-plugins@latest"] } } } From ed8ba5c713c07cbee614485af0ee1d1fe6a07e44 Mon Sep 17 00:00:00 2001 From: Mgrdich Date: Fri, 20 Feb 2026 12:46:12 -0500 Subject: [PATCH 9/9] chore: remove npm publish and release drafter workflows --- .github/release-drafter.yml | 33 ------------- .github/workflows/publish.yml | 69 --------------------------- .github/workflows/release-drafter.yml | 22 --------- 3 files changed, 124 deletions(-) delete mode 100644 .github/release-drafter.yml delete mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/release-drafter.yml diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index a781abc..0000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,33 +0,0 @@ -name-template: 'v$RESOLVED_VERSION' -tag-template: 'v$RESOLVED_VERSION' -categories: - - title: '🚀 Features' - labels: - - 'feature' - - 'enhancement' - - title: '🐛 Bug Fixes' - labels: - - 'fix' - - 'bugfix' - - 'bug' - - title: '🧰 Maintenance' - labels: - - 'chore' - - 'dependencies' -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' -change-title-escapes: '\<*_&' -version-resolver: - major: - labels: - - 'major' - minor: - labels: - - 'minor' - patch: - labels: - - 'patch' - default: patch -template: | - ## Changes - - $CHANGES diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 2a0a4ca..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Publish Package - -on: - release: - types: [published] - workflow_dispatch: - inputs: - version: - description: 'Version to publish (e.g., 1.2.3 or 1.2.3-beta.1)' - required: true - type: string - tag: - description: 'npm tag (use "latest" for stable, or custom tag for prereleases)' - required: false - default: 'latest' - type: string - -permissions: - contents: read - id-token: write - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '22' - # DO NOT use registry-url - it interferes with OIDC - - - name: Upgrade npm to 11.x (required for OIDC) - run: npm install -g npm@latest - - - name: Configure npm registry - run: npm config set registry https://registry.npmjs.org/ - - - name: Determine version and tag - id: version - run: | - if [ "${{ github.event_name }}" = "release" ]; then - # From release event - extract version from tag - release_tag="${{ github.event.release.tag_name }}" - version=$(echo "$release_tag" | sed 's/^v//') - tag="latest" - else - # From workflow_dispatch - use inputs - version="${{ inputs.version }}" - tag="${{ inputs.tag }}" - fi - echo "Version: $version" - echo "Tag: $tag" - echo "version=$version" >> $GITHUB_OUTPUT - echo "tag=$tag" >> $GITHUB_OUTPUT - - - name: Update package.json version - run: npm version ${{ steps.version.outputs.version }} --no-git-tag-version - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm run build - - - name: Publish to npm via OIDC - run: npm publish --access public --provenance --tag ${{ steps.version.outputs.tag }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml deleted file mode 100644 index e3badf0..0000000 --- a/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Release Drafter - -on: - push: - branches: - - main - pull_request: - types: [opened, reopened, synchronize] - -permissions: - contents: read - -jobs: - update_release_draft: - permissions: - contents: write - pull-requests: write - runs-on: ubuntu-latest - steps: - - uses: release-drafter/release-drafter@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}