
Security News
Socket Releases Free Certified Patches for Critical vm2 Sandbox Escape
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.
@openpets/athenahealth
Advanced tools
Template plugin demonstrating OpenPets best practices. Copy this directory to create your own pet with proper structure, test-connection tool, and graceful degradation.
A comprehensive template demonstrating OpenPets best practices. Copy this folder and customize it to build your own pet.
This template includes all required patterns:
{pet-name}-test-connection{pet-name}-{action} patternloadEnv() for configurationcreateLogger() for debugging# From the pets directory
cp -r _TEMPLATE_ my-pet
cd my-pet
Change these fields:
{
"name": "@openpets/my-pet",
"title": "My Pet",
"description": "What my pet does",
"envVariables": {
"required": [
{
"name": "MY_PET_API_KEY",
"description": "API key from My Service"
}
]
},
"queries": [
"test my-pet connection",
"list items from my-pet"
]
}
export const MyPetPlugin = async () => {
const logger = createLogger("my-pet")
const env = loadEnv("my-pet") // Loads MY_PET_* variables
const API_KEY = env.MY_PET_API_KEY
const isConfigured = !!API_KEY
if (!isConfigured) {
// Return limited toolset when not configured
return createPlugin([
{
name: "my-pet-test-connection",
description: "Test my-pet connection status",
schema: z.object({}),
async execute() {
return JSON.stringify({
success: false,
status: "not_configured",
message: "Please set MY_PET_API_KEY"
}, null, 2)
}
}
])
}
// Return full toolset when configured
const tools: ToolDefinition[] = [
{
name: "my-pet-test-connection",
// ... full implementation
},
{
name: "my-pet-list-items",
// ... your tools
}
]
return createPlugin(tools)
}
# My Pet Configuration
MY_PET_API_KEY=your_api_key_here
bun install
opencode run "test my-pet connection" --print-logs
All tools MUST follow the pattern: {pet-name}-{action}
| Good | Bad |
|---|---|
jira-list-issues | list-issues |
github-create-pr | create-pr |
stripe-get-customer | getCustomer |
my-pet-test-connection | test-connection |
Every pet MUST have a test-connection tool that:
{
name: "my-pet-test-connection",
description: "Test connection and configuration status",
schema: z.object({}),
async execute() {
return JSON.stringify({
success: true, // or false
status: "connected", // or "not_configured", "error"
message: "Connected successfully",
details: {
// Add relevant details
}
}, null, 2)
}
}
When your pet is not configured, return a limited toolset:
if (!isConfigured) {
logger.warn("Pet not configured - returning limited toolset")
return createPlugin([
// Only include test-connection tool
testConnectionTool
])
}
// Full toolset when configured
return createPlugin(allTools)
Always return JSON strings with consistent structure:
// Success response
return JSON.stringify({
success: true,
data: result,
message: "Operation completed"
}, null, 2)
// Error response
return JSON.stringify({
success: false,
error: error.message,
code: "INVALID_INPUT" // optional error code
}, null, 2)
// List response
return JSON.stringify({
success: true,
total: items.length,
items: items
}, null, 2)
Use these supported Zod types:
schema: z.object({
// Primitives
name: z.string().describe("User name"),
age: z.number().describe("User age"),
active: z.boolean().describe("Is active"),
// Optional with default
limit: z.number().optional().default(50).describe("Max results"),
// Enum
status: z.enum(["active", "archived"]).describe("Status filter"),
// Arrays (primitives only)
tags: z.array(z.string()).describe("Tags list"),
ids: z.array(z.number()).describe("ID list")
})
NOT supported (will cause errors):
z.array(z.object({...})) - No nested objects in arraysz.record() - No record typesz.union() with objects - No complex unionsFor complex data, use JSON strings:
schema: z.object({
filtersJson: z.string().describe("JSON string of filter options")
}),
execute(args) {
const filters = JSON.parse(args.filtersJson)
}
Use loadEnv() from openpets-sdk:
const env = loadEnv("my-pet")
// This loads variables with the prefix:
// MY_PET_API_KEY -> env.MY_PET_API_KEY
// MY_PET_BASE_URL -> env.MY_PET_BASE_URL
Document in package.json:
{
"envVariables": {
"required": [
{
"name": "MY_PET_API_KEY",
"description": "API key from My Service",
"provider": "My Service",
"priority": 1
}
],
"optional": [
{
"name": "MY_PET_DEBUG",
"description": "Enable debug logging",
"provider": "Configuration",
"priority": 2
}
]
}
}
Use the logger for debugging:
const logger = createLogger("my-pet")
logger.debug("Debug info", { context: data })
logger.info("Operation started")
logger.warn("Warning message")
logger.error("Error occurred", { error: err.message })
Before publishing, verify:
@openpets/my-petmy-pet-test-connection toolmy-pet-{action} patternpets validate passes# Validate first
pets validate
# Preview what will be published
pets publish --preview
# Publish to npm
pets publish
For real-world examples, check out:
pets/jira/ - Full-featured with 20+ toolspets/github/ - GitHub API integrationpets/stripe/ - Payment processingpets/wise/ - Financial servicesFAQs
Template plugin demonstrating OpenPets best practices. Copy this directory to create your own pet with proper structure, test-connection tool, and graceful degradation.
The npm package @openpets/athenahealth receives a total of 3 weekly downloads. As such, @openpets/athenahealth popularity was classified as not popular.
We found that @openpets/athenahealth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.

Research
Five malicious NuGet packages impersonate Chinese .NET libraries to deploy a stealer targeting browser credentials, crypto wallets, SSH keys, and local files.

Security News
pnpm 11 turns on a 1-day Minimum Release Age and blocks exotic subdeps by default, adding safeguards against fast-moving supply chain attacks.