OpenPets Registry
OpenPets provides a registry system similar to Smithery for discovering, installing, and publishing AI plugins.
The hosted OpenPets source registry is the primary deployment and discovery location for pets maintained in this repository. It is served from:
- Manifest:
https://pets.raggle.co/source-pets/source-manifest.json - Tarballs:
https://pets.raggle.co/source-pets/<pet-id>-<version>.tgz
npm remains supported for explicit npm releases, but do not assume a pet is unpublished just because npm view @openpets/<pet> returns 404. Check pets info <pet> or the source registry manifest first.
How Package Discovery Works
Unlike Smithery which requires a separate smithery.yaml file, OpenPets uses the standard package.json with a $schema field to enable discovery of external packages. This approach:
- No duplicate configuration: All metadata lives in
package.json - Works with existing npm workflows: No special build steps required
- Enables external discovery: Any package with the right markers is discoverable
Making Your Package Discoverable
Primary Path: OpenPets Source Registry
For pets in this repository, the normal discovery path is:
- Add or update
pets/<pet-id>/package.json. - Merge the pet source to
main. - Regenerate/deploy the source registry artifacts.
- Verify with:
pets info <pet-id>
pets search <pet-id>
pets tools <pet-id>pets info <pet-id> should report that it read metadata from a source registry tarball.
You can build source registry artifacts locally with:
bun run generate:source-registryUse the dry-run helper when you only need to inspect what would be included:
bun run generate:source-registry:dryExternal packages can also be made discoverable in these ways:
Option 1: Publish under @openpets scope
{
"name": "@openpets/my-plugin",
"version": "1.0.0"
}Option 2: Add the $schema field
{
"$schema": "https://pets.raggle.co/config.json",
"name": "my-awesome-mcp-server",
"version": "1.0.0"
}Option 3: Add the openpets keyword
{
"name": "my-plugin",
"keywords": ["openpets", "mcp-server"]
}Discovery Sources
The discovery system searches:
- OpenPets source registry: the hosted manifest and tarballs under
https://pets.raggle.co/source-pets/ - npm Registry: available only for explicit npm fallback/release workflows
- GitHub (optional): repositories containing
package.jsonfiles with$schemapointing topets.raggle.co
Quick Start
# Install the CLI globally
npm install -g openpets
# Search for plugins
pets search github
# Install a plugin
pets install github --client claude
# Inspect a plugin
pets inspect github
# List installed plugins
pets list installedInstallation
Installing Plugins
Install a plugin from the OpenPets source registry:
pets install <package-name> --client <client>Options:
| Flag | Description |
|---|---|
--client <client> | Target AI client: claude, opencode, cursor, vscode, or custom |
--config '{"key":"value"}' | Pre-configure environment variables |
--global, -g | Install globally |
--version <version> | Install a specific version |
Examples:
# Install for Claude Desktop
pets install maps --client claude
# Install with configuration
pets install postgres --config '{"DATABASE_URL":"postgres://localhost:5432/db"}'
# Install specific version
pets install github --version 1.2.0
# Install globally
pets install hackernews -gUninstalling Plugins
pets uninstall <package-name> --client <client>Options:
| Flag | Description |
|---|---|
--client <client> | Target AI client to remove from |
--global, -g | Uninstall globally |
Project Plugin Management
These commands manage plugins in the current project's opencode.json and .pets/config.json:
# Download and enable a pet in the current project
pets add <name>
# Inspect published/source-registry metadata for a pet
pets info <name>
# Configure environment variables for a pet
pets config <name>
# Keep only selected pets enabled
pets prune <pet> [pets...]
# Remove all pets from opencode.json
pets clear
# Reload OpenCode with updated plugin set
pets reload [message]Useful flags:
pets prune --dry-runpreviews changespets clear --dry-runpreviews removalspets clear --keep-agentskeeps.opencode/agent/*folderspets reload --session <id>reloads a specific session
Registry resolution:
pets add <name>,pets prune <name>, andpets info <name>resolve bare names through the OpenPets source registry first.- npm fallback is disabled by default for these project-management commands. Set
OPENPETS_NPM_FALLBACK=1only when you intentionally want npm fallback behavior. - Source registry URL overrides are treated as development-only.
OPENPETS_SOURCE_MANIFEST_URLandOPENPETS_SOURCE_BASE_URLare ignored unless they point at a trusted OpenPets host orOPENPETS_ALLOW_UNTRUSTED_SOURCE_REGISTRY=1is also set. - These commands do not inspect local workspace directories such as
pets/<name>when a bare pet name is provided. - If a package is not found, the CLI may suggest similar known pet IDs from the remote or bundled registry index, such as
post-bridgewhenpostbridgewas requested. - Use an explicit local path only with commands that support local plugin execution or development workflows, for example
pets exec <tool> --plugin ./pets/<name>/index.ts.
Discovery
Search Plugins
pets search [query]Search the OpenPets source registry.
# Search for GitHub-related plugins
pets search github
# List all available plugins
pets search
# Limit results
pets search ai --limit 10Inspect Plugins
pets inspect <package-name>Shows detailed information about a package:
- Name, version, description
- Keywords and categories
- Homepage and repository links
- Installation status
- Available versions
List Resources
pets list [type]Types:
installed(default) - Show all installed petsclients- Show supported AI clients and their config pathsservers- Show installed pets for a specific client
# List installed plugins
pets list
# Show supported clients
pets list clients
# List servers for a specific client
pets list servers --client claudeDevelopment
Initialize a New Plugin
pets init [name] [options]Creates a new plugin project with all necessary files.
Options:
| Flag | Description |
|---|---|
--yaml | Create openpets.yaml instead of package.json |
--runtime <type> | Runtime: typescript, bun, or container |
--dir <path> | Target directory |
Example:
# Create a new plugin
pets init my-awesome-plugin
# Create with YAML configuration
pets init my-plugin --yaml
# Create for container deployment
pets init my-plugin --runtime containerValidate Configuration
pets validate [directory]Validates the pet configuration and reports any errors or warnings.
Build
pets build <pet-name>Builds and validates a pet package.
Deploy
pets deploy <pet-name>Builds and deploys a pet with metadata.
Publish
pets publish [pet-name] [options]Publish a pet to npm. This is secondary to the hosted source registry and should be used only when an npm package release is explicitly intended.
Options:
| Flag | Description |
|---|---|
--preview | Dry-run mode (no actual publish) |
--channel <name> | npm tag (default: latest) |
--scope <scope> | npm scope (default: @openpets, use "" for unscoped) |
--otp <code> | One-time password for 2FA-enabled npm accounts |
Examples:
# Publish from pet directory
cd pets/my-plugin && pets publish
# Publish with preview
pets publish --preview
# Publish to beta channel
pets publish my-plugin --channel betaConfiguration
openpets.yaml
You can configure your plugin using an openpets.yaml file:
$schema: https://pets.raggle.co/config.yaml.json
name: my-plugin
version: 1.0.0
description: My awesome plugin
runtime:
runtime: typescript
transport: stdio
build:
entrypoint: index.ts
outDir: dist
target: node
format: esm
envVariables:
required:
- name: API_KEY
description: API key for the service
secret: true
optional:
- name: DEBUG
description: Enable debug mode
default: "false"
queries:
- "example query 1"
- "example query 2"
scenarios:
basic-test:
- "example query 1"
- "example query 2"package.json
Alternatively, use the standard package.json format with OpenPets extensions:
{
"$schema": "https://pets.raggle.co/config.json",
"name": "@openpets/my-plugin",
"version": "1.0.0",
"title": "My Plugin",
"subtitle": "A description",
"description": "Full description of my plugin",
"categories": ["productivity", "automation"],
"keywords": ["openpets", "plugin"],
"envVariables": {
"required": [
{
"name": "API_KEY",
"description": "API key"
}
]
},
"queries": ["example query"],
"scenarios": {
"basic-test": ["example query"]
}
}Supported Clients
| Client | Config Path |
|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
| OpenCode | ~/.opencode/config.json |
| Cursor | ~/.cursor/mcp.json |
| VS Code | ~/.vscode/mcp.json |
Running Plugins Locally
pets run <package-name> [options]Run a plugin locally for testing.
Options:
| Flag | Description |
|---|---|
--config '{"key":"value"}' | Configuration to pass |
--transport <type> | Transport type: stdio or http |
Example:
pets run hackernews
pets run postgres --config '{"DATABASE_URL":"postgres://..."}'Execute a Specific Tool
Run a tool directly in the current repository context:
pets exec <tool-name> [options]Options:
| Flag | Description |
|---|---|
--args '{"key":"value"}' | Inline JSON arguments |
--args-file <file> | Load arguments JSON from file (- for stdin) |
--plugin <name-or-path> | Restrict execution to one plugin |
--dry-run | Resolve and validate without execution |
--json | Return JSON metadata output |
--raw | Print only tool output |
API Reference
RegistryClient
import { getRegistryClient } from 'openpets'
const client = getRegistryClient()
// Search packages
const results = await client.search('github')
// Install a package
await client.install('github', { client: 'claude' })
// Uninstall a package
await client.uninstall('github', { client: 'claude' })
// Inspect a package
const info = await client.inspect('github')
// List installed pets
const installed = client.getInstalledPets()OpenPetsConfig
import { loadPetConfig, validatePetConfig } from 'openpets'
// Load configuration
const config = loadPetConfig('./my-plugin')
// Validate configuration
const result = validatePetConfig(config)
if (!result.valid) {
console.error(result.errors)
}Environment Variables
| Variable | Description |
|---|---|
PETS_DEBUG=true | Enable detailed debug logging |
HOME | Home directory for config files |
Discovery Commands
Discover Packages
Find all OpenPets-compatible packages from npm and GitHub:
# Discover from npm only
pets discover
# Include GitHub repository search
pets discover --github
# Limit results
pets discover --limit 20Note: GitHub discovery requires the GITHUB_TOKEN environment variable.
Registry Management
# Show registry status
pets registry status
# Update the registry
pets registry update
# Export registry to file
pets registry export my-registry.json
# Import registry from file
pets registry import my-registry.jsonProgrammatic Discovery API
import { getPackageDiscovery, getRegistryAggregator } from 'openpets'
// Direct discovery
const discovery = getPackageDiscovery()
const packages = await discovery.discoverAll({
includeNpm: true,
includeGithub: true,
githubToken: process.env.GITHUB_TOKEN,
keywords: ['openpets', 'mcp-server'],
limit: 100
})
// Using the aggregator (with caching)
const aggregator = getRegistryAggregator()
await aggregator.updateRegistry()
const results = await aggregator.search('github')
const pkg = await aggregator.getPackage('maps')Comparison with Smithery
| Feature | OpenPets | Smithery |
|---|---|---|
| Package Registry | npm (@openpets/*) | Smithery Registry |
| Config Format | package.json with $schema | smithery.yaml |
| External Discovery | $schema field + keywords | smithery.yaml in repo |
| Supported Runtimes | TypeScript, Bun, Container | TypeScript, Python, Container |
| Client Support | Claude, OpenCode, Cursor, VS Code | Claude, Cline, Continue, Zed |
| CLI | pets | npx @smithery/cli |
Why No Separate YAML File?
Smithery requires a smithery.yaml file to mark repositories as containing MCP servers. OpenPets takes a different approach:
- Uses existing package.json: The
$schemafield serves as the marker - npm-native workflow: Discovery works through npm search, not GitHub crawling
- No duplication: All configuration stays in one place
External packages can be discovered by:
- Publishing to npm with the
openpetskeyword - Adding
$schema: "https://pets.raggle.co/config.json"to package.json - Both are indexed during registry updates
Getting Help
pets help
pets --helpVisit pets.raggle.co/docs for full documentation.