{
  "$schema": "https://modelcontextprotocol.io/schema/manifest.json",
  "name": "singing-pet",
  "display_name": "Singing Pet",
  "description": "Turn a photo of a pet plus a song into a video where the pet appears to sing, with the mouth synced to the audio.",
  "version": "1.0.0",
  "vendor": {
    "name": "JRL Software LTD",
    "url": "https://singing.pet",
    "email": "jack@jrl.software"
  },
  "documentation": "https://singing.pet/mcp",
  "privacy_policy": "https://singing.pet/privacy",
  "terms_of_service": "https://singing.pet/terms",
  "server": {
    "url": "https://api.singing.pet/mcp",
    "transport": "streamable-http"
  },
  "authentication": {
    "methods": ["api_key", "oauth2"],
    "api_key": {
      "location": "header",
      "header": "Authorization",
      "scheme": "Bearer",
      "issue_url": "https://singing.pet/dashboard/api-keys"
    },
    "oauth2": {
      "authorization_server_metadata": "https://api.singing.pet/.well-known/oauth-authorization-server",
      "protected_resource_metadata": "https://api.singing.pet/.well-known/oauth-protected-resource",
      "dynamic_client_registration": true,
      "code_challenge_methods_supported": ["S256"],
      "scopes_supported": ["videos:read", "videos:write"]
    }
  },
  "tools": [
    {
      "name": "list_song_templates",
      "description": "List the songs a pet can be animated singing. Call before create_singing_video to get a valid template_id."
    },
    {
      "name": "create_singing_video",
      "description": "Animate a pet photo so the pet appears to sing a song. Takes a public image URL and a template_id. Costs 1 credit, renders in about a minute.",
      "scope": "videos:write"
    },
    {
      "name": "get_video_status",
      "description": "Check whether a video has finished rendering and get its download URL."
    },
    {
      "name": "list_videos",
      "description": "List this account's videos, newest first."
    },
    {
      "name": "delete_video",
      "description": "Permanently delete one of this account's videos.",
      "scope": "videos:write"
    },
    {
      "name": "get_credit_balance",
      "description": "How many API credits are left. One credit renders one video."
    }
  ],
  "pricing": {
    "model": "prepaid_credits",
    "unit": "1 credit per video",
    "currency": "USD",
    "packs": [
      { "credits": 100, "amount": 5 },
      { "credits": 500, "amount": 20 },
      { "credits": 2500, "amount": 75 }
    ]
  },
  "rate_limits": {
    "read": { "limit": 60, "window_seconds": 60 },
    "write": { "limit": 10, "window_seconds": 60 },
    "headers": ["RateLimit", "RateLimit-Policy", "Retry-After"]
  }
}
