API & MCP docs
Scripts and services can use the read-only REST API, while an MCP client can let an agent search the plugin directory directly.
Overview
- Base URL — the API lives on the same origin as this site; all paths below are relative. The curl examples use
https://pluginsmp.com— swap in your own origin if you self-host. - Authentication — none. Every endpoint is public and read-only.
- 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 with400 bad_requestnaming 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.
List plugins
GET/api/v1/plugins
Returns paginated plugin summaries. All parameters are optional. Repeated plugin format selections match any selected format; other filters combine with AND.
Query parameters
| Param | Type | Description |
|---|---|---|
| q | string | Free-text query over name, description, keywords, and author (max 200 chars). |
| category | string | Exact tag match. Tags come from manifest keywords — see /api/v1/categories. |
| owner | string | Exact GitHub owner login, for example owner=anthropics — see /creators. |
| type | skills | mcp | Only plugins containing this component type. |
| transport | stdio | streamable-http | sse | Only plugins with at least one MCP server using this transport. |
| protocol | repeatable plugin format | Repeat to match any selected format (OR). Comma-separated values also work. |
| sort | stars | updated | recent | stars = GitHub stars (default), updated = repository push date, recent = first added to the directory. |
| page | integer | 1-based page number. Clamped to >= 1. Default 1. |
| per_page | integer | Results per page, clamped to 1..50. Default 24. |
An unknown value for type, transport, protocol, or sort returns 400 bad_request listing the valid values.
Example request
curl "https://pluginsmp.com/api/v1/plugins?q=github&protocol=codex&protocol=claude-code&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"],
"protocols": ["codex", "claude-code"],
"createdAt": "2026-08-07T09:14:00.000Z",
"indexedAt": "2026-08-07T09:14:00.000Z"
}
],
"meta": { "page": 1, "per_page": 1, "total": 42, "total_pages": 42 }
}Get a plugin
GET/api/v1/plugins/{slug}
Full detail for one plugin: every summary field plus homepage, repository, plugin path, every detected protocol and raw manifest, skills, and MCP server configs. Returns 404 not_found for unknown slugs.
Path parameters
| Param | Type | Description |
|---|---|---|
| slug | string | Directory slug returned by the list endpoint. |
Example request
curl https://pluginsmp.com/api/v1/plugins/acme-github-toolsExample 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"],
"protocols": ["codex", "claude-code"],
"createdAt": "2026-08-07T09:14:00.000Z",
"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\", … }",
"manifestPath": ".codex-plugin/plugin.json",
"manifests": {
"codex": { "path": ".codex-plugin/plugin.json", "raw": "{ … }" },
"claude-code": { "path": ".claude-plugin/plugin.json", "raw": "{ … }" }
},
"skills": [
{
"dirName": "triage-issue",
"path": "skills/triage-issue/SKILL.md",
"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\"." }
}Stats
GET/api/v1/stats
Directory totals for plugins, skills, MCP servers, and tags.
Example request
curl https://pluginsmp.com/api/v1/statsExample response
{
"data": { "plugins": 137, "skills": 402, "mcpServers": 168, "categories": 54 }
}Tags
GET/api/v1/categories
Tags come from manifest keywords, are lowercased, and are ranked by how many plugins use them (top 100). Use a tag name as the category filter on the list endpoint.
Example request
curl https://pluginsmp.com/api/v1/categoriesExample response
{
"data": [
{ "name": "github", "count": 21 },
{ "name": "productivity", "count": 17 },
{ "name": "search", "count": 12 }
]
}MCP server
POST/api/mcp
The directory provides an MCP server so agents can search for plugins with tools. It uses 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": {
"agent-plugin-directory": {
"type": "streamable-http",
"url": "https://pluginsmp.com/api/mcp"
}
}
}Tools
| Tool | Arguments | Description |
|---|---|---|
| search_plugins | query?, protocol? (format or format[]), category?, owner?, type? (skills | mcp), transport?, sort?, page?, per_page? | Search the plugin directory. Filter behavior and limits match GET /api/v1/plugins; the result JSON uses items, total, page, perPage, and totalPages. |
| get_plugin | slug (required) | Full detail for one plugin, like GET /api/v1/plugins/{slug}. |
| get_stats | none | Directory totals, like GET /api/v1/stats. |
Example: initialize
curl -X POST https://pluginsmp.com/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://pluginsmp.com/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 }
}
}'