Skip to content

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:

  1. No duplicate configuration: All metadata lives in package.json
  2. Works with existing npm workflows: No special build steps required
  3. 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:

  1. Add or update pets/<pet-id>/package.json.
  2. Merge the pet source to main.
  3. Regenerate/deploy the source registry artifacts.
  4. Verify with:
bash
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:

bash
bun run generate:source-registry

Use the dry-run helper when you only need to inspect what would be included:

bash
bun run generate:source-registry:dry

External packages can also be made discoverable in these ways:

Option 1: Publish under @openpets scope

json
{
  "name": "@openpets/my-plugin",
  "version": "1.0.0"
}

Option 2: Add the $schema field

json
{
  "$schema": "https://pets.raggle.co/config.json",
  "name": "my-awesome-mcp-server",
  "version": "1.0.0"
}

Option 3: Add the openpets keyword

json
{
  "name": "my-plugin",
  "keywords": ["openpets", "mcp-server"]
}

Discovery Sources

The discovery system searches:

  1. OpenPets source registry: the hosted manifest and tarballs under https://pets.raggle.co/source-pets/
  2. npm Registry: available only for explicit npm fallback/release workflows
  3. GitHub (optional): repositories containing package.json files with $schema pointing to pets.raggle.co

Quick Start

bash
# 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 installed

Installation

Installing Plugins

Install a plugin from the OpenPets source registry:

bash
pets install <package-name> --client <client>

Options:

FlagDescription
--client <client>Target AI client: claude, opencode, cursor, vscode, or custom
--config '{"key":"value"}'Pre-configure environment variables
--global, -gInstall globally
--version <version>Install a specific version

Examples:

bash
# 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 -g

Uninstalling Plugins

bash
pets uninstall <package-name> --client <client>

Options:

FlagDescription
--client <client>Target AI client to remove from
--global, -gUninstall globally

Project Plugin Management

These commands manage plugins in the current project's opencode.json and .pets/config.json:

bash
# 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-run previews changes
  • pets clear --dry-run previews removals
  • pets clear --keep-agents keeps .opencode/agent/* folders
  • pets reload --session <id> reloads a specific session

Registry resolution:

  • pets add <name>, pets prune <name>, and pets 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=1 only when you intentionally want npm fallback behavior.
  • Source registry URL overrides are treated as development-only. OPENPETS_SOURCE_MANIFEST_URL and OPENPETS_SOURCE_BASE_URL are ignored unless they point at a trusted OpenPets host or OPENPETS_ALLOW_UNTRUSTED_SOURCE_REGISTRY=1 is 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-bridge when postbridge was 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

bash
pets search [query]

Search the OpenPets source registry.

bash
# Search for GitHub-related plugins
pets search github

# List all available plugins
pets search

# Limit results
pets search ai --limit 10

Inspect Plugins

bash
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

bash
pets list [type]

Types:

  • installed (default) - Show all installed pets
  • clients - Show supported AI clients and their config paths
  • servers - Show installed pets for a specific client
bash
# List installed plugins
pets list

# Show supported clients
pets list clients

# List servers for a specific client
pets list servers --client claude

Development

Initialize a New Plugin

bash
pets init [name] [options]

Creates a new plugin project with all necessary files.

Options:

FlagDescription
--yamlCreate openpets.yaml instead of package.json
--runtime <type>Runtime: typescript, bun, or container
--dir <path>Target directory

Example:

bash
# 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 container

Validate Configuration

bash
pets validate [directory]

Validates the pet configuration and reports any errors or warnings.

Build

bash
pets build <pet-name>

Builds and validates a pet package.

Deploy

bash
pets deploy <pet-name>

Builds and deploys a pet with metadata.

Publish

bash
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:

FlagDescription
--previewDry-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:

bash
# 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 beta

Configuration

openpets.yaml

You can configure your plugin using an openpets.yaml file:

yaml
$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:

json
{
  "$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

ClientConfig 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

bash
pets run <package-name> [options]

Run a plugin locally for testing.

Options:

FlagDescription
--config '{"key":"value"}'Configuration to pass
--transport <type>Transport type: stdio or http

Example:

bash
pets run hackernews
pets run postgres --config '{"DATABASE_URL":"postgres://..."}'

Execute a Specific Tool

Run a tool directly in the current repository context:

bash
pets exec <tool-name> [options]

Options:

FlagDescription
--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-runResolve and validate without execution
--jsonReturn JSON metadata output
--rawPrint only tool output

API Reference

RegistryClient

typescript
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

typescript
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

VariableDescription
PETS_DEBUG=trueEnable detailed debug logging
HOMEHome directory for config files

Discovery Commands

Discover Packages

Find all OpenPets-compatible packages from npm and GitHub:

bash
# Discover from npm only
pets discover

# Include GitHub repository search
pets discover --github

# Limit results
pets discover --limit 20

Note: GitHub discovery requires the GITHUB_TOKEN environment variable.

Registry Management

bash
# 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.json

Programmatic Discovery API

typescript
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

FeatureOpenPetsSmithery
Package Registrynpm (@openpets/*)Smithery Registry
Config Formatpackage.json with $schemasmithery.yaml
External Discovery$schema field + keywordssmithery.yaml in repo
Supported RuntimesTypeScript, Bun, ContainerTypeScript, Python, Container
Client SupportClaude, OpenCode, Cursor, VS CodeClaude, Cline, Continue, Zed
CLIpetsnpx @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:

  1. Uses existing package.json: The $schema field serves as the marker
  2. npm-native workflow: Discovery works through npm search, not GitHub crawling
  3. No duplication: All configuration stays in one place

External packages can be discovered by:

  • Publishing to npm with the openpets keyword
  • Adding $schema: "https://pets.raggle.co/config.json" to package.json
  • Both are indexed during registry updates

Getting Help

bash
pets help
pets --help

Visit pets.raggle.co/docs for full documentation.