@openpets/luma
v1.0.3
Published
Manage events, guests, calendars, and ticketing through the Luma API. Create events, manage registrations, send invites, and more.
Maintainers
Readme
Pet Plugin Template
A comprehensive template demonstrating OpenPets best practices. Copy this folder and customize it to build your own pet.
Luma API Key Setup
- Developer settings URL format:
https://luma.com/calendar/manage/{calendar_id}/settings/developer - Replace
{calendar_id}with your real calendar id from your Luma calendar URL - Store the id as
LUMA_CALENDAR_ID(optional helper) - Store the generated API key as
LUMA_API_KEY(required)
Best Practices Demonstrated
This template includes all required patterns:
- Test Connection Tool - Every pet MUST have
{pet-name}-test-connection - Graceful Degradation - Returns limited toolset when not configured
- Proper Tool Naming - All tools follow
{pet-name}-{action}pattern - Structured Responses - All tools return JSON with success/error status
- Environment Handling - Uses
loadEnv()for configuration - Logging - Uses
createLogger()for debugging
Quick Start
1. Copy This Template
# From the pets directory
cp -r _TEMPLATE_ my-pet
cd my-pet2. Update package.json
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"
]
}3. Update index.ts
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)
}4. Update .env.example
# My Pet Configuration
MY_PET_API_KEY=your_api_key_here5. Test Your Pet
bun install
opencode run "test my-pet connection" --print-logsTool Naming Convention
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 |
Required: Test Connection Tool
Every pet MUST have a test-connection tool that:
- Works even when the pet is not configured
- Returns structured status information
- Provides helpful error messages
{
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)
}
}Graceful Degradation
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)Response Format
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)Schema Types (Zod)
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 unions
For 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)
}Environment Variables
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_URLDocument 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
}
]
}
}Logging
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 })Validation Checklist
Before publishing, verify:
- [ ] Package name is
@openpets/my-pet - [ ] Has
my-pet-test-connectiontool - [ ] Test-connection works when NOT configured
- [ ] All tool names follow
my-pet-{action}pattern - [ ] All tools return JSON strings
- [ ] Environment variables documented in package.json
- [ ] .env.example has all variables
- [ ] queries array has example prompts
- [ ]
pets validatepasses
Publishing
# Validate first
pets validate
# Preview what will be published
pets publish --preview
# Publish to npm
pets publishExamples
For real-world examples, check out:
pets/jira/- Full-featured with 20+ toolspets/github/- GitHub API integrationpets/stripe/- Payment processingpets/wise/- Financial services
Need Help?
- AGENTS.md - Comprehensive development guide
- docs/best-practices.md - Best practices
- docs/testing.md - Testing guide
